fpdebug.pas 119 KB

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