fpdebug.pas 125 KB

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