fpdebug.pas 96 KB

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