fpdebug.pas 118 KB

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