fpdebug.pas 121 KB

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