fpdebug.pas 100 KB

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