fpdebug.pas 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998-2000 by Pierre Muller
  5. Debugger call routines for the IDE
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPDebug;
  13. interface
  14. {$i globdir.inc}
  15. uses
  16. {$ifdef win32}
  17. Windows,
  18. {$endif win32}
  19. Objects,Dialogs,Drivers,Views,
  20. GDBCon,GDBInt,Menus,
  21. WViews,WEditor,
  22. FPViews;
  23. type
  24. PDebugController=^TDebugController;
  25. TDebugController=object(TGDBController)
  26. InvalidSourceLine : boolean;
  27. { if true the current debugger raw will stay in middle of
  28. editor window when debugging PM }
  29. CenterDebuggerRow : boolean;
  30. Disableallinvalidbreakpoints : boolean;
  31. OrigPwd, { pwd at startup }
  32. LastFileName : string;
  33. LastSource : PView; {PsourceWindow !! }
  34. HiddenStepsCount : longint;
  35. { no need to switch if using another terminal }
  36. NoSwitch : boolean;
  37. HasExe : boolean;
  38. RunCount : longint;
  39. WindowWidth : longint;
  40. FPCBreakErrorNumber : longint;
  41. {$ifdef SUPPORT_REMOTE}
  42. isRemoteDebugging:boolean;
  43. {$endif SUPPORT_REMOTE}
  44. constructor Init;
  45. procedure SetExe(const exefn:string);
  46. procedure SetWidth(AWidth : longint);
  47. procedure SetSourceDirs;
  48. destructor Done;
  49. procedure DoSelectSourceline(const fn:string;line:longint);virtual;
  50. { procedure DoStartSession;virtual;
  51. procedure DoBreakSession;virtual;}
  52. procedure DoEndSession(code:longint);virtual;
  53. procedure DoUserSignal;virtual;
  54. procedure AnnotateError;
  55. procedure InsertBreakpoints;
  56. procedure RemoveBreakpoints;
  57. procedure ReadWatches;
  58. procedure RereadWatches;
  59. procedure ResetBreakpointsValues;
  60. procedure DoDebuggerScreen;virtual;
  61. procedure DoUserScreen;virtual;
  62. procedure Reset;virtual;
  63. procedure ResetDebuggerRows;
  64. procedure Run;virtual;
  65. procedure Continue;virtual;
  66. procedure UntilReturn;virtual;
  67. procedure CommandBegin(const s:string);virtual;
  68. procedure CommandEnd(const s:string);virtual;
  69. function IsRunning : boolean;
  70. function AllowQuit : boolean;virtual;
  71. function GetValue(Const expr : string) : pchar;
  72. function GetFramePointer : CORE_ADDR;
  73. function GetLongintAt(addr : CORE_ADDR) : longint;
  74. function GetPointerAt(addr : CORE_ADDR) : CORE_ADDR;
  75. end;
  76. BreakpointType = (bt_function,bt_file_line,bt_watch,
  77. bt_awatch,bt_rwatch,bt_address,bt_invalid);
  78. BreakpointState = (bs_enabled,bs_disabled,bs_deleted,bs_delete_after);
  79. PBreakpointCollection=^TBreakpointCollection;
  80. PBreakpoint=^TBreakpoint;
  81. TBreakpoint=object(TObject)
  82. typ : BreakpointType;
  83. state : BreakpointState;
  84. owner : PBreakpointCollection;
  85. Name : PString; { either function name or expr to watch }
  86. FileName : PString;
  87. OldValue,CurrentValue : Pstring;
  88. Line : Longint; { only used for bt_file_line type }
  89. Conditions : PString; { conditions relative to that breakpoint }
  90. IgnoreCount : Longint; { how many counts should be ignored }
  91. Commands : pchar; { commands that should be executed on breakpoint }
  92. GDBIndex : longint;
  93. GDBState : BreakpointState;
  94. constructor Init_function(Const AFunc : String);
  95. constructor Init_Address(Const AAddress : String);
  96. constructor Init_Empty;
  97. constructor Init_file_line(AFile : String; ALine : longint);
  98. constructor Init_type(atyp : BreakpointType;Const AnExpr : String);
  99. constructor Load(var S: TStream);
  100. procedure Store(var S: TStream);
  101. procedure Insert;
  102. procedure Remove;
  103. procedure Enable;
  104. procedure Disable;
  105. procedure UpdateSource;
  106. procedure ResetValues;
  107. destructor Done;virtual;
  108. end;
  109. TBreakpointCollection=object(TCollection)
  110. function At(Index: Integer): PBreakpoint;
  111. function GetGDB(index : longint) : PBreakpoint;
  112. function GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  113. function ToggleFileLine(FileName: String;LineNr : Longint) : boolean;
  114. procedure Update;
  115. procedure ShowBreakpoints(W : PFPWindow);
  116. function FindBreakpointAt(Editor : PSourceEditor; Line : longint) : PBreakpoint;
  117. procedure AdaptBreakpoints(Editor : PSourceEditor; Pos, Change : longint);
  118. procedure ShowAllBreakpoints;
  119. end;
  120. PBreakpointItem = ^TBreakpointItem;
  121. TBreakpointItem = object(TObject)
  122. Breakpoint : PBreakpoint;
  123. constructor Init(ABreakpoint : PBreakpoint);
  124. function GetText(MaxLen: Sw_integer): string; virtual;
  125. procedure Selected; virtual;
  126. function GetModuleName: string; virtual;
  127. end;
  128. PBreakpointsListBox = ^TBreakpointsListBox;
  129. TBreakpointsListBox = object(THSListBox)
  130. Transparent : boolean;
  131. NoSelection : boolean;
  132. MaxWidth : Sw_integer;
  133. (* ModuleNames : PStoreCollection; *)
  134. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  135. procedure AddBreakpoint(P: PBreakpointItem); virtual;
  136. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  137. function GetLocalMenu: PMenu;virtual;
  138. procedure Clear; virtual;
  139. procedure TrackSource; virtual;
  140. procedure EditNew; virtual;
  141. procedure EditCurrent; virtual;
  142. procedure DeleteCurrent; virtual;
  143. procedure ToggleCurrent;
  144. procedure Draw; virtual;
  145. procedure HandleEvent(var Event: TEvent); virtual;
  146. constructor Load(var S: TStream);
  147. procedure Store(var S: TStream);
  148. destructor Done; virtual;
  149. end;
  150. PBreakpointsWindow = ^TBreakpointsWindow;
  151. TBreakpointsWindow = object(TFPDlgWindow)
  152. BreakLB : PBreakpointsListBox;
  153. constructor Init;
  154. procedure AddBreakpoint(ABreakpoint : PBreakpoint);
  155. procedure ClearBreakpoints;
  156. procedure ReloadBreakpoints;
  157. procedure Close; virtual;
  158. procedure SizeLimits(var Min, Max: TPoint);virtual;
  159. procedure HandleEvent(var Event: TEvent); virtual;
  160. procedure Update; virtual;
  161. constructor Load(var S: TStream);
  162. procedure Store(var S: TStream);
  163. destructor Done; virtual;
  164. end;
  165. PBreakpointItemDialog = ^TBreakpointItemDialog;
  166. TBreakpointItemDialog = object(TCenterDialog)
  167. constructor Init(ABreakpoint: PBreakpoint);
  168. function Execute: Word; virtual;
  169. private
  170. Breakpoint : PBreakpoint;
  171. TypeRB : PRadioButtons;
  172. NameIL : PEditorInputLine;
  173. ConditionsIL: PEditorInputLine;
  174. LineIL : PEditorInputLine;
  175. IgnoreIL : PEditorInputLine;
  176. end;
  177. PWatch = ^TWatch;
  178. TWatch = Object(TObject)
  179. constructor Init(s : string);
  180. constructor Load(var S: TStream);
  181. procedure Store(var S: TStream);
  182. procedure rename(s : string);
  183. procedure Get_new_value;
  184. procedure Force_new_value;
  185. destructor done;virtual;
  186. expr : pstring;
  187. private
  188. GDBRunCount : longint;
  189. last_value,current_value : pchar;
  190. end;
  191. PWatchesCollection = ^TWatchesCollection;
  192. TWatchesCollection = Object(TCollection)
  193. constructor Init;
  194. procedure Insert(Item: Pointer); virtual;
  195. function At(Index: Integer): PWatch;
  196. procedure Update;
  197. private
  198. MaxW : integer;
  199. end;
  200. PWatchesListBox = ^TWatchesListBox;
  201. TWatchesListBox = object(THSListBox)
  202. Transparent : boolean;
  203. MaxWidth : Sw_integer;
  204. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  205. (* procedure AddWatch(P: PWatch); virtual; *)
  206. procedure Update(AMaxWidth : integer);
  207. function GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String; Virtual;
  208. function GetIndentedText(Item,Indent,MaxLen: Sw_Integer;var Modified : boolean): String; virtual;
  209. function GetLocalMenu: PMenu;virtual;
  210. (* procedure Clear; virtual;
  211. procedure TrackSource; virtual;*)
  212. procedure EditNew; virtual;
  213. procedure EditCurrent; virtual;
  214. procedure DeleteCurrent; virtual;
  215. (*procedure ToggleCurrent; *)
  216. procedure Draw; virtual;
  217. procedure HandleEvent(var Event: TEvent); virtual;
  218. constructor Load(var S: TStream);
  219. procedure Store(var S: TStream);
  220. destructor Done; virtual;
  221. end;
  222. PWatchItemDialog = ^TWatchItemDialog;
  223. TWatchItemDialog = object(TCenterDialog)
  224. constructor Init(AWatch: PWatch);
  225. function Execute: Word; virtual;
  226. private
  227. Watch : PWatch;
  228. NameIL : PEditorInputLine;
  229. TextST : PAdvancedStaticText;
  230. end;
  231. PWatchesWindow = ^TWatchesWindow;
  232. TWatchesWindow = Object(TFPDlgWindow)
  233. WLB : PWatchesListBox;
  234. Constructor Init;
  235. constructor Load(var S: TStream);
  236. procedure Store(var S: TStream);
  237. procedure Update; virtual;
  238. destructor Done; virtual;
  239. end;
  240. PFramesListBox = ^TFramesListBox;
  241. TFramesListBox = object(TMessageListBox)
  242. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  243. procedure Update;
  244. function GetLocalMenu: PMenu;virtual;
  245. procedure GotoSource; virtual;
  246. procedure GotoAssembly; virtual;
  247. procedure HandleEvent(var Event: TEvent); virtual;
  248. destructor Done; virtual;
  249. end;
  250. PStackWindow = ^TStackWindow;
  251. TStackWindow = Object(TFPDlgWindow)
  252. FLB : PFramesListBox;
  253. Constructor Init;
  254. constructor Load(var S: TStream);
  255. procedure Store(var S: TStream);
  256. procedure Update; virtual;
  257. destructor Done; virtual;
  258. end;
  259. procedure InitStackWindow;
  260. procedure DoneStackWindow;
  261. function ActiveBreakpoints : boolean;
  262. function GDBFileName(st : string) : string;
  263. function OSFileName(st : string) : string;
  264. const
  265. BreakpointTypeStr : Array[BreakpointType] of String[9]
  266. = ( 'function','file-line','watch','awatch','rwatch','address','invalid');
  267. BreakpointStateStr : Array[BreakpointState] of String[8]
  268. = ( 'enabled','disabled','invalid',''{'to be deleted' should never be used});
  269. var
  270. Debugger : PDebugController;
  271. BreakpointsCollection : PBreakpointCollection;
  272. WatchesCollection : PwatchesCollection;
  273. procedure InitDebugger;
  274. procedure DoneDebugger;
  275. procedure InitGDBWindow;
  276. procedure DoneGDBWindow;
  277. procedure InitDisassemblyWindow;
  278. procedure DoneDisassemblyWindow;
  279. procedure InitBreakpoints;
  280. procedure DoneBreakpoints;
  281. procedure InitWatches;
  282. procedure DoneWatches;
  283. procedure RegisterFPDebugViews;
  284. procedure UpdateDebugViews;
  285. implementation
  286. uses
  287. Dos,
  288. {$ifdef fpc}
  289. Video,
  290. {$endif fpc}
  291. {$ifdef DOS}
  292. fpusrscr,
  293. {$endif DOS}
  294. App,Strings,
  295. FVConsts,
  296. {$ifdef win32}
  297. Windebug,
  298. {$endif win32}
  299. {$ifdef Unix}
  300. {$ifdef VER1_0}
  301. Linux,
  302. {$else}
  303. termio,
  304. {$endif}
  305. {$endif Unix}
  306. Systems,Globals,
  307. FPRegs,
  308. FPString,FPVars,FPUtils,FPConst,FPSwitch,
  309. FPIntf,FPCompil,FPIde,FPHelp,
  310. Validate,WUtils,Wconsts;
  311. const
  312. RBreakpointsWindow: TStreamRec = (
  313. ObjType: 1701;
  314. VmtLink: Ofs(TypeOf(TBreakpointsWindow)^);
  315. Load: @TBreakpointsWindow.Load;
  316. Store: @TBreakpointsWindow.Store
  317. );
  318. RBreakpointsListBox : TStreamRec = (
  319. ObjType: 1702;
  320. VmtLink: Ofs(TypeOf(TBreakpointsListBox)^);
  321. Load: @TBreakpointsListBox.Load;
  322. Store: @TBreakpointsListBox.Store
  323. );
  324. RWatchesWindow: TStreamRec = (
  325. ObjType: 1703;
  326. VmtLink: Ofs(TypeOf(TWatchesWindow)^);
  327. Load: @TWatchesWindow.Load;
  328. Store: @TWatchesWindow.Store
  329. );
  330. RWatchesListBox: TStreamRec = (
  331. ObjType: 1704;
  332. VmtLink: Ofs(TypeOf(TWatchesListBox)^);
  333. Load: @TWatchesListBox.Load;
  334. Store: @TWatchesListBox.Store
  335. );
  336. RStackWindow: TStreamRec = (
  337. ObjType: 1705;
  338. VmtLink: Ofs(TypeOf(TStackWindow)^);
  339. Load: @TStackWindow.Load;
  340. Store: @TStackWindow.Store
  341. );
  342. RFramesListBox: TStreamRec = (
  343. ObjType: 1706;
  344. VmtLink: Ofs(TypeOf(TFramesListBox)^);
  345. Load: @TFramesListBox.Load;
  346. Store: @TFramesListBox.Store
  347. );
  348. RBreakpoint: TStreamRec = (
  349. ObjType: 1707;
  350. VmtLink: Ofs(TypeOf(TBreakpoint)^);
  351. Load: @TBreakpoint.Load;
  352. Store: @TBreakpoint.Store
  353. );
  354. RWatch: TStreamRec = (
  355. ObjType: 1708;
  356. VmtLink: Ofs(TypeOf(TWatch)^);
  357. Load: @TWatch.Load;
  358. Store: @TWatch.Store
  359. );
  360. RBreakpointCollection: TStreamRec = (
  361. ObjType: 1709;
  362. VmtLink: Ofs(TypeOf(TBreakpointCollection)^);
  363. Load: @TBreakpointCollection.Load;
  364. Store: @TBreakpointCollection.Store
  365. );
  366. RWatchesCollection: TStreamRec = (
  367. ObjType: 1710;
  368. VmtLink: Ofs(TypeOf(TWatchesCollection)^);
  369. Load: @TWatchesCollection.Load;
  370. Store: @TWatchesCollection.Store
  371. );
  372. {$ifdef I386}
  373. const
  374. FrameName = '$ebp';
  375. {$define FrameNameKnown}
  376. {$endif i386}
  377. {$ifdef m68k}
  378. const
  379. FrameName = '$fp';
  380. {$define FrameNameKnown}
  381. {$endif m68k}
  382. {$ifdef powerpc}
  383. { stack and frame registers are the same on powerpc,
  384. so I am not sure that this will work PM }
  385. const
  386. FrameName = '$r1';
  387. {$define FrameNameKnown}
  388. {$endif powerpc}
  389. {$ifdef TP}
  390. function HexStr(Value: longint; Len: byte): string;
  391. begin
  392. HexStr:=IntToHex(Value,Len);
  393. end;
  394. {$endif}
  395. function GDBFileName(st : string) : string;
  396. {$ifndef Unix}
  397. var i : longint;
  398. {$endif Unix}
  399. begin
  400. {$ifdef Unix}
  401. GDBFileName:=st;
  402. {$else}
  403. { should we also use / chars ? }
  404. for i:=1 to Length(st) do
  405. if st[i]='\' then
  406. {$ifdef win32}
  407. { Don't touch at '\ ' used to escapes spaces in windows file names PM }
  408. if (i=length(st)) or (st[i+1]<>' ') then
  409. {$endif win32}
  410. st[i]:='/';
  411. {$ifdef win32}
  412. { for win32 we should convert e:\ into //e/ PM }
  413. if (length(st)>2) and (st[2]=':') and (st[3]='/') then
  414. st:=CygDrivePrefix+'/'+st[1]+copy(st,3,length(st));
  415. { support spaces in the name by escaping them but without changing '\ ' into '\\ ' }
  416. for i:=Length(st) downto 1 do
  417. if (st[i]=' ') and ((i=1) or (st[i-1]<>'\')) then
  418. st:=copy(st,1,i-1)+'\'+copy(st,i,length(st));
  419. {$endif win32}
  420. {$ifdef go32v2}
  421. { for go32v2 we should convert //e/ back into e:/ PM }
  422. if (length(st)>3) and (st[1]='/') and (st[2]='/') and (st[4]='/') then
  423. st:=st[3]+':/'+copy(st,5,length(st));
  424. {$endif go32v2}
  425. GDBFileName:=LowerCaseStr(st);
  426. {$endif}
  427. end;
  428. function OSFileName(st : string) : string;
  429. {$ifndef Unix}
  430. var i : longint;
  431. {$endif Unix}
  432. begin
  433. {$ifdef Unix}
  434. OSFileName:=st;
  435. {$else}
  436. {$ifdef win32}
  437. { for win32 we should convert /cygdrive/e/ into e:\ PM }
  438. if pos(CygDrivePrefix+'/',st)=1 then
  439. st:=st[Length(CygdrivePrefix)+2]+':\'+copy(st,length(CygdrivePrefix)+4,length(st));
  440. {$endif win32}
  441. { support spaces in the name by escaping them but without changing '\ ' into '\\ ' }
  442. for i:=Length(st) downto 2 do
  443. if (st[i]=' ') and (st[i-1]='\') then
  444. st:=copy(st,1,i-2)+copy(st,i,length(st));
  445. {$ifdef go32v2}
  446. { for go32v2 we should convert //e/ back into e:/ PM }
  447. if (length(st)>3) and (st[1]='/') and (st[2]='/') and (st[4]='/') then
  448. st:=st[3]+':\'+copy(st,5,length(st));
  449. {$endif go32v2}
  450. { should we also use / chars ? }
  451. for i:=1 to Length(st) do
  452. if st[i]='/' then
  453. st[i]:='\';
  454. OSFileName:=LowerCaseStr(st);
  455. {$endif}
  456. end;
  457. {****************************************************************************
  458. TDebugController
  459. ****************************************************************************}
  460. procedure UpdateDebugViews;
  461. begin
  462. {$ifdef SUPPORT_REMOTE}
  463. PushStatus(msg_getting_info_on+RemoteMachine);
  464. {$endif SUPPORT_REMOTE}
  465. DeskTop^.Lock;
  466. If assigned(StackWindow) then
  467. StackWindow^.Update;
  468. If assigned(RegistersWindow) then
  469. RegistersWindow^.Update;
  470. If assigned(Debugger) then
  471. Debugger^.ReadWatches;
  472. If assigned(FPUWindow) then
  473. FPUWindow^.Update;
  474. DeskTop^.UnLock;
  475. {$ifdef SUPPORT_REMOTE}
  476. PopStatus;
  477. {$endif SUPPORT_REMOTE}
  478. end;
  479. constructor TDebugController.Init;
  480. begin
  481. inherited Init;
  482. CenterDebuggerRow:=IniCenterDebuggerRow;
  483. Disableallinvalidbreakpoints:=false;
  484. NoSwitch:=False;
  485. HasExe:=false;
  486. Debugger:=@self;
  487. WindowWidth:=-1;
  488. switch_to_user:=true;
  489. GetDir(0,OrigPwd);
  490. Command('set print object off');
  491. end;
  492. procedure TDebugController.SetExe(const exefn:string);
  493. var f : string;
  494. begin
  495. f := GDBFileName(GetShortName(exefn));
  496. if (f<>'') and ExistsFile(exefn) then
  497. begin
  498. LoadFile(f);
  499. HasExe:=true;
  500. Command('b FPC_BREAK_ERROR');
  501. FPCBreakErrorNumber:=last_breakpoint_number;
  502. {$ifdef FrameNameKnown}
  503. { this fails in GDB 5.1 because
  504. GDB replies that there is an attempt to dereference
  505. a generic pointer...
  506. test delayed in DoSourceLine... PM
  507. Command('cond '+IntToStr(FPCBreakErrorNumber)+
  508. ' (('+FrameName+' + 8)^ <> 0) or'+
  509. ' (('+FrameName+' + 12)^ <> 0)'); }
  510. {$endif FrameNameKnown}
  511. SetArgs(GetRunParameters);
  512. SetDir(GetRunDir);
  513. SetSourceDirs;
  514. InsertBreakpoints;
  515. ReadWatches;
  516. end
  517. else
  518. begin
  519. HasExe:=false;
  520. Command('file');
  521. end;
  522. end;
  523. procedure TDebugController.SetWidth(AWidth : longint);
  524. begin
  525. WindowWidth:=AWidth;
  526. Command('set width '+inttostr(WindowWidth));
  527. end;
  528. procedure TDebugController.SetSourceDirs;
  529. var f,s: string;
  530. i : longint;
  531. Dir : SearchRec;
  532. begin
  533. f:=GetSourceDirectories+';'+OrigPwd;
  534. repeat
  535. i:=pos(';',f);
  536. if i=0 then
  537. s:=f
  538. else
  539. begin
  540. s:=copy(f,1,i-1);
  541. system.delete(f,1,i);
  542. end;
  543. DefaultReplacements(s);
  544. if (pos('*',s)=0) and ExistsDir(s) then
  545. Command('dir '+GDBFileName(GetShortName(s)))
  546. { we should also handle the /* cases of -Fu option }
  547. else if pos('*',s)>0 then
  548. begin
  549. Dos.FindFirst(s,Directory,Dir);
  550. { the '*' can only be in the last dir level }
  551. s:=DirOf(s);
  552. while Dos.DosError=0 do
  553. begin
  554. if ((Dir.attr and Directory) <> 0) and ExistsDir(s+Dir.Name) then
  555. Command('dir '+GDBFileName(GetShortName(s+Dir.Name)));
  556. Dos.FindNext(Dir);
  557. end;
  558. {$ifdef FPC}
  559. Dos.FindClose(Dir);
  560. {$endif def FPC}
  561. end;
  562. until i=0;
  563. end;
  564. procedure TDebugController.InsertBreakpoints;
  565. procedure DoInsert(PB : PBreakpoint);
  566. begin
  567. PB^.Insert;
  568. end;
  569. begin
  570. BreakpointsCollection^.ForEach(@DoInsert);
  571. Disableallinvalidbreakpoints:=false;
  572. end;
  573. procedure TDebugController.ReadWatches;
  574. procedure DoRead(PB : PWatch);
  575. begin
  576. PB^.Get_new_value;
  577. end;
  578. begin
  579. WatchesCollection^.ForEach(@DoRead);
  580. If Assigned(WatchesWindow) then
  581. WatchesWindow^.Update;
  582. end;
  583. procedure TDebugController.RereadWatches;
  584. procedure DoRead(PB : PWatch);
  585. begin
  586. PB^.Force_new_value;
  587. end;
  588. begin
  589. WatchesCollection^.ForEach(@DoRead);
  590. If Assigned(WatchesWindow) then
  591. WatchesWindow^.Update;
  592. end;
  593. procedure TDebugController.RemoveBreakpoints;
  594. procedure DoDelete(PB : PBreakpoint);
  595. begin
  596. PB^.Remove;
  597. end;
  598. begin
  599. BreakpointsCollection^.ForEach(@DoDelete);
  600. end;
  601. procedure TDebugController.ResetBreakpointsValues;
  602. procedure DoResetVal(PB : PBreakpoint);
  603. begin
  604. PB^.ResetValues;
  605. end;
  606. begin
  607. BreakpointsCollection^.ForEach(@DoResetVal);
  608. end;
  609. function ActiveBreakpoints : boolean;
  610. var
  611. IsActive : boolean;
  612. procedure TestActive(PB : PBreakpoint);
  613. begin
  614. If PB^.state=bs_enabled then
  615. IsActive:=true;
  616. end;
  617. begin
  618. IsActive:=false;
  619. If assigned(BreakpointsCollection) then
  620. BreakpointsCollection^.ForEach(@TestActive);
  621. ActiveBreakpoints:=IsActive;
  622. end;
  623. destructor TDebugController.Done;
  624. begin
  625. { kill the program if running }
  626. Reset;
  627. RemoveBreakpoints;
  628. inherited Done;
  629. end;
  630. procedure TDebugController.Run;
  631. {$ifdef Unix}
  632. var
  633. Debuggeefile : text;
  634. ResetOK, TTYUsed : boolean;
  635. {$endif Unix}
  636. {$ifdef PALMOSGDB}
  637. const
  638. TargetProtocol = 'palmos';
  639. {$else}
  640. const
  641. TargetProtocol = 'remote';
  642. {$endif PALMOSGDB}
  643. {$ifdef SUPPORT_REMOTE}
  644. var
  645. S,ErrorStr : string;
  646. {$endif SUPPORT_REMOTE}
  647. begin
  648. ResetBreakpointsValues;
  649. {$ifdef SUPPORT_REMOTE}
  650. NoSwitch:=true;
  651. isRemoteDebugging:=false;
  652. {$ifndef CROSSGDB}
  653. If (RemoteMachine<>'') and (RemotePort<>'') then
  654. {$else CROSSGDB}
  655. if true then
  656. {$endif CROSSGDB}
  657. begin
  658. isRemoteDebugging:=true;
  659. S:=RemoteMachine;
  660. If pos('@',S)>0 then
  661. S:=copy(S,pos('@',S)+1,High(S));
  662. If RemotePort<>'' then
  663. S:=S+':'+RemotePort;
  664. {$ifdef PALMOSGDB}
  665. { set the default value for PalmOS }
  666. If S='' then
  667. S:='localhost:2000';
  668. {$endif PALMOSGDB}
  669. PushStatus(msg_connectingto+S);
  670. Command('target '+TargetProtocol+' '+S);
  671. if Error then
  672. begin
  673. ErrorStr:=strpas(GetError);
  674. ErrorBox(#3'Error in "target '+TargetProtocol+'"'#13#3+ErrorStr,nil);
  675. PopStatus;
  676. exit;
  677. end;
  678. PopStatus;
  679. end
  680. else
  681. begin
  682. {$endif SUPPORT_REMOTE}
  683. {$ifdef win32}
  684. { Run the debugge in another console }
  685. if DebuggeeTTY<>'' then
  686. Command('set new-console on')
  687. else
  688. Command('set new-console off');
  689. NoSwitch:=DebuggeeTTY<>'';
  690. {$endif win32}
  691. {$ifdef Unix}
  692. { Run the debuggee in another tty }
  693. if DebuggeeTTY <> '' then
  694. begin
  695. {$I-}
  696. Assign(Debuggeefile,DebuggeeTTY);
  697. system.Reset(Debuggeefile);
  698. ResetOK:=IOResult=0;
  699. If ResetOK and {$ifdef ver1_0}IsATTY(textrec(Debuggeefile).handle){$else}(IsATTY(textrec(Debuggeefile).handle)<>-1){$endif} then
  700. begin
  701. Command('tty '+DebuggeeTTY);
  702. TTYUsed:=true;
  703. end
  704. else
  705. begin
  706. Command('tty ');
  707. TTYUsed:=false;
  708. end;
  709. if ResetOK then
  710. close(Debuggeefile);
  711. if TTYUsed and (DebuggeeTTY<>TTYName(stdout)) then
  712. NoSwitch:= true
  713. else
  714. NoSwitch:=false;
  715. end
  716. else
  717. begin
  718. if TTYName(input)<>'' then
  719. Command('tty '+TTYName(input));
  720. NoSwitch := false;
  721. end;
  722. {$endif Unix}
  723. {$ifdef SUPPORT_REMOTE}
  724. end;
  725. {$endif SUPPORT_REMOTE}
  726. { Switch to user screen to get correct handles }
  727. UserScreen;
  728. { Don't try to print GDB messages while in User Screen mode }
  729. If assigned(GDBWindow) then
  730. GDBWindow^.Editor^.Lock;
  731. {$ifdef SUPPORT_REMOTE}
  732. if isRemoteDebugging then
  733. begin
  734. inc(init_count);
  735. { pass the stop in start code }
  736. Command('continue');
  737. end else
  738. {$endif SUPPORT_REMOTE}
  739. inherited Run;
  740. DebuggerScreen;
  741. If assigned(GDBWindow) then
  742. GDBWindow^.Editor^.UnLock;
  743. IDEApp.SetCmdState([cmResetDebugger,cmUntilReturn],true);
  744. IDEApp.UpdateRunMenu(true);
  745. UpdateDebugViews;
  746. end;
  747. function TDebugController.IsRunning : boolean;
  748. begin
  749. IsRunning:=debuggee_started;
  750. end;
  751. procedure TDebugController.Continue;
  752. begin
  753. {$ifdef NODEBUG}
  754. NoDebugger;
  755. {$else}
  756. if not debuggee_started then
  757. Run
  758. else
  759. inherited Continue;
  760. UpdateDebugViews;
  761. {$endif NODEBUG}
  762. end;
  763. procedure TDebugController.UntilReturn;
  764. begin
  765. Command('finish');
  766. UpdateDebugViews;
  767. { We could try to get the return value !
  768. Not done yet }
  769. end;
  770. procedure TDebugController.CommandBegin(const s:string);
  771. begin
  772. if assigned(GDBWindow) and (in_command>1) then
  773. begin
  774. { We should do something special for errors !! }
  775. If StrLen(GetError)>0 then
  776. GDBWindow^.WriteErrorText(GetError);
  777. GDBWindow^.WriteOutputText(GetOutput);
  778. end;
  779. if assigned(GDBWindow) then
  780. GDBWindow^.WriteString(S);
  781. end;
  782. procedure TDebugController.CommandEnd(const s:string);
  783. begin
  784. if assigned(GDBWindow) and (in_command<=1) then
  785. begin
  786. { We should do something special for errors !! }
  787. If StrLen(GetError)>0 then
  788. GDBWindow^.WriteErrorText(GetError);
  789. GDBWindow^.WriteOutputText(GetOutput);
  790. GDBWindow^.Editor^.TextEnd;
  791. end;
  792. end;
  793. function TDebugController.AllowQuit : boolean;
  794. begin
  795. if IsRunning then
  796. begin
  797. if ConfirmBox('Really quit GDB window'#13+
  798. 'and kill running program?',nil,true)=cmYes then
  799. begin
  800. Reset;
  801. DoneGDBWindow;
  802. {AllowQuit:=true;}
  803. AllowQuit:=false;
  804. end
  805. else
  806. AllowQuit:=false;
  807. end
  808. else if ConfirmBox('Really quit GDB window?',nil,true)=cmYes then
  809. begin
  810. DoneGDBWindow;
  811. {AllowQuit:=true;}
  812. AllowQuit:=false;
  813. end
  814. else
  815. AllowQuit:=false;
  816. end;
  817. procedure TDebugController.ResetDebuggerRows;
  818. procedure ResetDebuggerRow(P: PView); {$ifndef FPC}far;{$endif}
  819. begin
  820. if assigned(P) and
  821. (TypeOf(P^)=TypeOf(TSourceWindow)) then
  822. PSourceWindow(P)^.Editor^.SetLineFlagExclusive(lfDebuggerRow,-1);
  823. end;
  824. begin
  825. Desktop^.ForEach(@ResetDebuggerRow);
  826. end;
  827. procedure TDebugController.Reset;
  828. begin
  829. inherited Reset;
  830. { we need to free the executable
  831. if we want to recompile it }
  832. SetExe('');
  833. NoSwitch:=false;
  834. { In case we have something that the compiler touched }
  835. If IDEApp.IsRunning then
  836. begin
  837. IDEApp.SetCmdState([cmResetDebugger,cmUntilReturn],false);
  838. IDEApp.UpdateRunMenu(false);
  839. AskToReloadAllModifiedFiles;
  840. ResetDebuggerRows;
  841. end;
  842. end;
  843. procedure TDebugController.AnnotateError;
  844. var errornb : longint;
  845. begin
  846. if error then
  847. begin
  848. errornb:=error_num;
  849. UpdateDebugViews;
  850. ErrorBox(#3'Error within GDB'#13#3'Error code = %d',@errornb);
  851. end;
  852. end;
  853. function TDebugController.GetValue(Const expr : string) : pchar;
  854. var
  855. p,p2,p3 : pchar;
  856. begin
  857. if WindowWidth<>-1 then
  858. Command('set width 0xffffffff');
  859. Command('p '+expr);
  860. p:=GetOutput;
  861. p3:=nil;
  862. if assigned(p) and (p[strlen(p)-1]=#10) then
  863. begin
  864. p3:=p+strlen(p)-1;
  865. p3^:=#0;
  866. end;
  867. if assigned(p) then
  868. p2:=strpos(p,'=')
  869. else
  870. p2:=nil;
  871. if assigned(p2) then
  872. p:=p2+1;
  873. while p^ in [' ',TAB] do
  874. inc(p);
  875. { get rid of type }
  876. if p^ = '(' then
  877. p:=strpos(p,')')+1;
  878. while p^ in [' ',TAB] do
  879. inc(p);
  880. if assigned(p) then
  881. GetValue:=StrNew(p)
  882. else
  883. GetValue:=StrNew(GetError);
  884. if assigned(p3) then
  885. p3^:=#10;
  886. got_error:=false;
  887. if WindowWidth<>-1 then
  888. Command('set width '+IntToStr(WindowWidth));
  889. end;
  890. function TDebugController.GetFramePointer : CORE_ADDR;
  891. var
  892. st : string;
  893. p : longint;
  894. begin
  895. {$ifdef FrameNameKnown}
  896. Command('p /d '+FrameName);
  897. st:=strpas(GetOutput);
  898. p:=pos('=',st);
  899. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  900. inc(p);
  901. Delete(st,1,p);
  902. p:=1;
  903. while (st[p] in ['0'..'9']) do
  904. inc(p);
  905. Delete(st,p,High(st));
  906. GetFramePointer:=StrToCard(st);
  907. {$else not FrameNameKnown}
  908. GetFramePointer:=0;
  909. {$endif not FrameNameKnown}
  910. end;
  911. function TDebugController.GetLongintAt(addr : CORE_ADDR) : longint;
  912. var
  913. st : string;
  914. p : longint;
  915. begin
  916. Command('x /wd 0x'+hexstr(longint(addr),8));
  917. st:=strpas(GetOutput);
  918. p:=pos(':',st);
  919. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  920. inc(p);
  921. Delete(st,1,p);
  922. p:=1;
  923. while (st[p] in ['0'..'9']) do
  924. inc(p);
  925. Delete(st,p,High(st));
  926. GetLongintAt:=StrToInt(st);
  927. end;
  928. function TDebugController.GetPointerAt(addr : CORE_ADDR) : CORE_ADDR;
  929. var
  930. st : string;
  931. p : longint;
  932. begin
  933. Command('x /wx 0x'+hexstr(longint(addr),8));
  934. st:=strpas(GetOutput);
  935. p:=pos(':',st);
  936. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  937. inc(p);
  938. if (p<length(st)) and (st[p+1]='$') then
  939. inc(p);
  940. Delete(st,1,p);
  941. p:=1;
  942. while (st[p] in ['0'..'9','A'..'F','a'..'f']) do
  943. inc(p);
  944. Delete(st,p,High(st));
  945. GetPointerAt:=HexToCard(st);
  946. end;
  947. procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
  948. var
  949. W: PSourceWindow;
  950. Found : boolean;
  951. PB : PBreakpoint;
  952. S : String;
  953. BreakIndex : longint;
  954. stop_addr : CORE_ADDR;
  955. i,ExitCode : longint;
  956. ExitAddr,ExitFrame : CORE_ADDR;
  957. const
  958. FirstArgOffset = 2 * sizeof(CORE_ADDR);
  959. SecondArgOffset = 3 * sizeof(CORE_ADDR);
  960. ThirdArgOffset = 4 * sizeof(CORE_ADDR);
  961. begin
  962. BreakIndex:=stop_breakpoint_number;
  963. Desktop^.Lock;
  964. { 0 based line count in Editor }
  965. if Line>0 then
  966. dec(Line);
  967. S:=fn;
  968. stop_addr:=current_pc;
  969. if (BreakIndex=FPCBreakErrorNumber) then
  970. begin
  971. { Procedure HandleErrorAddrFrame
  972. (Errno : longint;addr,frame : longint);
  973. [public,alias:'FPC_BREAK_ERROR']; }
  974. {$ifdef FrameNameKnown}
  975. ExitCode:=GetLongintAt(GetFramePointer+FirstArgOffset);
  976. ExitAddr:=GetPointerAt(GetFramePointer+SecondArgOffset);
  977. ExitFrame:=GetPointerAt(GetFramePointer+ThirdArgOffset);
  978. if (ExitCode=0) and (ExitAddr=0) then
  979. begin
  980. Desktop^.Unlock;
  981. Command('continue');
  982. exit;
  983. end;
  984. { forget all old frames }
  985. clear_frames;
  986. { record new frames }
  987. Command('backtrace');
  988. for i:=0 to frame_count-1 do
  989. begin
  990. with frames[i]^ do
  991. begin
  992. if ExitAddr=address then
  993. begin
  994. Command('f '+IntToStr(i));
  995. if assigned(file_name) then
  996. begin
  997. s:=strpas(file_name);
  998. line:=line_number;
  999. stop_addr:=address;
  1000. end;
  1001. break;
  1002. end;
  1003. end;
  1004. end;
  1005. {$endif FrameNameKnown}
  1006. end;
  1007. { Update Disassembly position }
  1008. if Assigned(DisassemblyWindow) then
  1009. DisassemblyWindow^.SetCurAddress(stop_addr);
  1010. if (fn=LastFileName) then
  1011. begin
  1012. W:=PSourceWindow(LastSource);
  1013. if assigned(W) then
  1014. begin
  1015. W^.Editor^.SetCurPtr(0,Line);
  1016. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1017. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1018. UpdateDebugViews;
  1019. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1020. handled by SelectInDebugSession}
  1021. W^.SelectInDebugSession;
  1022. InvalidSourceLine:=false;
  1023. end
  1024. else
  1025. InvalidSourceLine:=true;
  1026. end
  1027. else
  1028. begin
  1029. if s='' then
  1030. W:=nil
  1031. else
  1032. W:=TryToOpenFile(nil,s,0,Line,false);
  1033. if assigned(W) then
  1034. begin
  1035. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1036. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1037. UpdateDebugViews;
  1038. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1039. handled by SelectInDebugSession}
  1040. W^.SelectInDebugSession;
  1041. LastSource:=W;
  1042. InvalidSourceLine:=false;
  1043. end
  1044. { only search a file once }
  1045. else
  1046. begin
  1047. Desktop^.UnLock;
  1048. if s='' then
  1049. Found:=false
  1050. else
  1051. { it is easier to handle with a * at the end }
  1052. Found:=IDEApp.OpenSearch(s+'*');
  1053. Desktop^.Lock;
  1054. if not Found then
  1055. begin
  1056. InvalidSourceLine:=true;
  1057. LastSource:=Nil;
  1058. { Show the stack in that case }
  1059. InitStackWindow;
  1060. UpdateDebugViews;
  1061. StackWindow^.MakeFirst;
  1062. end
  1063. else
  1064. begin
  1065. { should now be open }
  1066. W:=TryToOpenFile(nil,s,0,Line,true);
  1067. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1068. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1069. UpdateDebugViews;
  1070. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1071. handled by SelectInDebugSession}
  1072. W^.SelectInDebugSession;
  1073. LastSource:=W;
  1074. InvalidSourceLine:=false;
  1075. end;
  1076. end;
  1077. end;
  1078. LastFileName:=s;
  1079. Desktop^.UnLock;
  1080. if BreakIndex>0 then
  1081. begin
  1082. PB:=BreakpointsCollection^.GetGDB(BreakIndex);
  1083. if (BreakIndex=FPCBreakErrorNumber) then
  1084. begin
  1085. if (ExitCode<>0) or (ExitAddr<>0) then
  1086. WarningBox(#3'Run Time Error '+IntToStr(ExitCode)+#13+
  1087. #3'Error address $'+IntToHex(ExitAddr,8),nil)
  1088. else
  1089. WarningBox(#3'Run Time Error',nil);
  1090. end
  1091. else if not assigned(PB) then
  1092. begin
  1093. WarningBox(#3'Stopped by breakpoint '+IntToStr(BreakIndex),nil);
  1094. end
  1095. { For watch we should get old and new value !! }
  1096. else if (Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive)) and
  1097. (PB^.typ<>bt_file_line) and (PB^.typ<>bt_function) and
  1098. (PB^.typ<>bt_address) then
  1099. begin
  1100. Command('p '+GetStr(PB^.Name));
  1101. S:=GetPChar(GetOutput);
  1102. got_error:=false;
  1103. If Pos('=',S)>0 then
  1104. S:=Copy(S,Pos('=',S)+1,255);
  1105. If S[Length(S)]=#10 then
  1106. Delete(S,Length(S),1);
  1107. if Assigned(PB^.OldValue) then
  1108. DisposeStr(PB^.OldValue);
  1109. PB^.OldValue:=PB^.CurrentValue;
  1110. PB^.CurrentValue:=NewStr(S);
  1111. If PB^.typ=bt_function then
  1112. WarningBox(#3'GDB stopped due to'#13+
  1113. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name),nil)
  1114. else if (GetStr(PB^.OldValue)<>S) then
  1115. WarningBox(#3'GDB stopped due to'#13+
  1116. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  1117. #3+'Old value = '+GetStr(PB^.OldValue)+#13+
  1118. #3+'New value = '+GetStr(PB^.CurrentValue),nil)
  1119. else
  1120. WarningBox(#3'GDB stopped due to'#13+
  1121. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  1122. #3+' value = '+GetStr(PB^.CurrentValue),nil);
  1123. end;
  1124. end;
  1125. end;
  1126. procedure TDebugController.DoUserSignal;
  1127. var P :Array[1..2] of pstring;
  1128. S1, S2 : string;
  1129. begin
  1130. S1:=strpas(signal_name);
  1131. S2:=strpas(signal_string);
  1132. P[1]:=@S1;
  1133. P[2]:=@S2;
  1134. WarningBox(msg_programsignal,@P);
  1135. end;
  1136. procedure TDebugController.DoEndSession(code:longint);
  1137. var P :Array[1..2] of longint;
  1138. begin
  1139. IDEApp.SetCmdState([cmUntilReturn,cmResetDebugger],false);
  1140. IDEApp.UpdateRunMenu(false);
  1141. ResetDebuggerRows;
  1142. LastExitCode:=Code;
  1143. If HiddenStepsCount=0 then
  1144. InformationBox(msg_programexitedwithexitcode,@code)
  1145. else
  1146. begin
  1147. P[1]:=code;
  1148. P[2]:=HiddenStepsCount;
  1149. WarningBox(msg_programexitedwithcodeandsteps,@P);
  1150. end;
  1151. { In case we have something that the compiler touched }
  1152. AskToReloadAllModifiedFiles;
  1153. {$ifdef win32}
  1154. main_pid_valid:=false;
  1155. {$endif win32}
  1156. end;
  1157. procedure TDebugController.DoDebuggerScreen;
  1158. {$ifdef win32}
  1159. var
  1160. IdeMode : DWord;
  1161. {$endif win32}
  1162. begin
  1163. if NoSwitch then
  1164. begin
  1165. PopStatus;
  1166. end
  1167. else
  1168. begin
  1169. IDEApp.ShowIDEScreen;
  1170. Message(Application,evBroadcast,cmDebuggerStopped,pointer(RunCount));
  1171. PopStatus;
  1172. end;
  1173. {$ifdef win32}
  1174. if NoSwitch then
  1175. begin
  1176. { Ctrl-C as normal char }
  1177. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @IdeMode);
  1178. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT or ENABLE_WINDOW_INPUT) and not ENABLE_PROCESSED_INPUT;
  1179. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), IdeMode);
  1180. end;
  1181. ChangeDebuggeeWindowTitleTo(Stopped_State);
  1182. {$endif win32}
  1183. end;
  1184. procedure TDebugController.DoUserScreen;
  1185. {$ifdef win32}
  1186. var
  1187. IdeMode : DWord;
  1188. {$endif win32}
  1189. begin
  1190. Inc(RunCount);
  1191. if NoSwitch then
  1192. begin
  1193. {$ifdef SUPPORT_REMOTE}
  1194. PushStatus(msg_runningremotely+RemoteMachine);
  1195. {$else not SUPPORT_REMOTE}
  1196. {$ifdef Unix}
  1197. PushStatus(msg_runninginanotherwindow+DebuggeeTTY);
  1198. {$else not Unix}
  1199. PushStatus(msg_runninginanotherwindow);
  1200. {$endif Unix}
  1201. {$endif not SUPPORT_REMOTE}
  1202. end
  1203. else
  1204. begin
  1205. PushStatus(msg_runningprogram);
  1206. IDEApp.ShowUserScreen;
  1207. end;
  1208. {$ifdef win32}
  1209. if NoSwitch then
  1210. begin
  1211. { Ctrl-C as interrupt }
  1212. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @IdeMode);
  1213. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT or ENABLE_PROCESSED_INPUT or ENABLE_WINDOW_INPUT);
  1214. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), IdeMode);
  1215. end;
  1216. ChangeDebuggeeWindowTitleTo(Running_State);
  1217. {$endif win32}
  1218. end;
  1219. {****************************************************************************
  1220. TBreakpoint
  1221. ****************************************************************************}
  1222. constructor TBreakpoint.Init_function(Const AFunc : String);
  1223. begin
  1224. typ:=bt_function;
  1225. state:=bs_enabled;
  1226. GDBState:=bs_deleted;
  1227. Name:=NewStr(AFunc);
  1228. FileName:=nil;
  1229. Line:=0;
  1230. IgnoreCount:=0;
  1231. Commands:=nil;
  1232. Conditions:=nil;
  1233. OldValue:=nil;
  1234. CurrentValue:=nil;
  1235. end;
  1236. constructor TBreakpoint.Init_Address(Const AAddress : String);
  1237. begin
  1238. typ:=bt_address;
  1239. state:=bs_enabled;
  1240. GDBState:=bs_deleted;
  1241. Name:=NewStr(AAddress);
  1242. FileName:=nil;
  1243. Line:=0;
  1244. IgnoreCount:=0;
  1245. Commands:=nil;
  1246. Conditions:=nil;
  1247. OldValue:=nil;
  1248. CurrentValue:=nil;
  1249. end;
  1250. constructor TBreakpoint.Init_Empty;
  1251. begin
  1252. typ:=bt_function;
  1253. state:=bs_enabled;
  1254. GDBState:=bs_deleted;
  1255. Name:=Nil;
  1256. FileName:=nil;
  1257. Line:=0;
  1258. IgnoreCount:=0;
  1259. Commands:=nil;
  1260. Conditions:=nil;
  1261. OldValue:=nil;
  1262. CurrentValue:=nil;
  1263. end;
  1264. constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AnExpr : String);
  1265. begin
  1266. typ:=atyp;
  1267. state:=bs_enabled;
  1268. GDBState:=bs_deleted;
  1269. Name:=NewStr(AnExpr);
  1270. IgnoreCount:=0;
  1271. Commands:=nil;
  1272. Conditions:=nil;
  1273. OldValue:=nil;
  1274. CurrentValue:=nil;
  1275. end;
  1276. constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
  1277. var
  1278. CurDir : String;
  1279. begin
  1280. typ:=bt_file_line;
  1281. state:=bs_enabled;
  1282. GDBState:=bs_deleted;
  1283. AFile:=FEXpand(AFile);
  1284. (*
  1285. { d:test.pas:12 does not work !! }
  1286. { I do not know how to solve this if
  1287. if (Length(AFile)>1) and (AFile[2]=':') then
  1288. AFile:=Copy(AFile,3,255); }
  1289. {$ifdef Unix}
  1290. CurDir:=GetCurDir;
  1291. {$else}
  1292. CurDir:=LowerCaseStr(GetCurDir);
  1293. {$endif Unix}
  1294. if Pos(CurDir,OSFileName(AFile))=1 then
  1295. FileName:=NewStr(Copy(OSFileName(AFile),length(CurDir)+1,255))
  1296. else
  1297. *)
  1298. FileName:=NewStr(OSFileName(AFile));
  1299. Name:=nil;
  1300. Line:=ALine;
  1301. IgnoreCount:=0;
  1302. Commands:=nil;
  1303. Conditions:=nil;
  1304. OldValue:=nil;
  1305. CurrentValue:=nil;
  1306. end;
  1307. constructor TBreakpoint.Load(var S: TStream);
  1308. var
  1309. FName : PString;
  1310. begin
  1311. S.Read(typ,SizeOf(BreakpointType));
  1312. S.Read(state,SizeOf(BreakpointState));
  1313. GDBState:=bs_deleted;
  1314. case typ of
  1315. bt_file_line :
  1316. begin
  1317. { convert to current target }
  1318. FName:=S.ReadStr;
  1319. FileName:=NewStr(OSFileName(GetStr(FName)));
  1320. If Assigned(FName) then
  1321. DisposeStr(FName);
  1322. S.Read(Line,SizeOf(Line));
  1323. Name:=nil;
  1324. end;
  1325. else
  1326. begin
  1327. Name:=S.ReadStr;
  1328. Line:=0;
  1329. FileName:=nil;
  1330. end;
  1331. end;
  1332. S.Read(IgnoreCount,SizeOf(IgnoreCount));
  1333. Commands:=S.StrRead;
  1334. Conditions:=S.ReadStr;
  1335. OldValue:=nil;
  1336. CurrentValue:=nil;
  1337. end;
  1338. procedure TBreakpoint.Store(var S: TStream);
  1339. var
  1340. St : String;
  1341. begin
  1342. S.Write(typ,SizeOf(BreakpointType));
  1343. S.Write(state,SizeOf(BreakpointState));
  1344. case typ of
  1345. bt_file_line :
  1346. begin
  1347. st:=OSFileName(GetStr(FileName));
  1348. S.WriteStr(@St);
  1349. S.Write(Line,SizeOf(Line));
  1350. end;
  1351. else
  1352. begin
  1353. S.WriteStr(Name);
  1354. end;
  1355. end;
  1356. S.Write(IgnoreCount,SizeOf(IgnoreCount));
  1357. S.StrWrite(Commands);
  1358. S.WriteStr(Conditions);
  1359. end;
  1360. procedure TBreakpoint.Insert;
  1361. var
  1362. p,p2 : pchar;
  1363. st : string;
  1364. begin
  1365. If not assigned(Debugger) then Exit;
  1366. Remove;
  1367. Debugger^.last_breakpoint_number:=0;
  1368. if (GDBState=bs_deleted) and (state=bs_enabled) then
  1369. begin
  1370. if (typ=bt_file_line) and assigned(FileName) then
  1371. Debugger^.Command('break '+GDBFileName(NameAndExtOf(GetStr(FileName)))+':'+IntToStr(Line))
  1372. else if (typ=bt_function) and assigned(name) then
  1373. Debugger^.Command('break '+name^)
  1374. else if (typ=bt_address) and assigned(name) then
  1375. Debugger^.Command('break *0x'+name^)
  1376. else if (typ=bt_watch) and assigned(name) then
  1377. Debugger^.Command('watch '+name^)
  1378. else if (typ=bt_awatch) and assigned(name) then
  1379. Debugger^.Command('awatch '+name^)
  1380. else if (typ=bt_rwatch) and assigned(name) then
  1381. Debugger^.Command('rwatch '+name^);
  1382. if Debugger^.last_breakpoint_number<>0 then
  1383. begin
  1384. GDBIndex:=Debugger^.last_breakpoint_number;
  1385. GDBState:=bs_enabled;
  1386. Debugger^.Command('cond '+IntToStr(GDBIndex)+' '+GetStr(Conditions));
  1387. If IgnoreCount>0 then
  1388. Debugger^.Command('ignore '+IntToStr(GDBIndex)+' '+IntToStr(IgnoreCount));
  1389. If Assigned(Commands) then
  1390. begin
  1391. {Commands are not handled yet }
  1392. Debugger^.Command('command '+IntToStr(GDBIndex));
  1393. p:=commands;
  1394. while assigned(p) do
  1395. begin
  1396. p2:=strscan(p,#10);
  1397. if assigned(p2) then
  1398. p2^:=#0;
  1399. st:=strpas(p);
  1400. Debugger^.command(st);
  1401. if assigned(p2) then
  1402. p2^:=#10;
  1403. p:=p2;
  1404. if assigned(p) then
  1405. inc(p);
  1406. end;
  1407. Debugger^.Command('end');
  1408. end;
  1409. end
  1410. else
  1411. { Here there was a problem !! }
  1412. begin
  1413. GDBIndex:=0;
  1414. if not Debugger^.Disableallinvalidbreakpoints then
  1415. begin
  1416. if (typ=bt_file_line) and assigned(FileName) then
  1417. begin
  1418. ClearFormatParams;
  1419. AddFormatParamStr(NameAndExtOf(FileName^));
  1420. AddFormatParamInt(Line);
  1421. if ChoiceBox(msg_couldnotsetbreakpointat,@FormatParams,[btn_ok,button_DisableAllBreakpoints],false)=cmUserBtn2 then
  1422. Debugger^.Disableallinvalidbreakpoints:=true;
  1423. end
  1424. else
  1425. begin
  1426. ClearFormatParams;
  1427. AddFormatParamStr(BreakpointTypeStr[typ]);
  1428. AddFormatParamStr(GetStr(Name));
  1429. if ChoiceBox(msg_couldnotsetbreakpointtype,@FormatParams,[btn_ok,button_DisableAllBreakpoints],false)=cmUserBtn2 then
  1430. Debugger^.Disableallinvalidbreakpoints:=true;
  1431. end;
  1432. end;
  1433. state:=bs_disabled;
  1434. UpdateSource;
  1435. end;
  1436. end
  1437. else if (GDBState=bs_disabled) and (state=bs_enabled) then
  1438. Enable
  1439. else if (GDBState=bs_enabled) and (state=bs_disabled) then
  1440. Disable;
  1441. end;
  1442. procedure TBreakpoint.Remove;
  1443. begin
  1444. If not assigned(Debugger) then Exit;
  1445. if GDBIndex>0 then
  1446. Debugger^.Command('delete '+IntToStr(GDBIndex));
  1447. GDBIndex:=0;
  1448. GDBState:=bs_deleted;
  1449. end;
  1450. procedure TBreakpoint.Enable;
  1451. begin
  1452. If not assigned(Debugger) then Exit;
  1453. if GDBIndex>0 then
  1454. Debugger^.Command('enable '+IntToStr(GDBIndex))
  1455. else
  1456. Insert;
  1457. GDBState:=bs_enabled;
  1458. end;
  1459. procedure TBreakpoint.Disable;
  1460. begin
  1461. If not assigned(Debugger) then Exit;
  1462. if GDBIndex>0 then
  1463. Debugger^.Command('disable '+IntToStr(GDBIndex));
  1464. GDBState:=bs_disabled;
  1465. end;
  1466. procedure TBreakpoint.ResetValues;
  1467. begin
  1468. if assigned(OldValue) then
  1469. DisposeStr(OldValue);
  1470. OldValue:=nil;
  1471. if assigned(CurrentValue) then
  1472. DisposeStr(CurrentValue);
  1473. CurrentValue:=nil;
  1474. end;
  1475. procedure TBreakpoint.UpdateSource;
  1476. var W: PSourceWindow;
  1477. b : boolean;
  1478. begin
  1479. if typ=bt_file_line then
  1480. begin
  1481. W:=SearchOnDesktop(OSFileName(GetStr(FileName)),false);
  1482. If assigned(W) then
  1483. begin
  1484. if state=bs_enabled then
  1485. b:=true
  1486. else
  1487. b:=false;
  1488. W^.Editor^.SetLineFlagState(Line-1,lfBreakpoint,b);
  1489. end;
  1490. end;
  1491. end;
  1492. destructor TBreakpoint.Done;
  1493. begin
  1494. Remove;
  1495. ResetValues;
  1496. if assigned(Name) then
  1497. DisposeStr(Name);
  1498. if assigned(FileName) then
  1499. DisposeStr(FileName);
  1500. if assigned(Conditions) then
  1501. DisposeStr(Conditions);
  1502. if assigned(Commands) then
  1503. StrDispose(Commands);
  1504. inherited Done;
  1505. end;
  1506. {****************************************************************************
  1507. TBreakpointCollection
  1508. ****************************************************************************}
  1509. function TBreakpointCollection.At(Index: Integer): PBreakpoint;
  1510. begin
  1511. At:=inherited At(Index);
  1512. end;
  1513. procedure TBreakpointCollection.Update;
  1514. begin
  1515. if assigned(Debugger) then
  1516. begin
  1517. Debugger^.RemoveBreakpoints;
  1518. Debugger^.InsertBreakpoints;
  1519. end;
  1520. if assigned(BreakpointsWindow) then
  1521. BreakpointsWindow^.Update;
  1522. end;
  1523. function TBreakpointCollection.GetGDB(index : longint) : PBreakpoint;
  1524. function IsNum(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1525. begin
  1526. IsNum:=P^.GDBIndex=index;
  1527. end;
  1528. begin
  1529. if index=0 then
  1530. GetGDB:=nil
  1531. else
  1532. GetGDB:=FirstThat(@IsNum);
  1533. end;
  1534. procedure TBreakpointCollection.ShowBreakpoints(W : PFPWindow);
  1535. procedure SetInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1536. begin
  1537. If assigned(P^.FileName) and
  1538. (OSFileName(P^.FileName^)=OSFileName(FExpand(PSourceWindow(W)^.Editor^.FileName))) then
  1539. PSourceWindow(W)^.Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,P^.state=bs_enabled);
  1540. end;
  1541. procedure SetInDisassembly(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1542. var
  1543. PDL : PDisasLine;
  1544. S : string;
  1545. ps,qs,i : longint;
  1546. begin
  1547. for i:=0 to PDisassemblyWindow(W)^.Editor^.GetLineCount-1 do
  1548. begin
  1549. PDL:=PDisasLine(PDisassemblyWindow(W)^.Editor^.GetLine(i));
  1550. if PDL^.Address=0 then
  1551. begin
  1552. if (P^.typ=bt_file_line) then
  1553. begin
  1554. S:=PDisassemblyWindow(W)^.Editor^.GetDisplayText(i);
  1555. ps:=pos(':',S);
  1556. qs:=pos(' ',copy(S,ps+1,High(S)));
  1557. if (GDBFileName(P^.FileName^)=GDBFileName(FExpand(Copy(S,1,ps-1)))) and
  1558. (StrToInt(copy(S,ps+1,qs-1))=P^.line) then
  1559. PDisassemblyWindow(W)^.Editor^.SetLineFlagState(i,lfBreakpoint,P^.state=bs_enabled);
  1560. end;
  1561. end
  1562. else
  1563. begin
  1564. If (P^.typ=bt_address) and (PDL^.Address=HexToCard(P^.Name^)) then
  1565. PDisassemblyWindow(W)^.Editor^.SetLineFlagState(i,lfBreakpoint,P^.state=bs_enabled);
  1566. end;
  1567. end;
  1568. end;
  1569. begin
  1570. if W=PFPWindow(DisassemblyWindow) then
  1571. ForEach(@SetInDisassembly)
  1572. else
  1573. ForEach(@SetInSource);
  1574. end;
  1575. procedure TBreakpointCollection.AdaptBreakpoints(Editor : PSourceEditor; Pos, Change : longint);
  1576. procedure AdaptInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1577. begin
  1578. If assigned(P^.FileName) and
  1579. (P^.FileName^=OSFileName(FExpand(Editor^.FileName))) then
  1580. begin
  1581. if P^.state=bs_enabled then
  1582. Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,false);
  1583. if P^.Line-1>=Pos then
  1584. begin
  1585. if (Change>0) or (P^.Line-1>=Pos-Change) then
  1586. P^.line:=P^.Line+Change
  1587. else
  1588. begin
  1589. { removing inside a ForEach call leads to problems }
  1590. { so we do that after PM }
  1591. P^.state:=bs_delete_after;
  1592. end;
  1593. end;
  1594. if P^.state=bs_enabled then
  1595. Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,true);
  1596. end;
  1597. end;
  1598. var
  1599. I : longint;
  1600. begin
  1601. ForEach(@AdaptInSource);
  1602. I:=Count-1;
  1603. While (I>=0) do
  1604. begin
  1605. if At(I)^.state=bs_delete_after then
  1606. AtFree(I);
  1607. Dec(I);
  1608. end;
  1609. end;
  1610. function TBreakpointCollection.FindBreakpointAt(Editor : PSourceEditor; Line : longint) : PBreakpoint;
  1611. function IsAtLine(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1612. begin
  1613. If assigned(P^.FileName) and
  1614. (P^.FileName^=OSFileName(FExpand(Editor^.FileName))) and
  1615. (Line=P^.Line) then
  1616. IsAtLine:=true
  1617. else
  1618. IsAtLine:=false;
  1619. end;
  1620. begin
  1621. FindBreakpointAt:=FirstThat(@IsAtLine);
  1622. end;
  1623. procedure TBreakpointCollection.ShowAllBreakpoints;
  1624. procedure SetInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1625. var
  1626. W : PSourceWindow;
  1627. begin
  1628. If assigned(P^.FileName) then
  1629. begin
  1630. W:=SearchOnDesktop(P^.FileName^,false);
  1631. if assigned(W) then
  1632. W^.Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,P^.state=bs_enabled);
  1633. end;
  1634. end;
  1635. begin
  1636. ForEach(@SetInSource);
  1637. end;
  1638. function TBreakpointCollection.GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  1639. function IsThis(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1640. begin
  1641. IsThis:=(P^.typ=typ) and (GetStr(P^.Name)=S);
  1642. end;
  1643. begin
  1644. GetType:=FirstThat(@IsThis);
  1645. end;
  1646. function TBreakpointCollection.ToggleFileLine(FileName: String;LineNr : Longint) : boolean;
  1647. function IsThere(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1648. begin
  1649. IsThere:=(P^.typ=bt_file_line) and assigned(P^.FileName) and
  1650. (OSFileName(P^.FileName^)=FileName) and (P^.Line=LineNr);
  1651. end;
  1652. var
  1653. PB : PBreakpoint;
  1654. begin
  1655. ToggleFileLine:=false;
  1656. FileName:=OSFileName(FExpand(FileName));
  1657. PB:=FirstThat(@IsThere);
  1658. If Assigned(PB) then
  1659. begin
  1660. { delete it form source window }
  1661. PB^.state:=bs_disabled;
  1662. PB^.UpdateSource;
  1663. { remove from collection }
  1664. BreakpointsCollection^.free(PB);
  1665. end
  1666. else
  1667. begin
  1668. PB:= New(PBreakpoint,Init_file_line(FileName,LineNr));
  1669. if assigned(PB) then
  1670. Begin
  1671. Insert(PB);
  1672. PB^.UpdateSource;
  1673. ToggleFileLine:=true;
  1674. End;
  1675. end;
  1676. Update;
  1677. end;
  1678. {****************************************************************************
  1679. TBreakpointItem
  1680. ****************************************************************************}
  1681. constructor TBreakpointItem.Init(ABreakpoint : PBreakpoint);
  1682. begin
  1683. inherited Init;
  1684. Breakpoint:=ABreakpoint;
  1685. end;
  1686. function TBreakpointItem.GetText(MaxLen: Sw_integer): string;
  1687. var S: string;
  1688. begin
  1689. with Breakpoint^ do
  1690. begin
  1691. S:=BreakpointTypeStr[typ];
  1692. While Length(S)<10 do
  1693. S:=S+' ';
  1694. S:=S+'|';
  1695. S:=S+BreakpointStateStr[state]+' ';
  1696. While Length(S)<20 do
  1697. S:=S+' ';
  1698. S:=S+'|';
  1699. if (typ=bt_file_line) then
  1700. S:=S+NameAndExtOf(GetStr(FileName))+':'+IntToStr(Line)
  1701. else
  1702. S:=S+GetStr(name);
  1703. While Length(S)<40 do
  1704. S:=S+' ';
  1705. S:=S+'|';
  1706. if IgnoreCount>0 then
  1707. S:=S+IntToStr(IgnoreCount);
  1708. While Length(S)<49 do
  1709. S:=S+' ';
  1710. S:=S+'|';
  1711. if assigned(Conditions) then
  1712. S:=S+' '+GetStr(Conditions);
  1713. if length(S)>MaxLen then S:=copy(S,1,MaxLen-2)+'..';
  1714. GetText:=S;
  1715. end;
  1716. end;
  1717. procedure TBreakpointItem.Selected;
  1718. begin
  1719. end;
  1720. function TBreakpointItem.GetModuleName: string;
  1721. begin
  1722. if breakpoint^.typ=bt_file_line then
  1723. GetModuleName:=GetStr(breakpoint^.FileName)
  1724. else
  1725. GetModuleName:='';
  1726. end;
  1727. {****************************************************************************
  1728. TBreakpointsListBox
  1729. ****************************************************************************}
  1730. constructor TBreakpointsListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  1731. begin
  1732. inherited Init(Bounds,1,AHScrollBar, AVScrollBar);
  1733. GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  1734. NoSelection:=true;
  1735. end;
  1736. function TBreakpointsListBox.GetLocalMenu: PMenu;
  1737. var M: PMenu;
  1738. begin
  1739. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  1740. M:=NewMenu(
  1741. NewItem(menu_bplocal_gotosource,'',kbNoKey,cmMsgGotoSource,hcMsgGotoSource,
  1742. NewItem(menu_bplocal_editbreakpoint,'',kbNoKey,cmEditBreakpoint,hcEditBreakpoint,
  1743. NewItem(menu_bplocal_newbreakpoint,'',kbNoKey,cmNewBreakpoint,hcNewBreakpoint,
  1744. NewItem(menu_bplocal_deletebreakpoint,'',kbNoKey,cmDeleteBreakpoint,hcDeleteBreakpoint,
  1745. NewItem(menu_bplocal_togglestate,'',kbNoKey,cmToggleBreakpoint,hcToggleBreakpoint,
  1746. nil))))));
  1747. GetLocalMenu:=M;
  1748. end;
  1749. procedure TBreakpointsListBox.HandleEvent(var Event: TEvent);
  1750. var DontClear: boolean;
  1751. begin
  1752. case Event.What of
  1753. evKeyDown :
  1754. begin
  1755. DontClear:=false;
  1756. case Event.KeyCode of
  1757. kbEnter :
  1758. Message(@Self,evCommand,cmMsgGotoSource,nil);
  1759. kbIns :
  1760. Message(@Self,evCommand,cmNewBreakpoint,nil);
  1761. kbDel :
  1762. Message(@Self,evCommand,cmDeleteBreakpoint,nil);
  1763. else
  1764. DontClear:=true;
  1765. end;
  1766. if not DontClear then
  1767. ClearEvent(Event);
  1768. end;
  1769. evBroadcast :
  1770. case Event.Command of
  1771. cmListItemSelected :
  1772. if Event.InfoPtr=@Self then
  1773. Message(@Self,evCommand,cmEditBreakpoint,nil);
  1774. end;
  1775. evCommand :
  1776. begin
  1777. DontClear:=false;
  1778. case Event.Command of
  1779. cmMsgTrackSource :
  1780. if Range>0 then
  1781. TrackSource;
  1782. cmEditBreakpoint :
  1783. EditCurrent;
  1784. cmToggleBreakpoint :
  1785. ToggleCurrent;
  1786. cmDeleteBreakpoint :
  1787. DeleteCurrent;
  1788. cmNewBreakpoint :
  1789. EditNew;
  1790. cmMsgClear :
  1791. Clear;
  1792. else
  1793. DontClear:=true;
  1794. end;
  1795. if not DontClear then
  1796. ClearEvent(Event);
  1797. end;
  1798. end;
  1799. inherited HandleEvent(Event);
  1800. end;
  1801. procedure TBreakpointsListBox.AddBreakpoint(P: PBreakpointItem);
  1802. var W : integer;
  1803. begin
  1804. if List=nil then New(List, Init(20,20));
  1805. W:=length(P^.GetText(255));
  1806. if W>MaxWidth then
  1807. begin
  1808. MaxWidth:=W;
  1809. if HScrollBar<>nil then
  1810. HScrollBar^.SetRange(0,MaxWidth);
  1811. end;
  1812. List^.Insert(P);
  1813. SetRange(List^.Count);
  1814. if Focused=List^.Count-1-1 then
  1815. FocusItem(List^.Count-1);
  1816. P^.Breakpoint^.UpdateSource;
  1817. DrawView;
  1818. end;
  1819. function TBreakpointsListBox.GetText(Item,MaxLen: Sw_Integer): String;
  1820. var P: PBreakpointItem;
  1821. S: string;
  1822. begin
  1823. P:=List^.At(Item);
  1824. S:=P^.GetText(MaxLen);
  1825. GetText:=copy(S,1,MaxLen);
  1826. end;
  1827. procedure TBreakpointsListBox.Clear;
  1828. begin
  1829. if assigned(List) then
  1830. Dispose(List, Done);
  1831. List:=nil;
  1832. MaxWidth:=0;
  1833. SetRange(0); DrawView;
  1834. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1835. end;
  1836. procedure TBreakpointsListBox.TrackSource;
  1837. var W: PSourceWindow;
  1838. P: PBreakpointItem;
  1839. R: TRect;
  1840. begin
  1841. (*Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1842. if Range=0 then Exit;*)
  1843. P:=List^.At(Focused);
  1844. if P^.GetModuleName='' then Exit;
  1845. Desktop^.Lock;
  1846. GetNextEditorBounds(R);
  1847. R.B.Y:=Owner^.Origin.Y;
  1848. W:=EditorWindowFile(P^.GetModuleName);
  1849. if assigned(W) then
  1850. begin
  1851. W^.GetExtent(R);
  1852. R.B.Y:=Owner^.Origin.Y;
  1853. W^.ChangeBounds(R);
  1854. W^.Editor^.SetCurPtr(1,P^.Breakpoint^.Line);
  1855. end
  1856. else
  1857. W:=TryToOpenFile(@R,P^.GetModuleName,1,P^.Breakpoint^.Line,true);
  1858. if W<>nil then
  1859. begin
  1860. W^.Select;
  1861. W^.Editor^.TrackCursor(true);
  1862. W^.Editor^.SetLineFlagExclusive(lfHighlightRow,P^.Breakpoint^.Line);
  1863. end;
  1864. if Assigned(Owner) then
  1865. Owner^.Select;
  1866. Desktop^.UnLock;
  1867. end;
  1868. procedure TBreakpointsListBox.ToggleCurrent;
  1869. var
  1870. P: PBreakpointItem;
  1871. begin
  1872. if Range=0 then Exit;
  1873. P:=List^.At(Focused);
  1874. if P=nil then Exit;
  1875. if P^.Breakpoint^.state=bs_enabled then
  1876. P^.Breakpoint^.state:=bs_disabled
  1877. else if P^.Breakpoint^.state=bs_disabled then
  1878. P^.Breakpoint^.state:=bs_enabled;
  1879. P^.Breakpoint^.UpdateSource;
  1880. BreakpointsCollection^.Update;
  1881. end;
  1882. procedure TBreakpointsListBox.EditCurrent;
  1883. var
  1884. P: PBreakpointItem;
  1885. begin
  1886. if Range=0 then Exit;
  1887. P:=List^.At(Focused);
  1888. if P=nil then Exit;
  1889. Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P^.Breakpoint)),nil);
  1890. P^.Breakpoint^.UpdateSource;
  1891. BreakpointsCollection^.Update;
  1892. end;
  1893. procedure TBreakpointsListBox.DeleteCurrent;
  1894. var
  1895. P: PBreakpointItem;
  1896. begin
  1897. if Range=0 then Exit;
  1898. P:=List^.At(Focused);
  1899. if P=nil then Exit;
  1900. { delete it form source window }
  1901. P^.Breakpoint^.state:=bs_disabled;
  1902. P^.Breakpoint^.UpdateSource;
  1903. BreakpointsCollection^.free(P^.Breakpoint);
  1904. List^.free(P);
  1905. BreakpointsCollection^.Update;
  1906. end;
  1907. procedure TBreakpointsListBox.EditNew;
  1908. var
  1909. P: PBreakpoint;
  1910. begin
  1911. P:=New(PBreakpoint,Init_Empty);
  1912. if Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P)),nil)<>cmCancel then
  1913. begin
  1914. P^.UpdateSource;
  1915. BreakpointsCollection^.Insert(P);
  1916. BreakpointsCollection^.Update;
  1917. end
  1918. else
  1919. dispose(P,Done);
  1920. end;
  1921. procedure TBreakpointsListBox.Draw;
  1922. var
  1923. I, J, Item: Sw_Integer;
  1924. NormalColor, SelectedColor, FocusedColor, Color: Word;
  1925. ColWidth, CurCol, Indent: Integer;
  1926. B: TDrawBuffer;
  1927. Text: String;
  1928. SCOff: Byte;
  1929. TC: byte;
  1930. procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
  1931. begin
  1932. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  1933. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  1934. begin
  1935. NormalColor := GetColor(1);
  1936. FocusedColor := GetColor(3);
  1937. SelectedColor := GetColor(4);
  1938. end else
  1939. begin
  1940. NormalColor := GetColor(2);
  1941. SelectedColor := GetColor(4);
  1942. end;
  1943. if Transparent then
  1944. begin MT(NormalColor); MT(SelectedColor); end;
  1945. if NoSelection then
  1946. SelectedColor:=NormalColor;
  1947. if HScrollBar <> nil then Indent := HScrollBar^.Value
  1948. else Indent := 0;
  1949. ColWidth := Size.X div NumCols + 1;
  1950. for I := 0 to Size.Y - 1 do
  1951. begin
  1952. for J := 0 to NumCols-1 do
  1953. begin
  1954. Item := J*Size.Y + I + TopItem;
  1955. CurCol := J*ColWidth;
  1956. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  1957. (Focused = Item) and (Range > 0) then
  1958. begin
  1959. Color := FocusedColor;
  1960. SetCursor(CurCol+1,I);
  1961. SCOff := 0;
  1962. end
  1963. else if (Item < Range) and IsSelected(Item) then
  1964. begin
  1965. Color := SelectedColor;
  1966. SCOff := 2;
  1967. end
  1968. else
  1969. begin
  1970. Color := NormalColor;
  1971. SCOff := 4;
  1972. end;
  1973. MoveChar(B[CurCol], ' ', Color, ColWidth);
  1974. if Item < Range then
  1975. begin
  1976. Text := GetText(Item, ColWidth + Indent);
  1977. Text := Copy(Text,Indent,ColWidth);
  1978. MoveStr(B[CurCol+1], Text, Color);
  1979. if ShowMarkers then
  1980. begin
  1981. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  1982. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  1983. end;
  1984. end;
  1985. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  1986. end;
  1987. WriteLine(0, I, Size.X, 1, B);
  1988. end;
  1989. end;
  1990. constructor TBreakpointsListBox.Load(var S: TStream);
  1991. begin
  1992. inherited Load(S);
  1993. end;
  1994. procedure TBreakpointsListBox.Store(var S: TStream);
  1995. var OL: PCollection;
  1996. OldR : integer;
  1997. begin
  1998. OL:=List;
  1999. OldR:=Range;
  2000. Range:=0;
  2001. New(List, Init(1,1));
  2002. inherited Store(S);
  2003. Dispose(List, Done);
  2004. Range:=OldR;
  2005. List:=OL;
  2006. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  2007. collection? Pasting here a modified version of TListBox.Store+
  2008. TAdvancedListBox.Store isn't a better solution, since by eventually
  2009. changing the obj-hierarchy you'll always have to modify this, too - BG }
  2010. end;
  2011. destructor TBreakpointsListBox.Done;
  2012. begin
  2013. inherited Done;
  2014. if List<>nil then Dispose(List, Done);
  2015. end;
  2016. {****************************************************************************
  2017. TBreakpointsWindow
  2018. ****************************************************************************}
  2019. constructor TBreakpointsWindow.Init;
  2020. var R,R2: TRect;
  2021. HSB,VSB: PScrollBar;
  2022. ST: PStaticText;
  2023. S: String;
  2024. X,X1 : Sw_integer;
  2025. Btn: PButton;
  2026. const
  2027. NumButtons = 5;
  2028. begin
  2029. Desktop^.GetExtent(R); R.A.Y:=R.B.Y-18;
  2030. inherited Init(R, dialog_breakpointlist, wnNoNumber);
  2031. HelpCtx:=hcBreakpointListWindow;
  2032. GetExtent(R); R.Grow(-1,-1); R.B.Y:=R.A.Y+1;
  2033. S:=label_breakpointpropheader;
  2034. New(ST, Init(R,S));
  2035. ST^.GrowMode:=gfGrowHiX;
  2036. Insert(ST);
  2037. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,1); R.B.Y:=R.A.Y+1;
  2038. New(ST, Init(R, CharStr('Ä', MaxViewWidth)));
  2039. ST^.GrowMode:=gfGrowHiX;
  2040. Insert(ST);
  2041. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,2);Dec(R.B.Y,5);
  2042. R2.Copy(R); Inc(R2.B.Y); R2.A.Y:=R2.B.Y-1;
  2043. New(HSB, Init(R2)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX; Insert(HSB);
  2044. HSB^.SetStep(R.B.X-R.A.X-2,1);
  2045. R2.Copy(R); Inc(R2.B.X); R2.A.X:=R2.B.X-1;
  2046. New(VSB, Init(R2)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
  2047. VSB^.SetStep(R.B.Y-R.A.Y-2,1);
  2048. New(BreakLB, Init(R,HSB,VSB));
  2049. BreakLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  2050. BreakLB^.Transparent:=true;
  2051. Insert(BreakLB);
  2052. GetExtent(R);R.Grow(-1,-1);
  2053. Dec(R.B.Y);
  2054. R.A.Y:=R.B.Y-2;
  2055. X:=(R.B.X-R.A.X) div NumButtons;
  2056. X1:=R.A.X+(X div 2);
  2057. R.A.X:=X1-3;R.B.X:=X1+7;
  2058. New(Btn, Init(R, button_Close, cmClose, bfDefault));
  2059. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2060. Insert(Btn);
  2061. X1:=X1+X;
  2062. R.A.X:=X1-3;R.B.X:=X1+7;
  2063. New(Btn, Init(R, button_New, cmNewBreakpoint, bfNormal));
  2064. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2065. Insert(Btn);
  2066. X1:=X1+X;
  2067. R.A.X:=X1-3;R.B.X:=X1+7;
  2068. New(Btn, Init(R, button_Edit, cmEditBreakpoint, bfNormal));
  2069. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2070. Insert(Btn);
  2071. X1:=X1+X;
  2072. R.A.X:=X1-3;R.B.X:=X1+7;
  2073. New(Btn, Init(R, button_ToggleButton, cmToggleBreakInList, bfNormal));
  2074. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2075. Insert(Btn);
  2076. X1:=X1+X;
  2077. R.A.X:=X1-3;R.B.X:=X1+7;
  2078. New(Btn, Init(R, button_Delete, cmDeleteBreakpoint, bfNormal));
  2079. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2080. Insert(Btn);
  2081. BreakLB^.Select;
  2082. Update;
  2083. BreakpointsWindow:=@self;
  2084. end;
  2085. constructor TBreakpointsWindow.Load(var S: TStream);
  2086. begin
  2087. inherited Load(S);
  2088. GetSubViewPtr(S,BreakLB);
  2089. end;
  2090. procedure TBreakpointsWindow.Store(var S: TStream);
  2091. begin
  2092. inherited Store(S);
  2093. PutSubViewPtr(S,BreakLB);
  2094. end;
  2095. procedure TBreakpointsWindow.AddBreakpoint(ABreakpoint : PBreakpoint);
  2096. begin
  2097. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(ABreakpoint)));
  2098. end;
  2099. procedure TBreakpointsWindow.ClearBreakpoints;
  2100. begin
  2101. BreakLB^.Clear;
  2102. ReDraw;
  2103. end;
  2104. procedure TBreakpointsWindow.ReloadBreakpoints;
  2105. procedure InsertInBreakLB(P : PBreakpoint);
  2106. begin
  2107. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(P)));
  2108. end;
  2109. begin
  2110. If not assigned(BreakpointsCollection) then
  2111. exit;
  2112. BreakpointsCollection^.ForEach(@InsertInBreakLB);
  2113. ReDraw;
  2114. end;
  2115. procedure TBreakpointsWindow.SizeLimits(var Min, Max: TPoint);
  2116. begin
  2117. inherited SizeLimits(Min,Max);
  2118. Min.X:=40; Min.Y:=18;
  2119. end;
  2120. procedure TBreakpointsWindow.Close;
  2121. begin
  2122. Hide;
  2123. end;
  2124. procedure TBreakpointsWindow.HandleEvent(var Event: TEvent);
  2125. var DontClear : boolean;
  2126. begin
  2127. case Event.What of
  2128. evKeyDown :
  2129. begin
  2130. if (Event.KeyCode=kbEnter) or (Event.KeyCode=kbEsc) then
  2131. begin
  2132. ClearEvent(Event);
  2133. Hide;
  2134. end;
  2135. end;
  2136. evCommand :
  2137. begin
  2138. DontClear:=False;
  2139. case Event.Command of
  2140. cmNewBreakpoint :
  2141. BreakLB^.EditNew;
  2142. cmEditBreakpoint :
  2143. BreakLB^.EditCurrent;
  2144. cmDeleteBreakpoint :
  2145. BreakLB^.DeleteCurrent;
  2146. cmToggleBreakInList :
  2147. BreakLB^.ToggleCurrent;
  2148. cmClose :
  2149. Hide;
  2150. else
  2151. DontClear:=true;
  2152. end;
  2153. if not DontClear then
  2154. ClearEvent(Event);
  2155. end;
  2156. evBroadcast :
  2157. case Event.Command of
  2158. cmUpdate :
  2159. Update;
  2160. end;
  2161. end;
  2162. inherited HandleEvent(Event);
  2163. end;
  2164. procedure TBreakpointsWindow.Update;
  2165. var
  2166. StoreFocus : longint;
  2167. begin
  2168. StoreFocus:=BreakLB^.Focused;
  2169. ClearBreakpoints;
  2170. ReloadBreakpoints;
  2171. If StoreFocus<BreakLB^.Range then
  2172. BreakLB^.FocusItem(StoreFocus);
  2173. end;
  2174. destructor TBreakpointsWindow.Done;
  2175. begin
  2176. inherited Done;
  2177. BreakpointsWindow:=nil;
  2178. end;
  2179. {****************************************************************************
  2180. TBreakpointItemDialog
  2181. ****************************************************************************}
  2182. constructor TBreakpointItemDialog.Init(ABreakpoint: PBreakpoint);
  2183. var R,R2,R3: TRect;
  2184. Items: PSItem;
  2185. I : BreakpointType;
  2186. KeyCount: sw_integer;
  2187. begin
  2188. KeyCount:=longint(high(BreakpointType));
  2189. R.Assign(0,0,60,Max(9+KeyCount,18));
  2190. inherited Init(R,dialog_modifynewbreakpoint);
  2191. Breakpoint:=ABreakpoint;
  2192. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  2193. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.B.X-3;
  2194. New(NameIL, Init(R, 255)); Insert(NameIL);
  2195. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  2196. Insert(New(PHistory, Init(R2, NameIL, hidWatchDialog)));
  2197. R.Copy(R3); Inc(R.A.Y); R.B.Y:=R.A.Y+1;
  2198. R2.Copy(R); R2.Move(-1,-1);
  2199. Insert(New(PLabel, Init(R2, label_breakpoint_name, NameIL)));
  2200. R.Move(0,3);
  2201. New(ConditionsIL, Init(R, 255)); Insert(ConditionsIL);
  2202. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_conditions, ConditionsIL)));
  2203. R.Move(0,3); R.B.X:=R.A.X+36;
  2204. New(LineIL, Init(R, 128)); Insert(LineIL);
  2205. LineIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  2206. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_line, LineIL)));
  2207. R.Move(0,3);
  2208. New(IgnoreIL, Init(R, 128)); Insert(IgnoreIL);
  2209. IgnoreIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  2210. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_ignorecount, IgnoreIL)));
  2211. R.Copy(R3); Inc(R.A.X,38); Inc(R.A.Y,7); R.B.Y:=R.A.Y+KeyCount;
  2212. Items:=nil;
  2213. { don't use invalid type }
  2214. for I:=pred(high(BreakpointType)) downto low(BreakpointType) do
  2215. Items:=NewSItem(BreakpointTypeStr[I], Items);
  2216. New(TypeRB, Init(R, Items));
  2217. R2.Copy(R); R2.Move(-1,-1); R2.B.Y:=R2.A.Y+1;
  2218. Insert(New(PLabel, Init(R2, label_breakpoint_type, TypeRB)));
  2219. Insert(TypeRB);
  2220. InsertButtons(@Self);
  2221. NameIL^.Select;
  2222. end;
  2223. function TBreakpointItemDialog.Execute: Word;
  2224. var R: word;
  2225. S1: string;
  2226. err: word;
  2227. L: longint;
  2228. begin
  2229. R:=longint(Breakpoint^.typ);
  2230. TypeRB^.SetData(R);
  2231. If Breakpoint^.typ=bt_file_line then
  2232. S1:=GetStr(Breakpoint^.FileName)
  2233. else
  2234. S1:=GetStr(Breakpoint^.name);
  2235. NameIL^.SetData(S1);
  2236. If Breakpoint^.typ=bt_file_line then
  2237. S1:=IntToStr(Breakpoint^.Line)
  2238. else
  2239. S1:='0';
  2240. LineIL^.SetData(S1);
  2241. S1:=IntToStr(Breakpoint^.IgnoreCount);
  2242. IgnoreIL^.SetData(S1);
  2243. S1:=GetStr(Breakpoint^.Conditions);
  2244. ConditionsIL^.SetData(S1);
  2245. if assigned(FirstEditorWindow) then
  2246. FindReplaceEditor:=FirstEditorWindow^.Editor;
  2247. R:=inherited Execute;
  2248. FindReplaceEditor:=nil;
  2249. if R=cmOK then
  2250. begin
  2251. TypeRB^.GetData(R);
  2252. L:=R;
  2253. Breakpoint^.typ:=BreakpointType(L);
  2254. NameIL^.GetData(S1);
  2255. If Breakpoint^.typ=bt_file_line then
  2256. begin
  2257. If assigned(Breakpoint^.FileName) then
  2258. DisposeStr(Breakpoint^.FileName);
  2259. Breakpoint^.FileName:=NewStr(S1);
  2260. end
  2261. else
  2262. begin
  2263. If assigned(Breakpoint^.Name) then
  2264. DisposeStr(Breakpoint^.Name);
  2265. Breakpoint^.name:=NewStr(S1);
  2266. end;
  2267. If Breakpoint^.typ=bt_file_line then
  2268. begin
  2269. LineIL^.GetData(S1);
  2270. Val(S1,L,err);
  2271. Breakpoint^.Line:=L;
  2272. end;
  2273. IgnoreIL^.GetData(S1);
  2274. Val(S1,L,err);
  2275. Breakpoint^.IgnoreCount:=L;
  2276. ConditionsIL^.GetData(S1);
  2277. If assigned(Breakpoint^.Conditions) then
  2278. DisposeStr(Breakpoint^.Conditions);
  2279. Breakpoint^.Conditions:=NewStr(S1);
  2280. end;
  2281. Execute:=R;
  2282. end;
  2283. {****************************************************************************
  2284. TWatch
  2285. ****************************************************************************}
  2286. constructor TWatch.Init(s : string);
  2287. begin
  2288. expr:=NewStr(s);
  2289. last_value:=nil;
  2290. current_value:=nil;
  2291. Get_new_value;
  2292. GDBRunCount:=-1;
  2293. end;
  2294. constructor TWatch.Load(var S: TStream);
  2295. begin
  2296. expr:=S.ReadStr;
  2297. last_value:=nil;
  2298. current_value:=nil;
  2299. Get_new_value;
  2300. GDBRunCount:=-1;
  2301. end;
  2302. procedure TWatch.Store(var S: TStream);
  2303. begin
  2304. S.WriteStr(expr);
  2305. end;
  2306. procedure TWatch.rename(s : string);
  2307. begin
  2308. if assigned(expr) then
  2309. begin
  2310. if GetStr(expr)=S then
  2311. exit;
  2312. DisposeStr(expr);
  2313. end;
  2314. expr:=NewStr(s);
  2315. if assigned(last_value) then
  2316. StrDispose(last_value);
  2317. last_value:=nil;
  2318. if assigned(current_value) then
  2319. StrDispose(current_value);
  2320. current_value:=nil;
  2321. GDBRunCount:=-1;
  2322. Get_new_value;
  2323. end;
  2324. procedure TWatch.Get_new_value;
  2325. var p, q : pchar;
  2326. i, j, curframe, startframe : longint;
  2327. s,s2 : string;
  2328. loop_higher, found : boolean;
  2329. last_removed : char;
  2330. function GetValue(var s : string) : boolean;
  2331. begin
  2332. Debugger^.command('p '+s);
  2333. if not Debugger^.Error then
  2334. begin
  2335. s:=StrPas(Debugger^.GetOutput);
  2336. GetValue:=true;
  2337. end
  2338. else
  2339. begin
  2340. s:=StrPas(Debugger^.GetError);
  2341. GetValue:=false;
  2342. { do not open a messagebox for such errors }
  2343. Debugger^.got_error:=false;
  2344. end;
  2345. end;
  2346. begin
  2347. If not assigned(Debugger) or Not Debugger^.HasExe or
  2348. (GDBRunCount=Debugger^.RunCount) then
  2349. exit;
  2350. GDBRunCount:=Debugger^.RunCount;
  2351. if assigned(last_value) then
  2352. strdispose(last_value);
  2353. last_value:=current_value;
  2354. s:=GetStr(expr);
  2355. found:=GetValue(s);
  2356. Debugger^.got_error:=false;
  2357. loop_higher:=not found;
  2358. if not found then
  2359. begin
  2360. curframe:=Debugger^.get_current_frame;
  2361. startframe:=curframe;
  2362. end
  2363. else
  2364. begin
  2365. curframe:=0;
  2366. startframe:=0;
  2367. end;
  2368. while loop_higher do
  2369. begin
  2370. s:='parent_ebp';
  2371. if GetValue(s) then
  2372. begin
  2373. repeat
  2374. inc(curframe);
  2375. if not Debugger^.set_current_frame(curframe) then
  2376. loop_higher:=false;
  2377. {$ifdef FrameNameKnown}
  2378. s2:='/x '+FrameName;
  2379. {$else not FrameNameKnown}
  2380. s2:='/x $ebp';
  2381. {$endif FrameNameKnown}
  2382. getValue(s2);
  2383. j:=pos('=',s2);
  2384. if j>0 then
  2385. s2:=copy(s2,j+1,length(s2));
  2386. while s2[1] in [' ',TAB] do
  2387. delete(s2,1,1);
  2388. if pos(s2,s)>0 then
  2389. loop_higher :=false;
  2390. until not loop_higher;
  2391. { try again at that level }
  2392. s:=GetStr(expr);
  2393. found:=GetValue(s);
  2394. loop_higher:=not found;
  2395. end
  2396. else
  2397. loop_higher:=false;
  2398. end;
  2399. if found then
  2400. p:=StrNew(Debugger^.GetOutput)
  2401. else
  2402. begin
  2403. { get a reasonable output at least }
  2404. s:=GetStr(expr);
  2405. GetValue(s);
  2406. p:=StrNew(Debugger^.GetError);
  2407. end;
  2408. Debugger^.got_error:=false;
  2409. { We should try here to find the expr in parent
  2410. procedure if there are
  2411. I will implement this as I added a
  2412. parent_ebp pseudo local var to local procedure
  2413. in stabs debug info PM }
  2414. { But there are some pitfalls like
  2415. locals redefined in other sublocals that call the function }
  2416. if curframe<>startframe then
  2417. Debugger^.set_current_frame(startframe);
  2418. q:=nil;
  2419. if assigned(p) and (p[0]='$') then
  2420. q:=StrPos(p,'=');
  2421. if not assigned(q) then
  2422. q:=p;
  2423. if assigned(q) then
  2424. i:=strlen(q)
  2425. else
  2426. i:=0;
  2427. if (i>0) and (q[i-1]=#10) then
  2428. begin
  2429. while (i>1) and ((q[i-2]=' ') or (q[i-2]=#9)) do
  2430. dec(i);
  2431. last_removed:=q[i-1];
  2432. q[i-1]:=#0;
  2433. end
  2434. else
  2435. last_removed:=#0;
  2436. if assigned(q) then
  2437. current_value:=strnew(q)
  2438. else
  2439. current_value:=strnew('');
  2440. if last_removed<>#0 then
  2441. q[i-1]:=last_removed;
  2442. strdispose(p);
  2443. GDBRunCount:=Debugger^.RunCount;
  2444. end;
  2445. procedure TWatch.Force_new_value;
  2446. begin
  2447. GDBRunCount:=-1;
  2448. Get_new_value;
  2449. end;
  2450. destructor TWatch.Done;
  2451. begin
  2452. if assigned(expr) then
  2453. disposestr(expr);
  2454. if assigned(last_value) then
  2455. strdispose(last_value);
  2456. if assigned(current_value) then
  2457. strdispose(current_value);
  2458. inherited done;
  2459. end;
  2460. {****************************************************************************
  2461. TWatchesCollection
  2462. ****************************************************************************}
  2463. constructor TWatchesCollection.Init;
  2464. begin
  2465. inherited Init(10,10);
  2466. end;
  2467. procedure TWatchesCollection.Insert(Item: Pointer);
  2468. begin
  2469. PWatch(Item)^.Get_new_value;
  2470. Inherited Insert(Item);
  2471. Update;
  2472. end;
  2473. procedure TWatchesCollection.Update;
  2474. var
  2475. W,W1 : integer;
  2476. procedure GetMax(P : PWatch);
  2477. begin
  2478. if assigned(P^.Current_value) then
  2479. W1:=StrLen(P^.Current_value)+3+Length(GetStr(P^.expr))
  2480. else
  2481. W1:=2+Length(GetStr(P^.expr));
  2482. if W1>W then
  2483. W:=W1;
  2484. end;
  2485. begin
  2486. W:=0;
  2487. ForEach(@GetMax);
  2488. MaxW:=W;
  2489. If assigned(WatchesWindow) then
  2490. WatchesWindow^.WLB^.Update(MaxW);
  2491. end;
  2492. function TWatchesCollection.At(Index: Integer): PWatch;
  2493. begin
  2494. At:=Inherited At(Index);
  2495. end;
  2496. {****************************************************************************
  2497. TWatchesListBox
  2498. ****************************************************************************}
  2499. constructor TWatchesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  2500. begin
  2501. inherited Init(Bounds,1,AHScrollBar,AVScrollBar);
  2502. If assigned(List) then
  2503. dispose(list,done);
  2504. List:=WatchesCollection;
  2505. end;
  2506. procedure TWatchesListBox.Update(AMaxWidth : integer);
  2507. var R : TRect;
  2508. begin
  2509. GetExtent(R);
  2510. MaxWidth:=AMaxWidth;
  2511. if (HScrollBar<>nil) and (R.B.X-R.A.X<MaxWidth) then
  2512. HScrollBar^.SetRange(0,MaxWidth-(R.B.X-R.A.X))
  2513. else
  2514. HScrollBar^.SetRange(0,0);
  2515. if R.B.X-R.A.X>MaxWidth then
  2516. HScrollBar^.Hide
  2517. else
  2518. HScrollBar^.Show;
  2519. SetRange(List^.Count+1);
  2520. if R.B.Y-R.A.Y>Range then
  2521. VScrollBar^.Hide
  2522. else
  2523. VScrollBar^.Show;
  2524. {if Focused=List^.Count-1-1 then
  2525. FocusItem(List^.Count-1);
  2526. What was that for ?? PM }
  2527. DrawView;
  2528. end;
  2529. function TWatchesListBox.GetIndentedText(Item,Indent,MaxLen: Sw_Integer;var Modified : boolean): String;
  2530. var
  2531. PW : PWatch;
  2532. ValOffset : Sw_integer;
  2533. S : String;
  2534. begin
  2535. Modified:=false;
  2536. if Item>=WatchesCollection^.Count then
  2537. begin
  2538. GetIndentedText:='';
  2539. exit;
  2540. end;
  2541. PW:=WatchesCollection^.At(Item);
  2542. ValOffset:=Length(GetStr(PW^.Expr))+2;
  2543. if not assigned(PW^.expr) then
  2544. GetIndentedText:=''
  2545. else if Indent<ValOffset then
  2546. begin
  2547. S:=GetStr(PW^.Expr);
  2548. if Indent=0 then
  2549. S:=' '+S
  2550. else
  2551. S:=Copy(S,Indent,High(S));
  2552. if not assigned(PW^.current_value) then
  2553. S:=S+' <Unknown value>'
  2554. else
  2555. S:=S+' '+GetPChar(PW^.Current_value);
  2556. GetIndentedText:=Copy(S,1,MaxLen);
  2557. end
  2558. else
  2559. begin
  2560. if not assigned(PW^.Current_value) or
  2561. (StrLen(PW^.Current_value)<Indent-Valoffset) then
  2562. S:=''
  2563. else
  2564. S:=GetPchar(@(PW^.Current_Value[Indent-Valoffset]));
  2565. GetIndentedText:=Copy(S,1,MaxLen);
  2566. end;
  2567. if assigned(PW^.current_value) and
  2568. assigned(PW^.last_value) and
  2569. (strcomp(PW^.Last_value,PW^.Current_value)<>0) then
  2570. Modified:=true;
  2571. end;
  2572. procedure TWatchesListBox.EditCurrent;
  2573. var
  2574. P: PWatch;
  2575. begin
  2576. if Range=0 then Exit;
  2577. if Focused<WatchesCollection^.Count then
  2578. P:=WatchesCollection^.At(Focused)
  2579. else
  2580. P:=New(PWatch,Init(''));
  2581. Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil);
  2582. WatchesCollection^.Update;
  2583. end;
  2584. function TWatchesListBox.GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String;
  2585. var
  2586. Dummy_Modified : boolean;
  2587. begin
  2588. GetText:=GetIndentedText(Item, 0, MaxLen, Dummy_Modified);
  2589. end;
  2590. procedure TWatchesListBox.DeleteCurrent;
  2591. var
  2592. P: PWatch;
  2593. begin
  2594. if (Range=0) or
  2595. (Focused>=WatchesCollection^.Count) then
  2596. exit;
  2597. P:=WatchesCollection^.At(Focused);
  2598. WatchesCollection^.free(P);
  2599. WatchesCollection^.Update;
  2600. end;
  2601. procedure TWatchesListBox.EditNew;
  2602. var
  2603. P: PWatch;
  2604. S : string;
  2605. begin
  2606. if Focused<WatchesCollection^.Count then
  2607. begin
  2608. P:=WatchesCollection^.At(Focused);
  2609. S:=GetStr(P^.expr);
  2610. end
  2611. else
  2612. S:='';
  2613. P:=New(PWatch,Init(S));
  2614. if Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil)<>cmCancel then
  2615. begin
  2616. WatchesCollection^.AtInsert(Focused,P);
  2617. WatchesCollection^.Update;
  2618. end
  2619. else
  2620. dispose(P,Done);
  2621. end;
  2622. procedure TWatchesListBox.Draw;
  2623. var
  2624. I, J, Item: Sw_Integer;
  2625. NormalColor, SelectedColor, FocusedColor, Color: Word;
  2626. ColWidth, CurCol, Indent: Integer;
  2627. B: TDrawBuffer;
  2628. Modified : boolean;
  2629. Text: String;
  2630. SCOff: Byte;
  2631. TC: byte;
  2632. procedure MT(var C: word);
  2633. begin
  2634. if TC<>0 then C:=(C and $ff0f) or (TC and $f0);
  2635. end;
  2636. begin
  2637. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  2638. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  2639. begin
  2640. NormalColor := GetColor(1);
  2641. FocusedColor := GetColor(3);
  2642. SelectedColor := GetColor(4);
  2643. end else
  2644. begin
  2645. NormalColor := GetColor(2);
  2646. SelectedColor := GetColor(4);
  2647. end;
  2648. if Transparent then
  2649. begin MT(NormalColor); MT(SelectedColor); end;
  2650. (* if NoSelection then
  2651. SelectedColor:=NormalColor;*)
  2652. if HScrollBar <> nil then Indent := HScrollBar^.Value
  2653. else Indent := 0;
  2654. ColWidth := Size.X div NumCols + 1;
  2655. for I := 0 to Size.Y - 1 do
  2656. begin
  2657. for J := 0 to NumCols-1 do
  2658. begin
  2659. Item := J*Size.Y + I + TopItem;
  2660. CurCol := J*ColWidth;
  2661. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  2662. (Focused = Item) and (Range > 0) then
  2663. begin
  2664. Color := FocusedColor;
  2665. SetCursor(CurCol+1,I);
  2666. SCOff := 0;
  2667. end
  2668. else if (Item < Range) and IsSelected(Item) then
  2669. begin
  2670. Color := SelectedColor;
  2671. SCOff := 2;
  2672. end
  2673. else
  2674. begin
  2675. Color := NormalColor;
  2676. SCOff := 4;
  2677. end;
  2678. MoveChar(B[CurCol], ' ', Color, ColWidth);
  2679. if Item < Range then
  2680. begin
  2681. (* Text := GetText(Item, ColWidth + Indent);
  2682. Text := Copy(Text,Indent,ColWidth); *)
  2683. Text:=GetIndentedText(Item,Indent,ColWidth,Modified);
  2684. if modified then
  2685. begin
  2686. SCOff:=0;
  2687. Color:=(Color and $fff0) or Red;
  2688. end;
  2689. MoveStr(B[CurCol], Text, Color);
  2690. if {ShowMarkers or } Modified then
  2691. begin
  2692. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  2693. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  2694. WordRec(B[CurCol+ColWidth-2]).Hi := Color and $ff;
  2695. end;
  2696. end;
  2697. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  2698. end;
  2699. WriteLine(0, I, Size.X, 1, B);
  2700. end;
  2701. end;
  2702. function TWatchesListBox.GetLocalMenu: PMenu;
  2703. var M: PMenu;
  2704. begin
  2705. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  2706. M:=NewMenu(
  2707. NewItem(menu_watchlocal_edit,'',kbNoKey,cmEdit,hcNoContext,
  2708. NewItem(menu_watchlocal_new,'',kbNoKey,cmNew,hcNoContext,
  2709. NewItem(menu_watchlocal_delete,'',kbNoKey,cmDelete,hcNoContext,
  2710. NewLine(
  2711. NewItem(menu_msglocal_saveas,'',kbNoKey,cmSaveAs,hcSaveAs,
  2712. nil))))));
  2713. GetLocalMenu:=M;
  2714. end;
  2715. procedure TWatchesListBox.HandleEvent(var Event: TEvent);
  2716. var DontClear: boolean;
  2717. begin
  2718. case Event.What of
  2719. evKeyDown :
  2720. begin
  2721. DontClear:=false;
  2722. case Event.KeyCode of
  2723. kbEnter :
  2724. Message(@Self,evCommand,cmEdit,nil);
  2725. kbIns :
  2726. Message(@Self,evCommand,cmNew,nil);
  2727. kbDel :
  2728. Message(@Self,evCommand,cmDelete,nil);
  2729. else
  2730. DontClear:=true;
  2731. end;
  2732. if not DontClear then
  2733. ClearEvent(Event);
  2734. end;
  2735. evBroadcast :
  2736. case Event.Command of
  2737. cmListItemSelected :
  2738. if Event.InfoPtr=@Self then
  2739. Message(@Self,evCommand,cmEdit,nil);
  2740. end;
  2741. evCommand :
  2742. begin
  2743. DontClear:=false;
  2744. case Event.Command of
  2745. cmEdit :
  2746. EditCurrent;
  2747. cmDelete :
  2748. DeleteCurrent;
  2749. cmNew :
  2750. EditNew;
  2751. else
  2752. DontClear:=true;
  2753. end;
  2754. if not DontClear then
  2755. ClearEvent(Event);
  2756. end;
  2757. end;
  2758. inherited HandleEvent(Event);
  2759. end;
  2760. constructor TWatchesListBox.Load(var S: TStream);
  2761. begin
  2762. inherited Load(S);
  2763. If assigned(List) then
  2764. dispose(list,done);
  2765. List:=WatchesCollection;
  2766. { we must set Range PM }
  2767. SetRange(List^.count+1);
  2768. end;
  2769. procedure TWatchesListBox.Store(var S: TStream);
  2770. var OL: PCollection;
  2771. OldRange : Sw_integer;
  2772. begin
  2773. OL:=List;
  2774. OldRange:=Range;
  2775. Range:=0;
  2776. New(List, Init(1,1));
  2777. inherited Store(S);
  2778. Dispose(List, Done);
  2779. List:=OL;
  2780. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  2781. collection? Pasting here a modified version of TListBox.Store+
  2782. TAdvancedListBox.Store isn't a better solution, since by eventually
  2783. changing the obj-hierarchy you'll always have to modify this, too - BG }
  2784. SetRange(OldRange);
  2785. end;
  2786. destructor TWatchesListBox.Done;
  2787. begin
  2788. List:=nil;
  2789. inherited Done;
  2790. end;
  2791. {****************************************************************************
  2792. TWatchesWindow
  2793. ****************************************************************************}
  2794. Constructor TWatchesWindow.Init;
  2795. var
  2796. HSB,VSB: PScrollBar;
  2797. R,R2 : trect;
  2798. begin
  2799. Desktop^.GetExtent(R);
  2800. R.A.Y:=R.B.Y-7;
  2801. inherited Init(R, dialog_watches,SearchFreeWindowNo);
  2802. Palette:=wpCyanWindow;
  2803. GetExtent(R);
  2804. HelpCtx:=hcWatchesWindow;
  2805. R.Grow(-1,-1);
  2806. R2.Copy(R);
  2807. Inc(R2.B.Y);
  2808. R2.A.Y:=R2.B.Y-1;
  2809. New(HSB, Init(R2));
  2810. HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX;
  2811. HSB^.SetStep(R.B.X-R.A.X,1);
  2812. Insert(HSB);
  2813. R2.Copy(R);
  2814. Inc(R2.B.X);
  2815. R2.A.X:=R2.B.X-1;
  2816. New(VSB, Init(R2));
  2817. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  2818. Insert(VSB);
  2819. New(WLB,Init(R,HSB,VSB));
  2820. WLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  2821. WLB^.Transparent:=true;
  2822. Insert(WLB);
  2823. If assigned(WatchesWindow) then
  2824. dispose(WatchesWindow,done);
  2825. WatchesWindow:=@Self;
  2826. Update;
  2827. end;
  2828. procedure TWatchesWindow.Update;
  2829. begin
  2830. WatchesCollection^.Update;
  2831. Draw;
  2832. end;
  2833. constructor TWatchesWindow.Load(var S: TStream);
  2834. begin
  2835. inherited Load(S);
  2836. GetSubViewPtr(S,WLB);
  2837. If assigned(WatchesWindow) then
  2838. dispose(WatchesWindow,done);
  2839. WatchesWindow:=@Self;
  2840. end;
  2841. procedure TWatchesWindow.Store(var S: TStream);
  2842. begin
  2843. inherited Store(S);
  2844. PutSubViewPtr(S,WLB);
  2845. end;
  2846. Destructor TWatchesWindow.Done;
  2847. begin
  2848. WatchesWindow:=nil;
  2849. Dispose(WLB,done);
  2850. inherited done;
  2851. end;
  2852. {****************************************************************************
  2853. TWatchItemDialog
  2854. ****************************************************************************}
  2855. constructor TWatchItemDialog.Init(AWatch: PWatch);
  2856. var R,R2: TRect;
  2857. begin
  2858. R.Assign(0,0,50,10);
  2859. inherited Init(R,'Edit Watch');
  2860. Watch:=AWatch;
  2861. GetExtent(R); R.Grow(-3,-2);
  2862. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
  2863. New(NameIL, Init(R, 255)); Insert(NameIL);
  2864. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  2865. Insert(New(PHistory, Init(R2, NameIL, hidWatchDialog)));
  2866. R2.Copy(R); R2.Move(-1,-1);
  2867. Insert(New(PLabel, Init(R2, label_watch_expressiontowatch, NameIL)));
  2868. GetExtent(R);
  2869. R.Grow(-3,-1);
  2870. R.A.Y:=R.A.Y+3;
  2871. TextST:=New(PAdvancedStaticText, Init(R, label_watch_values));
  2872. Insert(TextST);
  2873. InsertButtons(@Self);
  2874. NameIL^.Select;
  2875. end;
  2876. function TWatchItemDialog.Execute: Word;
  2877. var R: word;
  2878. S1,S2: string;
  2879. begin
  2880. S1:=GetStr(Watch^.expr);
  2881. NameIL^.SetData(S1);
  2882. S1:=GetPChar(Watch^.Current_value);
  2883. S2:=GetPChar(Watch^.Last_value);
  2884. ClearFormatParams;
  2885. AddFormatParamStr(S1);
  2886. AddFormatParamStr(S2);
  2887. if assigned(Watch^.Last_value) and
  2888. assigned(Watch^.Current_value) and
  2889. (strcomp(Watch^.Last_value,Watch^.Current_value)=0) then
  2890. S1:=FormatStrF(msg_watch_currentvalue,FormatParams)
  2891. else
  2892. S1:=FormatStrF(msg_watch_currentandpreviousvalue,FormatParams);
  2893. TextST^.SetText(S1);
  2894. if assigned(FirstEditorWindow) then
  2895. FindReplaceEditor:=FirstEditorWindow^.Editor;
  2896. R:=inherited Execute;
  2897. FindReplaceEditor:=nil;
  2898. if R=cmOK then
  2899. begin
  2900. NameIL^.GetData(S1);
  2901. Watch^.Rename(S1);
  2902. If assigned(Debugger) then
  2903. Debugger^.ReadWatches;
  2904. end;
  2905. Execute:=R;
  2906. end;
  2907. {****************************************************************************
  2908. TStackWindow
  2909. ****************************************************************************}
  2910. constructor TFramesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  2911. begin
  2912. Inherited Init(Bounds,AHScrollBar,AVScrollBar);
  2913. end;
  2914. procedure TFramesListBox.Update;
  2915. var i : longint;
  2916. W : PSourceWindow;
  2917. begin
  2918. { call backtrace command }
  2919. If not assigned(Debugger) then
  2920. exit;
  2921. {$ifndef NODEBUG}
  2922. DeskTop^.Lock;
  2923. Clear;
  2924. { forget all old frames }
  2925. Debugger^.clear_frames;
  2926. if Debugger^.WindowWidth<>-1 then
  2927. Debugger^.Command('set width 0xffffffff');
  2928. Debugger^.Command('backtrace');
  2929. { generate list }
  2930. { all is in tframeentry }
  2931. for i:=0 to Debugger^.frame_count-1 do
  2932. begin
  2933. with Debugger^.frames[i]^ do
  2934. begin
  2935. if assigned(file_name) then
  2936. AddItem(new(PMessageItem,init(0,GetPChar(function_name)+GetPChar(args),
  2937. AddModuleName(GetPChar(file_name)),line_number,1)))
  2938. else
  2939. AddItem(new(PMessageItem,init(0,HexStr(address,8)+' '+GetPChar(function_name)+GetPChar(args),
  2940. AddModuleName(''),line_number,1)));
  2941. W:=SearchOnDesktop(GetPChar(file_name),false);
  2942. { First reset all Debugger rows }
  2943. If assigned(W) then
  2944. begin
  2945. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,-1);
  2946. W^.Editor^.DebuggerRow:=-1;
  2947. end;
  2948. end;
  2949. end;
  2950. { Now set all Debugger rows }
  2951. for i:=0 to Debugger^.frame_count-1 do
  2952. begin
  2953. with Debugger^.frames[i]^ do
  2954. begin
  2955. W:=SearchOnDesktop(GetPChar(file_name),false);
  2956. If assigned(W) then
  2957. begin
  2958. If W^.Editor^.DebuggerRow=-1 then
  2959. begin
  2960. W^.Editor^.SetLineFlagState(line_number-1,lfDebuggerRow,true);
  2961. W^.Editor^.DebuggerRow:=line_number-1;
  2962. end;
  2963. end;
  2964. end;
  2965. end;
  2966. if Assigned(list) and (List^.Count > 0) then
  2967. FocusItem(0);
  2968. if Debugger^.WindowWidth<>-1 then
  2969. Debugger^.Command('set width '+IntToStr(Debugger^.WindowWidth));
  2970. DeskTop^.Unlock;
  2971. {$endif}
  2972. end;
  2973. function TFramesListBox.GetLocalMenu: PMenu;
  2974. begin
  2975. GetLocalMenu:=Inherited GetLocalMenu;
  2976. end;
  2977. procedure TFramesListBox.GotoSource;
  2978. begin
  2979. { select frame for watches }
  2980. If not assigned(Debugger) then
  2981. exit;
  2982. {$ifndef NODEBUG}
  2983. Debugger^.Command('f '+IntToStr(Focused));
  2984. { for local vars }
  2985. Debugger^.RereadWatches;
  2986. {$endif}
  2987. { goto source }
  2988. inherited GotoSource;
  2989. end;
  2990. procedure TFramesListBox.GotoAssembly;
  2991. begin
  2992. { select frame for watches }
  2993. If not assigned(Debugger) then
  2994. exit;
  2995. {$ifndef NODEBUG}
  2996. Debugger^.Command('f '+IntToStr(Focused));
  2997. { for local vars }
  2998. Debugger^.RereadWatches;
  2999. {$endif}
  3000. { goto source/assembly mixture }
  3001. InitDisassemblyWindow;
  3002. DisassemblyWindow^.LoadFunction('');
  3003. DisassemblyWindow^.SetCurAddress(Debugger^.frames[Focused]^.address);
  3004. DisassemblyWindow^.SelectInDebugSession;
  3005. end;
  3006. procedure TFramesListBox.HandleEvent(var Event: TEvent);
  3007. begin
  3008. if ((Event.What=EvKeyDown) and (Event.CharCode='i')) or
  3009. ((Event.What=EvCommand) and (Event.Command=cmDisassemble)) then
  3010. GotoAssembly;
  3011. inherited HandleEvent(Event);
  3012. end;
  3013. destructor TFramesListBox.Done;
  3014. begin
  3015. Inherited Done;
  3016. end;
  3017. Constructor TStackWindow.Init;
  3018. var
  3019. HSB,VSB: PScrollBar;
  3020. R,R2 : trect;
  3021. begin
  3022. Desktop^.GetExtent(R);
  3023. R.A.Y:=R.B.Y-5;
  3024. inherited Init(R, dialog_callstack, wnNoNumber);
  3025. Palette:=wpCyanWindow;
  3026. GetExtent(R);
  3027. HelpCtx:=hcStackWindow;
  3028. R.Grow(-1,-1);
  3029. R2.Copy(R);
  3030. Inc(R2.B.Y);
  3031. R2.A.Y:=R2.B.Y-1;
  3032. New(HSB, Init(R2));
  3033. HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX;
  3034. Insert(HSB);
  3035. R2.Copy(R);
  3036. Inc(R2.B.X);
  3037. R2.A.X:=R2.B.X-1;
  3038. New(VSB, Init(R2));
  3039. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  3040. Insert(VSB);
  3041. New(FLB,Init(R,HSB,VSB));
  3042. FLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  3043. Insert(FLB);
  3044. If assigned(StackWindow) then
  3045. dispose(StackWindow,done);
  3046. StackWindow:=@Self;
  3047. Update;
  3048. end;
  3049. procedure TStackWindow.Update;
  3050. begin
  3051. FLB^.Update;
  3052. DrawView;
  3053. end;
  3054. constructor TStackWindow.Load(var S: TStream);
  3055. begin
  3056. inherited Load(S);
  3057. GetSubViewPtr(S,FLB);
  3058. If assigned(StackWindow) then
  3059. dispose(StackWindow,done);
  3060. StackWindow:=@Self;
  3061. end;
  3062. procedure TStackWindow.Store(var S: TStream);
  3063. begin
  3064. inherited Store(S);
  3065. PutSubViewPtr(S,FLB);
  3066. end;
  3067. Destructor TStackWindow.Done;
  3068. begin
  3069. StackWindow:=nil;
  3070. Dispose(FLB,done);
  3071. inherited done;
  3072. end;
  3073. {****************************************************************************
  3074. Init/Final
  3075. ****************************************************************************}
  3076. function GetGDBTargetShortName : string;
  3077. begin
  3078. {$ifdef SUPPORT_REMOTE}
  3079. {$ifdef PALMOSGDB}
  3080. GetGDBTargetShortName:='palmos';
  3081. {$else}
  3082. GetGDBTargetShortName:='linux';
  3083. {$endif PALMOSGDB}
  3084. {$else not SUPPORT_REMOTE}
  3085. GetGDBTargetShortName:=source_info.shortname
  3086. {$endif not SUPPORT_REMOTE}
  3087. end;
  3088. procedure InitDebugger;
  3089. {$ifdef DEBUG}
  3090. var s : string;
  3091. i,p : longint;
  3092. {$endif DEBUG}
  3093. var
  3094. NeedRecompileExe : boolean;
  3095. cm : longint;
  3096. begin
  3097. {$ifdef DEBUG}
  3098. if not use_gdb_file then
  3099. begin
  3100. Assign(gdb_file,GDBOutFileName);
  3101. {$I-}
  3102. Rewrite(gdb_file);
  3103. if InOutRes<>0 then
  3104. begin
  3105. s:=GDBOutFileName;
  3106. p:=pos('.',s);
  3107. if p>1 then
  3108. for i:=0 to 9 do
  3109. begin
  3110. s:=copy(s,1,p-2)+chr(i+ord('0'))+copy(s,p,length(s));
  3111. InOutRes:=0;
  3112. Assign(gdb_file,s);
  3113. rewrite(gdb_file);
  3114. if InOutRes=0 then
  3115. break;
  3116. end;
  3117. end;
  3118. if IOResult=0 then
  3119. Use_gdb_file:=true;
  3120. end;
  3121. {$I+}
  3122. {$endif}
  3123. NeedRecompileExe:=false;
  3124. if UpCaseStr(TargetSwitches^.GetCurrSelParam)<>UpCaseStr(GetGDBTargetShortName) then
  3125. begin
  3126. ClearFormatParams;
  3127. AddFormatParamStr(TargetSwitches^.GetCurrSelParam);
  3128. AddFormatParamStr(GetGDBTargetShortName);
  3129. cm:=ConfirmBox(msg_cantdebugchangetargetto,@FormatParams,true);
  3130. if cm=cmCancel then
  3131. Exit;
  3132. if cm=cmYes then
  3133. begin
  3134. { force recompilation }
  3135. PrevMainFile:='';
  3136. NeedRecompileExe:=true;
  3137. TargetSwitches^.SetCurrSelParam(GetGDBTargetShortName);
  3138. If DebugInfoSwitches^.GetCurrSelParam='-' then
  3139. DebugInfoSwitches^.SetCurrSelParam('l');
  3140. IDEApp.UpdateTarget;
  3141. end;
  3142. end;
  3143. if not NeedRecompileExe then
  3144. NeedRecompileExe:=(not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) or
  3145. (PrevMainFile<>MainFile) or NeedRecompile(cRun,false);
  3146. if Not NeedRecompileExe and Not MainHasDebugInfo then
  3147. begin
  3148. ClearFormatParams;
  3149. cm:=ConfirmBox(msg_compiledwithoutdebuginforecompile,nil,true);
  3150. if cm=cmCancel then
  3151. Exit;
  3152. if cm=cmYes then
  3153. begin
  3154. { force recompilation }
  3155. PrevMainFile:='';
  3156. NeedRecompileExe:=true;
  3157. DebugInfoSwitches^.SetCurrSelParam('l');
  3158. end;
  3159. end;
  3160. if NeedRecompileExe then
  3161. DoCompile(cRun);
  3162. if CompilationPhase<>cpDone then
  3163. Exit;
  3164. if (EXEFile='') then
  3165. begin
  3166. ErrorBox(msg_nothingtodebug,nil);
  3167. Exit;
  3168. end;
  3169. { init debugcontroller }
  3170. if not assigned(Debugger) then
  3171. begin
  3172. PushStatus(msg_startingdebugger);
  3173. new(Debugger,Init);
  3174. PopStatus;
  3175. end;
  3176. Debugger^.SetExe(ExeFile);
  3177. {$ifdef GDBWINDOW}
  3178. InitGDBWindow;
  3179. {$endif def GDBWINDOW}
  3180. end;
  3181. procedure DoneDebugger;
  3182. begin
  3183. {$ifdef DEBUG}
  3184. If IDEApp.IsRunning then
  3185. PushStatus('Closing debugger');
  3186. {$endif}
  3187. if assigned(Debugger) then
  3188. dispose(Debugger,Done);
  3189. Debugger:=nil;
  3190. {$ifdef DOS}
  3191. If assigned(UserScreen) then
  3192. PDosScreen(UserScreen)^.FreeGraphBuffer;
  3193. {$endif DOS}
  3194. {$ifdef DEBUG}
  3195. If Use_gdb_file then
  3196. begin
  3197. Use_gdb_file:=false;
  3198. Close(GDB_file);
  3199. end;
  3200. If IDEApp.IsRunning then
  3201. PopStatus;
  3202. {$endif DEBUG}
  3203. end;
  3204. procedure InitGDBWindow;
  3205. var
  3206. R : TRect;
  3207. begin
  3208. if GDBWindow=nil then
  3209. begin
  3210. DeskTop^.GetExtent(R);
  3211. new(GDBWindow,init(R));
  3212. DeskTop^.Insert(GDBWindow);
  3213. end;
  3214. end;
  3215. procedure DoneGDBWindow;
  3216. begin
  3217. If IDEApp.IsRunning and
  3218. assigned(GDBWindow) then
  3219. begin
  3220. DeskTop^.Delete(GDBWindow);
  3221. end;
  3222. GDBWindow:=nil;
  3223. end;
  3224. procedure InitDisassemblyWindow;
  3225. var
  3226. R : TRect;
  3227. begin
  3228. if DisassemblyWindow=nil then
  3229. begin
  3230. DeskTop^.GetExtent(R);
  3231. new(DisassemblyWindow,init(R));
  3232. DeskTop^.Insert(DisassemblyWindow);
  3233. end;
  3234. end;
  3235. procedure DoneDisassemblyWindow;
  3236. begin
  3237. if assigned(DisassemblyWindow) then
  3238. begin
  3239. DeskTop^.Delete(DisassemblyWindow);
  3240. Dispose(DisassemblyWindow,Done);
  3241. DisassemblyWindow:=nil;
  3242. end;
  3243. end;
  3244. procedure InitStackWindow;
  3245. begin
  3246. if StackWindow=nil then
  3247. begin
  3248. new(StackWindow,init);
  3249. DeskTop^.Insert(StackWindow);
  3250. end;
  3251. end;
  3252. procedure DoneStackWindow;
  3253. begin
  3254. if assigned(StackWindow) then
  3255. begin
  3256. DeskTop^.Delete(StackWindow);
  3257. StackWindow:=nil;
  3258. end;
  3259. end;
  3260. procedure InitBreakpoints;
  3261. begin
  3262. New(BreakpointsCollection,init(10,10));
  3263. end;
  3264. procedure DoneBreakpoints;
  3265. begin
  3266. Dispose(BreakpointsCollection,Done);
  3267. BreakpointsCollection:=nil;
  3268. end;
  3269. procedure InitWatches;
  3270. begin
  3271. New(WatchesCollection,init);
  3272. end;
  3273. procedure DoneWatches;
  3274. begin
  3275. Dispose(WatchesCollection,Done);
  3276. WatchesCollection:=nil;
  3277. end;
  3278. procedure RegisterFPDebugViews;
  3279. begin
  3280. RegisterType(RWatchesWindow);
  3281. RegisterType(RBreakpointsWindow);
  3282. RegisterType(RWatchesListBox);
  3283. RegisterType(RBreakpointsListBox);
  3284. RegisterType(RStackWindow);
  3285. RegisterType(RFramesListBox);
  3286. RegisterType(RBreakpoint);
  3287. RegisterType(RWatch);
  3288. RegisterType(RBreakpointCollection);
  3289. RegisterType(RWatchesCollection);
  3290. end;
  3291. end.
  3292. {
  3293. $Log$
  3294. Revision 1.53 2004-11-08 20:28:26 peter
  3295. * Breakpoints are now deleted when removed from source, disabling is
  3296. still possible from the breakpoint list
  3297. * COMPILER_1_0, FVISION, GABOR defines removed, only support new
  3298. FV and 1.9.x compilers
  3299. * Run directory added to Run menu
  3300. * Useless programinfo window removed
  3301. Revision 1.52 2004/11/06 17:22:52 peter
  3302. * fixes for new fv
  3303. Revision 1.51 2004/07/09 23:17:25 peter
  3304. * revert isatty patch
  3305. Revision 1.49 2004/02/20 21:46:06 peter
  3306. * fix compile with 1.0.x
  3307. Revision 1.48 2003/11/19 17:11:39 marco
  3308. * termio unit
  3309. Revision 1.47 2003/11/17 10:05:51 marco
  3310. * threads for FreeBSD. Not working tho
  3311. Revision 1.46 2003/03/30 12:12:12 armin
  3312. * allow local and remote debugging if SUPPORT_REMOTE is given
  3313. Revision 1.45 2003/03/27 14:10:55 pierre
  3314. * fix problem with mixed case target names as suggested by Armin Diehl
  3315. Revision 1.44 2003/01/14 16:25:23 pierre
  3316. + small palmos specific additions
  3317. Revision 1.43 2002/12/18 01:20:12 pierre
  3318. + Use TEditorInputLine instead of TInputLine
  3319. Revision 1.42 2002/12/16 15:15:40 pierre
  3320. * Added TBreakpointCollection.FindBreakpointAt method
  3321. Revision 1.41 2002/12/16 09:05:28 pierre
  3322. * sanity ceck in ToggleFileLine method
  3323. Revision 1.40 2002/02/09 02:04:46 pierre
  3324. * fix problem with disable all invalid breakpoints
  3325. Revision 1.39 2002/12/12 00:05:57 pierre
  3326. * add code for breakpoint moves + registers in fprags.pas unit
  3327. Revision 1.38 2002/11/30 01:56:52 pierre
  3328. + powerpc cpu support started
  3329. Revision 1.37 2002/11/28 13:00:25 pierre
  3330. + remote support
  3331. Revision 1.36 2002/11/21 17:52:28 pierre
  3332. * some crossgdb infos added
  3333. Revision 1.35 2002/11/21 15:48:39 pierre
  3334. * fix several problems related to remote cross debugging
  3335. Revision 1.34 2002/11/21 00:37:56 pierre
  3336. + some cross gdb enhancements
  3337. Revision 1.33 2002/09/21 22:23:49 pierre
  3338. * restore text mode on reset for Dos apps
  3339. Revision 1.32 2002/09/17 21:58:45 pierre
  3340. * correct last fpu patch so 'info all' is called only once
  3341. Revision 1.31 2002/09/17 21:48:41 pierre
  3342. * allow fpu window to be resized
  3343. Revision 1.30 2002/09/17 21:20:07 pierre
  3344. * fix infinite recursion if GDB window and register window open
  3345. Revision 1.29 2002/09/13 22:30:50 pierre
  3346. * only fpc uses video unit
  3347. Revision 1.28 2002/09/13 08:13:07 pierre
  3348. * avoid RTE 201 in hexstr calls
  3349. Revision 1.27 2002/09/07 21:04:41 carl
  3350. * fix range check errors for version 1.1 compilation
  3351. Revision 1.26 2002/09/07 15:40:42 peter
  3352. * old logs removed and tabs fixed
  3353. Revision 1.25 2002/09/03 13:59:47 pierre
  3354. + added history for watches and breakpoints
  3355. Revision 1.24 2002/09/02 10:18:09 pierre
  3356. * fix problems with breakpoint lists
  3357. Revision 1.23 2002/08/13 08:59:12 pierre
  3358. + Run menu changes depending on wether the debuggee is running or not
  3359. Revision 1.22 2002/08/13 07:15:02 pierre
  3360. + Disable all invalid breakpoints feature added
  3361. Revision 1.21 2002/06/10 19:26:48 pierre
  3362. * check if DebuggeTTY is a valid terminal
  3363. Revision 1.20 2002/06/06 14:11:25 pierre
  3364. * handle win32 Ctrl-C change for graphic version
  3365. Revision 1.19 2002/06/06 08:16:18 pierre
  3366. * avoid crashes if quitting while debuggee is running
  3367. Revision 1.18 2002/04/25 13:33:31 pierre
  3368. * fix the problem with dirs containing asterisks
  3369. Revision 1.17 2002/04/17 11:11:54 pierre
  3370. * avoid problems for ClassVariable in Watches window
  3371. Revision 1.16 2002/04/11 06:41:13 pierre
  3372. * fix problem of TWatchesListBox with fvision
  3373. Revision 1.15 2002/04/03 06:18:30 pierre
  3374. * fix some win32 GDB filename problems
  3375. Revision 1.14 2002/04/02 15:09:38 pierre
  3376. * fixed wrong exit without unlock
  3377. Revision 1.13 2002/04/02 13:23:54 pierre
  3378. * Use StrToCard and HexToCard functions to avoid signed/unsigned overflows
  3379. Revision 1.12 2002/04/02 12:20:58 pierre
  3380. * fix problem with breakpoints in subdirs
  3381. Revision 1.11 2002/04/02 11:10:29 pierre
  3382. * fix FPC_BREAK_ERROR problem and avoid blinking J
  3383. Revision 1.10 2002/03/27 11:24:09 pierre
  3384. * fix several problems related to long file nmze support for win32 exes
  3385. Revision 1.9 2002/02/06 14:45:00 pierre
  3386. + handle signals
  3387. }