fpdebug.pas 114 KB

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