fpdebug.pas 116 KB

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