fpdebug.pas 116 KB

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