fpdebug.pas 118 KB

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