fpdebug.pas 127 KB

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