fpdebug.pas 117 KB

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