File: lazdebuggerintf.pas

package info (click to toggle)
lazarus 4.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 275,760 kB
  • sloc: pascal: 2,341,904; xml: 509,420; makefile: 348,726; cpp: 93,608; sh: 3,387; java: 609; perl: 297; sql: 222; ansic: 137
file content (324 lines) | stat: -rw-r--r-- 15,107 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
{***************************************************************************
 *                                                                         *
 * This unit is distributed under the LGPL version 2                       *
 *                                                                         *
 * Additionally this unit can be used under any newer version (3 or up)    *
 * of the LGPL                                                             *
 *                                                                         *
 * Users are also granted the same "linking exception" as defined          *
 * for the LCL.                                                            *
 * See the LCL license for details                                         *
 *                                                                         *
 *                                                                         *
 ***************************************************************************
 @author(Martin Friebe)
}
unit LazDebuggerIntf;

{$mode objfpc}{$H+}
{$INTERFACES CORBA} // no ref counting needed

interface

uses
  Classes, SysUtils, Types, LazDebuggerValueConverter, LazDebuggerIntfBaseTypes,
  LazDebuggerIntfFloatTypes;

type
  TDBGState = LazDebuggerIntfBaseTypes.TDBGState deprecated 'Use LazDebuggerIntfBaseTypes.TDBGState';

  {$REGION ***** Internal types ***** }

  IInternalDbgMonitorIntfType  = interface end;
  IInternalDbgSupplierIntfType = interface end;

  generic IInternalDbgMonitorIntf<_SUPPLIER_INTF> = interface(IInternalDbgMonitorIntfType)
    procedure RemoveSupplier(ASupplier: _SUPPLIER_INTF);
  end;

  generic IInternalDbgSupplierIntf<_MONITOR_INTF> = interface(IInternalDbgSupplierIntfType)
    procedure SetMonitor(AMonitor: _MONITOR_INTF);
  end;

  {$ENDREGION}

type

  TDebuggerDataState = (ddsUnknown,                    //
                        ddsRequested, ddsEvaluating,   //
                        ddsValid,                      // Got a valid value
                        ddsInvalid,                    // Does not have a value
                        ddsError                       // Error, but got some Value to display (e.g. error msg)
                       );

  IDbgDataRequestIntf = interface;

  TDbgDataRequestEventType = (
    weeCancel
  );
  TDbgDataRequestEventData = record
    case TDbgDataRequestEventType of
      weeCancel: ();
  end;
  TDbgDataRequestEvent = procedure(Sender: IDbgDataRequestIntf; Data: TDbgDataRequestEventData) of object;

  IDbgDataRequestIntf = interface
    ['{48D16FDC-8F02-4302-ABAA-4EA68827580D}']
    procedure AddFreeNotification(ANotification: TNotifyEvent);
    procedure RemoveFreeNotification(ANotification: TNotifyEvent);

    procedure AddNotification(AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent);
    procedure RemoveNotification(AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent);

    (* Begin/EndUdate
       - shall indicate that the newly set values are now valid. Ready for display.
         (Indicated by EndUpdate)
       - shall protect the object from destruction.
         A debugger backend may access the object during this time, without further checks.
       - shall ensure changes outside the backend, will not affect calls by the
         backend to any method setting/adding/modifing requested data.
         ~ I.e. if the backend adds values to an array or structure, further calls
           by the backend to add more data must be accepted without failure.
         ~ However, further data may be discarded internally, if possible without
           causing later failures (e.g. if the requested data is no longer needed)
   (!) - does NOT affect, if read-only properties/functions can change their value.
         E.g., if the requested value is no longer needed, then "Expression" and
         other "passed in/provided values" may change (reset to default/empty)
     * When used in the IDE (Begin/EndUpdate themself shall only be valid in the main thread),
       shall
       - allow the backend to read "passed in/provided values" from another thread
       - allow the backend to set new values from another thread
         (I.e., if the IDE (or any non-backend code) makes changes, they must
          consider thread safety)
       // Any "frontend" outside the IDE (commandline / dbg-server) doens not
          need to consider thread safety, as long as it knows that this in not
          required by any of the backends it uses.
    *)
    procedure BeginUpdate;
    procedure EndUpdate;
  end;



{%region **********************************************************************
 ******************************************************************************
 **                                                                          **
 **   W A T C H T E S                                                        **
 **                                                                          **
 ******************************************************************************
 ******************************************************************************}

  TWatcheEvaluateFlag =
    ( defClassAutoCast,     // Find real class of instance, and use, instead of declared class of variable
      defAllowFunctionCall, //
      defFunctionCallRunAllThreads, //
      defExtraDepth,        // Evaluate 1 extra level of sub-elements => i.e., evaluate each nested sub-item
      defSkipValConv,
      defSkipValueFormatter, // Don't use any Valueformatter // not eval related
      defMemDump,           // Return Memory Dump, **instead** of value
      // deprecated
      defNoTypeInfo,        // No Typeinfo object will be returned // for structures that means a printed value will be returned
      defSimpleTypeInfo,    // Returns: Kind (skSimple, skClass, ..); TypeName (but does make no attempt to avoid an alias)
      defFullTypeInfo      // Get all typeinfo, resolve all anchestors
//     defRawMemory,         // returns Array of bytes for hex dump
//     defNoValue            // Skip the value, if returning raw mem
    );
  TWatcheEvaluateFlags = set of TWatcheEvaluateFlag;

  TDBGTypeBase = class(TObject)
  end;

  TLzDbgToken = QWord;
  {$If SizeOf(TLzDbgToken) < SizeOf(Pointer)} {$Error 'TLzDbgToken must be able to store pointers'} {$EndIf}


  TLzDbgFloatPrecission = (dfpSingle, dfpDouble, dfpExtended);
//  TLzDbgSetData = bitpacked array [0..255] of boolean;
  TLzDbgStructType      = (dstUnknown, dstRecord, dstObject, dstClass, dstInterface, dstInternal);
  TLzDbgArrayType       = (datUnknown, datDynArray, datStatArray);
  TLzDbgFieldVisibility = (dfvUnknown, dfvPrivate, dfvProtected, dfvPublic, dfvPublished);
  TLzDbgFieldFlag  = (dffClass, dffAbstract, dffVirtual, dffOverwritten, dffConstructor, dffDestructor, dffVariant);
  TLzDbgArrayTypes = set of TLzDbgArrayType;
  TLzDbgFieldFlags = set of TLzDbgFieldFlag;

  { IDbgWatchDataIntf:
    - Interface for providing result-data.
    - REQUIREMENTS (for the backend)
      ** INIT with Create...." **
         First call must be to one of the "Create...." methods.
         Other data can only be set/added after that.
      ** INIT exactly ONCE **
         Only one "Create...." method can be called.
         The type can't be changed after that.
         - Except for:
           CreateError may be called even if one of the non-erroc "Create..." had been called before
      ** All ARRAY elements must have the same type **
         - All entries of an array (added with "SetNextArrayData") must have the
           same type (i.e., be initialized using the same "Create...." method)
         - This includes all *nested* types (e.g. pointer deref)
      ** SetPCharShouldBeStringValue
         - Like array elements: The 2nd value must have the same type as the first.
         - Not allowed to be called on nested elements
    - Adding nested data (calling any method returning a new IDbgWatchDataIntf)
      The Frontend may return "nil" to indicate it does not want this particular data.
  }

  IDbgWatchDataIntf = interface
    ['{0FE00324-C265-4239-8781-51FFF8CEA31C}']
    procedure CreatePrePrinted(AVal: String); // ATypes: TLzDbgWatchDataTypes);
    procedure CreateString(AVal: String);// AnEncoding // "pchar data" // shortstring
    procedure CreateWideString(AVal: WideString);
    procedure CreateCharValue(ACharValue: QWord; AByteSize: Integer = 0);
    procedure CreateNumValue(ANumValue: QWord; ASigned: Boolean; AByteSize: Integer = 0);
    procedure CreatePointerValue(AnAddrValue: TDbgPtr);
    procedure CreateFloatValue(AFloatValue: Single);
    procedure CreateFloatValue(AFloatValue: Double);
    procedure CreateFloatValue(AFloatValue: TDbgExtended);
    procedure CreateFloatValue(AFloatValue: Extended; APrecission: TLzDbgFloatPrecission); deprecated;
    procedure CreateBoolValue(AnOrdBoolValue: QWord; AByteSize: Integer = 0);
    procedure CreateEnumValue(ANumValue: QWord; AName: String; AByteSize: Integer = 0; AnIsEnumIdent: Boolean = False);
//    //procedure CreateEnumValue(ANumValue: QWord; const ANames: TStringDynArray; const AOrdValues: TIntegerDynArray);
    procedure CreateSetValue(const ANames: TStringDynArray); //; const AOrdValues: array of Integer);
//    // CreateSetValue: "ASetVal" only has "length(ANames)" entries. Any higher value will be ignored / should be zero
//    procedure CreateSetValue(const ASetVal: TLzDbgSetData; const ANames: TStringDynArray); //; const AOrdValues: array of Integer);
    function CreateVariantValue(AName: String = ''; AVisibility: TLzDbgFieldVisibility = dfvUnknown): IDbgWatchDataIntf;

    //temporary
    function CreateProcedure(AVal: TDBGPtr; AnIsFunction: Boolean; ALoc, ADesc: String): IDbgWatchDataIntf;
    function CreateProcedureRef(AVal: TDBGPtr; AnIsFunction: Boolean; ALoc, ADesc: String): IDbgWatchDataIntf;

    // Returns Intf for setting element-type => for empty array
    function CreateArrayValue(AnArrayType: TLzDbgArrayType;
                              ATotalCount: Integer = 0;
                              ALowIdx: Integer = 0
                             ): IDbgWatchDataIntf;

    procedure CreateStructure(AStructType: TLzDbgStructType;
                              ADataAddress: TDBGPtr = 0
                              //AOwnFieldCount: Integer = 0;    // Fields declared in this structure (no anchestors)
                              //ARecurseFieldCount: Integer = 0 // Fields including anchestors
                             );
    // returns the intf for the converted result
    // Use SetDerefData to get the interface for the NON-converted result
    function CreateValueHandlerResult(AValueHandler: ILazDbgValueConverterIntf): IDbgWatchDataIntf;
    procedure CreateMemDump(AVal: RawByteString);
    procedure CreateError(AVal: String);

    // For all Values
    (* SetPCharShouldBeStringValue:
       - Current Res should be "PChar-based"
       - Result of this function should be used for "String-based"
    *)
    function  SetPCharShouldBeStringValue: IDbgWatchDataIntf;
    // For all Values (except error)
    procedure SetTypeName(ATypeName: String);

    // For Array
    procedure SetDataAddress(AnAddr: TDbgPtr);

    // For Pointers:
    function  SetDerefData: IDbgWatchDataIntf;

    // For Arrays
    (* - The returned IDbgWatchDataIntf is only valid until the next call of SetNextItemData.
         For nested arrays, this includes calls to any outer arrays SetNextItemData.
       - Type related (ASigned, AByteSize, APrecission, ...) are taken from the
         proto-type or the  first Item only. They are ignored on subsequent items
    *)
    function  SetNextArrayData: IDbgWatchDataIntf;

    // For structures:
    function  SetAnchestor(ATypeName: String): IDbgWatchDataIntf; // Only: object, class, interface
    function  AddField(AFieldName: String;
                       AVisibility: TLzDbgFieldVisibility;
                       AFlags: TLzDbgFieldFlags
//                       AnAnchestor: IDbgWatchDataIntf  // nil => unknown
                      ): IDbgWatchDataIntf;
  end;

  { IDbgWatchValueIntf }

  IDbgWatchValueIntf = interface(IDbgDataRequestIntf)
    ['{20A8A0E3-C456-463D-8B33-DC0CF6037D6B}']
    function ResData: IDbgWatchDataIntf;

    (* ***** Methods for the front-end to provide the request  ***** *)

    function GetEvaluateFlags: TWatcheEvaluateFlags;
    function GetDbgValConverter: ILazDbgValueConvertSelectorIntf;
    function GetExpression: String;
    function GetFirstIndexOffs: Int64;
    function GetRepeatCount: Integer;
    function GetStackFrame: Integer;
    function GetThreadId: Integer;
    function GetValidity: TDebuggerDataState;
    procedure SetTypeInfo(AValue: TDBGTypeBase); // Must not be used by MemDump
    procedure SetValidity(AValue: TDebuggerDataState);
    procedure SetSliceIndexPos(APos, ALen: Integer);

    property EvaluateFlags: TWatcheEvaluateFlags read GetEvaluateFlags;
    property FirstIndexOffs: Int64 read GetFirstIndexOffs;
    property RepeatCount: Integer read GetRepeatCount;
    property ThreadId: Integer read GetThreadId;
    property StackFrame: Integer read GetStackFrame;
    property Expression: String read GetExpression;

    property Validity: TDebuggerDataState read GetValidity write SetValidity;
    property TypeInfo: TDBGTypeBase {read GetTypeInfo} write SetTypeInfo; // Must not be used by MemDump
  end;



  IDbgWatchesSupplierIntf = interface;

  IDbgWatchesMonitorIntf  = interface(specialize IInternalDbgMonitorIntf<IDbgWatchesSupplierIntf>)
    ['{42A7069E-D5DD-4350-A592-2000F67DC7E9}']
    procedure InvalidateWatchValues;
    procedure DoStateChange(const AOldState, ANewState: TDBGState); //deprecated;
  end;

  IDbgWatchesSupplierIntf = interface(specialize IInternalDbgSupplierIntf<IDbgWatchesMonitorIntf>)
    ['{F893B607-C295-4A3A-8253-FAB3D03C5AD5}']
    procedure RequestData(AWatchValue: IDbgWatchValueIntf);
  end;

{%endregion   ^^^^^  Watches  ^^^^^   }


{%region   ^^^^^  Locals  ^^^^^   }

  IDbgLocalsListIntf = interface(IDbgDataRequestIntf)
    ['{B288AD25-7D54-447C-AE9D-32B3E9789BCE}']
    function Add(AName: String): IDbgWatchDataIntf;

    function GetStackFrame: Integer;
    function GetThreadId: Integer;
    procedure SetValidity(AValue: TDebuggerDataState);

    property ThreadId: Integer read GetThreadId;
    property StackFrame: Integer read GetStackFrame;
    property Validity: TDebuggerDataState {read GetValidity} write SetValidity;
  end;


  IDbgLocalsSupplierIntf = interface;

  IDbgLocalsMonitorIntf  = interface(specialize IInternalDbgMonitorIntf<IDbgLocalsSupplierIntf>)
    ['{7EBDD107-E55F-4E3F-9281-5CA0116EA75D}']
    procedure InvalidateLocalValues;
    procedure DoStateChange(const AOldState, ANewState: TDBGState); //deprecated;
  end;

  IDbgLocalsSupplierIntf = interface(specialize IInternalDbgSupplierIntf<IDbgLocalsMonitorIntf>)
    ['{755A287E-4609-4E8B-94CF-08525DC9A082}']
    procedure RequestData(ALocalsList: IDbgLocalsListIntf);
  end;

{%endregion   ^^^^^  Locals  ^^^^^   }


implementation


end.