fpdebug.pas 97 KB

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