fpdebug.pas 128 KB

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