• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef PANDA_RUNTIME_DEBUG_DEBUG_INTERFACE_H
16 #define PANDA_RUNTIME_DEBUG_DEBUG_INTERFACE_H
17 
18 #include <cstdint>
19 #include <list>
20 #include <optional>
21 #include <string>
22 #include <string_view>
23 #include <vector>
24 
25 #include "libpandabase/macros.h"
26 #include "libpandabase/utils/expected.h"
27 #include "libpandafile/file.h"
28 #include "runtime/include/console_call_type.h"
29 #include "runtime/include/coretypes/tagged_value.h"
30 #include "runtime/include/mem/panda_containers.h"
31 #include "runtime/include/thread.h"
32 #include "runtime/include/tooling/pt_location.h"
33 #include "runtime/include/tooling/pt_macros.h"
34 #include "runtime/include/tooling/pt_object.h"
35 #include "runtime/include/tooling/pt_property.h"
36 #include "runtime/include/tooling/pt_thread.h"
37 #include "runtime/include/tooling/pt_value.h"
38 #include "runtime/include/tooling/vreg_value.h"
39 #include "runtime/interpreter/frame.h"
40 #include "runtime/include/tooling/pt_lang_extension.h"
41 #include "runtime/include/typed_value.h"
42 
43 namespace ark::tooling {
44 class PtLangExt;
45 
46 class Error {
47 public:
48     enum class Type {
49         BREAKPOINT_NOT_FOUND,
50         BREAKPOINT_ALREADY_EXISTS,
51         ENTRY_POINT_RESOLVE_ERROR,
52         FRAME_NOT_FOUND,
53         NO_MORE_FRAMES,
54         OPAQUE_FRAME,
55         INVALID_BREAKPOINT,
56         INVALID_ENTRY_POINT,
57         METHOD_NOT_FOUND,
58         PANDA_FILE_LOAD_ERROR,
59         THREAD_NOT_FOUND,
60         THREAD_NOT_SUSPENDED,
61         INVALID_REGISTER,
62         INVALID_VALUE,
63         INVALID_EXPRESSION,
64         PROPERTY_ACCESS_WATCH_NOT_FOUND,
65         INVALID_PROPERTY_ACCESS_WATCH,
66         PROPERTY_MODIFY_WATCH_NOT_FOUND,
67         INVALID_PROPERTY_MODIFY_WATCH,
68         DEPRECATED,
69     };
70 
Error(Type type,std::string msg)71     Error(Type type, std::string msg) : type_(type), msg_(std::move(msg)) {}
72 
GetType()73     Type GetType() const
74     {
75         return type_;
76     }
77 
GetMessage()78     std::string GetMessage() const
79     {
80         return msg_;
81     }
82 
83     ~Error() = default;
84 
85     DEFAULT_COPY_SEMANTIC(Error);
86     DEFAULT_MOVE_SEMANTIC(Error);
87 
88 private:
89     Type type_;
90     std::string msg_;
91 };
92 
93 class PtFrame {
94 public:
95     enum class RegisterKind { PRIMITIVE, REFERENCE, TAGGED };
96 
97     PtFrame() = default;
98 
99     virtual bool IsInterpreterFrame() const = 0;
100 
101     virtual Method *GetMethod() const = 0;
102 
103     virtual uint64_t GetVReg(size_t i) const = 0;
104 
105     virtual RegisterKind GetVRegKind(size_t i) const = 0;
106 
107     virtual size_t GetVRegNum() const = 0;
108 
109     virtual uint64_t GetArgument(size_t i) const = 0;
110 
111     virtual RegisterKind GetArgumentKind(size_t i) const = 0;
112 
113     virtual size_t GetArgumentNum() const = 0;
114 
115     virtual uint64_t GetAccumulator() const = 0;
116 
117     virtual RegisterKind GetAccumulatorKind() const = 0;
118 
119     virtual panda_file::File::EntityId GetMethodId() const = 0;
120 
121     virtual uint32_t GetBytecodeOffset() const = 0;
122 
123     virtual std::string GetPandaFile() const = 0;
124 
125     // mock API
126     virtual uint32_t GetFrameId() const = 0;
127 
128     virtual ~PtFrame() = default;
129 
130     NO_COPY_SEMANTIC(PtFrame);
131     NO_MOVE_SEMANTIC(PtFrame);
132 };
133 
134 struct PtStepRange {
135     uint32_t startBcOffset {0};
136     uint32_t endBcOffset {0};
137 };
138 
139 // * * * * *
140 // Mock API helpers
141 // NOTE(maksenov): cleanup
142 // * * * * *
143 
144 using ExceptionID = panda_file::File::EntityId;
145 using ExecutionContextId = panda_file::File::EntityId;
146 using ThreadGroup = uint32_t;
147 
148 using ExpressionWrapper = std::string;
149 using ExceptionWrapper = std::string;
150 
151 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
152 struct ThreadInfo {
153     char *name;
154     size_t nameLength;
155     int32_t priority;
156     bool isDaemon;
157     ThreadGroup threadGroup;
158 };
159 
160 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
161 struct PandaClassDefinition {
162     PtClass klass;
163     uint32_t classByteCount;
164     const unsigned char *classBytes;
165 };
166 
167 enum PauseReason {
168     AMBIGUOUS,
169     ASSERT,
170     DEBUGCOMMAND,
171     DOM,
172     EVENTLISTENER,
173     EXCEPTION,
174     INSTRUMENTATION,
175     OOM,
176     OTHER,
177     PROMISEREJECTION,
178     XHR,
179     BREAK_ON_START
180 };
181 
182 struct ExecutionContextWrapper {
183     ExecutionContextId id;
184     std::string origin;
185     std::string name;
186 };
187 
188 enum class PtHookType {
189     PT_HOOK_TYPE_BREAKPOINT,
190     PT_HOOK_TYPE_LOAD_MODULE,
191     PT_HOOK_TYPE_PAUSED,
192     PT_HOOK_TYPE_EXCEPTION,
193     PT_HOOK_TYPE_EXCEPTION_CATCH,
194     PT_HOOK_TYPE_PROPERTY_ACCESS,
195     PT_HOOK_TYPE_PROPERTY_MODIFICATION,
196     PT_HOOK_TYPE_CONSOLE_CALL,
197     PT_HOOK_TYPE_FRAME_POP,
198     PT_HOOK_TYPE_GARBAGE_COLLECTION_START,
199     PT_HOOK_TYPE_GARBAGE_COLLECTION_FINISH,
200     PT_HOOK_TYPE_METHOD_ENTRY,
201     PT_HOOK_TYPE_METHOD_EXIT,
202     PT_HOOK_TYPE_SINGLE_STEP,
203     PT_HOOK_TYPE_THREAD_START,
204     PT_HOOK_TYPE_THREAD_END,
205     PT_HOOK_TYPE_VM_DEATH,
206     PT_HOOK_TYPE_VM_INITIALIZATION,
207     PT_HOOK_TYPE_VM_START,
208     PT_HOOK_TYPE_EXCEPTION_REVOKED,
209     PT_HOOK_TYPE_EXECUTION_CONTEXT_CREATEED,
210     PT_HOOK_TYPE_EXECUTION_CONTEXT_DESTROYED,
211     PT_HOOK_TYPE_EXECUTION_CONTEXTS_CLEARED,
212     PT_HOOK_TYPE_INSPECT_REQUESTED,
213     PT_HOOK_TYPE_CLASS_LOAD,
214     PT_HOOK_TYPE_CLASS_PREPARE,
215     PT_HOOK_TYPE_MONITOR_WAIT,
216     PT_HOOK_TYPE_MONITOR_WAITED,
217     PT_HOOK_TYPE_MONITOR_CONTENDED_ENTER,
218     PT_HOOK_TYPE_MONITOR_CONTENDED_ENTERED,
219     PT_HOOK_TYPE_OBJECT_ALLOC,
220     // The count of hooks. Don't move
221     PT_HOOK_TYPE_COUNT
222 };
223 
224 // * * * * *
225 // Mock API helpers ends
226 // * * * * *
227 
228 class PtHooks {
229 public:
230     PtHooks() = default;
231 
232     /**
233      * @brief Method is called by the runtime when breakpoint hits. Thread where breakpoint hits is stopped until
234      * continue or step event will be received
235      * @param thread Identifier of the thread where breakpoint hits. Now the callback is called in the same
236      * thread
237      * @param method Method
238      * @param location Breakpoint location
239      */
Breakpoint(PtThread,Method *,const PtLocation &)240     virtual void Breakpoint(PtThread /* thread */, Method * /* method */, const PtLocation & /* location */) {}
241 
242     /**
243      * @brief Method is called by the runtime when panda file is loaded
244      * @param pandaFileName Path to panda file that is loaded
245      */
LoadModule(std::string_view)246     virtual void LoadModule(std::string_view /* pandaFileName */) {}
247 
248     /**
249      * @brief Method is called by the runtime when managed thread is attached to it
250      * @param thread The attached thread
251      */
ThreadStart(PtThread)252     virtual void ThreadStart(PtThread /* thread */) {}
253 
254     /**
255      * @brief Method is called by the runtime when managed thread is detached
256      * @param thread The detached thread
257      */
ThreadEnd(PtThread)258     virtual void ThreadEnd(PtThread /* thread */) {}
259 
260     /// @brief Method is called by the runtime when virtual machine start initialization
VmStart()261     virtual void VmStart() {}
262 
263     /**
264      * @brief Method is called by the runtime when virtual machine finish initialization
265      * @param thread The initial thread
266      */
VmInitialization(PtThread)267     virtual void VmInitialization(PtThread /* thread */) {}
268 
269     /// @brief Method is called by the runtime when virtual machine death
VmDeath()270     virtual void VmDeath() {}
271 
272     /**
273      * @brief Method is called by the runtime when a class is first loaded
274      * @param thread Thread loading the class
275      * @param klass Class being loaded
276      */
ClassLoad(PtThread,BaseClass *)277     virtual void ClassLoad(PtThread /* thread */, BaseClass * /* klass */) {}
278 
279     /**
280      * @brief Method is called by the runtime when class preparation is complete
281      * @param thread Thread generating the class prepare
282      * @param klass Class being prepared
283      */
ClassPrepare(PtThread,BaseClass *)284     virtual void ClassPrepare(PtThread /* thread */, BaseClass * /* klass */) {}
285 
286     /**
287      * @brief Method is called by the runtime when a thread is about to wait on an object
288      * @param thread The thread about to wait
289      * @param object Reference to the monitor
290      * @param timeout The number of milliseconds the thread will wait
291      */
MonitorWait(PtThread,ObjectHeader *,int64_t)292     virtual void MonitorWait(PtThread /* thread */, ObjectHeader * /* object */, int64_t /* timeout */) {}
293 
294     /**
295      * @brief Method is called by the runtime when a thread finishes waiting on an object
296      * @param thread The thread about to wait
297      * @param object Reference to the monitor
298      * @param timedOut True if the monitor timed out
299      */
MonitorWaited(PtThread,ObjectHeader *,bool)300     virtual void MonitorWaited(PtThread /* thread */, ObjectHeader * /* object */, bool /* timedOut */) {}
301 
302     /**
303      * @brief Method is called by the runtime when a thread is attempting to enter a monitor already acquired by another
304      * thread
305      * @param thread The thread about to wait
306      * @param object Reference to the monitor
307      */
MonitorContendedEnter(PtThread,ObjectHeader *)308     virtual void MonitorContendedEnter(PtThread /* thread */, ObjectHeader * /* object */) {}
309 
310     /**
311      * @brief Method is called by the runtime when a thread enters a monitor after waiting for it to be released by
312      * another thread
313      * @param thread The thread about to wait
314      * @param object Reference to the monitor
315      */
MonitorContendedEntered(PtThread,ObjectHeader *)316     virtual void MonitorContendedEntered(PtThread /* thread */, ObjectHeader * /* object */) {}
317 
Exception(PtThread,Method *,const PtLocation &,ObjectHeader *,Method *,const PtLocation &)318     virtual void Exception(PtThread /* thread */, Method * /* method */, const PtLocation & /* location */,
319                            ObjectHeader * /* exceptionObject */, Method * /* catchMethod */,
320                            const PtLocation & /* catchLocation */)
321     {
322     }
323 
ExceptionCatch(PtThread,Method *,const PtLocation &,ObjectHeader *)324     virtual void ExceptionCatch(PtThread /* thread */, Method * /* catchMethod */, const PtLocation & /* location */,
325                                 ObjectHeader * /* exceptionObject */)
326     {
327     }
328 
PropertyAccess(PtThread,Method *,const PtLocation &,ObjectHeader *,PtProperty)329     virtual void PropertyAccess(PtThread /* thread */, Method * /* catchMethod */, const PtLocation & /* location */,
330                                 ObjectHeader * /* object */, PtProperty /* property */)
331     {
332     }
333 
PropertyModification(PtThread,Method *,const PtLocation &,ObjectHeader *,PtProperty,VRegValue)334     virtual void PropertyModification(PtThread /* thread */, Method * /* method */, const PtLocation & /* location */,
335                                       ObjectHeader * /* object */, PtProperty /* property */, VRegValue /* newValue */)
336     {
337     }
338 
ConsoleCall(PtThread,ConsoleCallType,uint64_t,const PandaVector<TypedValue> &)339     virtual void ConsoleCall(PtThread /* thread */, ConsoleCallType /* type */, uint64_t /* timestamp */,
340                              const PandaVector<TypedValue> & /* arguments */)
341     {
342     }
343 
FramePop(PtThread,Method *,bool)344     virtual void FramePop(PtThread /* thread */, Method * /* method */, bool /* wasPoppedByException */) {}
345 
GarbageCollectionFinish()346     virtual void GarbageCollectionFinish() {}
347 
GarbageCollectionStart()348     virtual void GarbageCollectionStart() {}
349 
ObjectAlloc(BaseClass *,ObjectHeader *,PtThread,size_t)350     virtual void ObjectAlloc(BaseClass * /* klass */, ObjectHeader * /* object */, PtThread /* thread */,
351                              size_t /* size */)
352     {
353     }
354 
MethodEntry(PtThread,Method *)355     virtual void MethodEntry(PtThread /* thread */, Method * /* method */) {}
356 
MethodExit(PtThread,Method *,bool,VRegValue)357     virtual void MethodExit(PtThread /* thread */, Method * /* method */, bool /* wasPoppedByException */,
358                             VRegValue /* returnValue */)
359     {
360     }
361 
SingleStep(PtThread,Method *,const PtLocation &)362     virtual void SingleStep(PtThread /* thread */, Method * /* method */, const PtLocation & /* location */) {}
363 
364     // * * * * *
365     // Deprecated hooks
366     // * * * * *
367 
Paused(PauseReason)368     virtual void Paused(PauseReason /* reason */) {}
Breakpoint(PtThread,const PtLocation &)369     virtual void Breakpoint(PtThread /* thread */, const PtLocation & /* location */) {}
Exception(PtThread,const PtLocation &,PtObject,const PtLocation &)370     virtual void Exception(PtThread /* thread */, const PtLocation & /* location */, PtObject /* exceptionObject */,
371                            const PtLocation & /* catchLocation */)
372     {
373     }
ExceptionCatch(PtThread,const PtLocation &,PtObject)374     virtual void ExceptionCatch(PtThread /* thread */, const PtLocation & /* location */,
375                                 PtObject /* exceptionObject */)
376     {
377     }
FramePop(PtThread,PtMethod,bool)378     virtual void FramePop(PtThread /* thread */, PtMethod /* method */, bool /* wasPoppedByException */) {}
MethodEntry(PtThread,PtMethod)379     virtual void MethodEntry(PtThread /* thread */, PtMethod /* method */) {}
380 
MethodExit(PtThread,PtMethod,bool,PtValue)381     virtual void MethodExit(PtThread /* thread */, PtMethod /* method */, bool /* wasPoppedByException */,
382                             PtValue /* returnValue */)
383     {
384     }
PropertyAccess(PtThread,const PtLocation &,PtObject,PtProperty)385     virtual void PropertyAccess(PtThread /* thread */, const PtLocation & /* location */, PtObject /* object */,
386                                 PtProperty /* property */)
387     {
388     }
PropertyModification(PtThread,const PtLocation &,PtObject,PtProperty,PtValue)389     virtual void PropertyModification(PtThread /* thread */, const PtLocation & /* location */, PtObject /* object */,
390                                       PtProperty /* property */, PtValue /* newValue */)
391     {
392     }
MonitorWait(PtThread,PtObject,int64_t)393     virtual void MonitorWait(PtThread /* thread */, PtObject /* object */, int64_t /* timeout */) {}
MonitorWaited(PtThread,PtObject,bool)394     virtual void MonitorWaited(PtThread /* thread */, PtObject /* object */, bool /* timedOut */) {}
MonitorContendedEnter(PtThread,PtObject)395     virtual void MonitorContendedEnter(PtThread /* thread */, PtObject /* object */) {}
MonitorContendedEntered(PtThread,PtObject)396     virtual void MonitorContendedEntered(PtThread /* thread */, PtObject /* object */) {}
ObjectAlloc(PtClass,PtObject,PtThread,size_t)397     virtual void ObjectAlloc(PtClass /* klass */, PtObject /* object */, PtThread /* thread */, size_t /* size */) {}
SingleStep(PtThread,const PtLocation &)398     virtual void SingleStep(PtThread /* thread */, const PtLocation & /* location */) {}
ClassLoad(PtThread,PtClass)399     virtual void ClassLoad(PtThread /* thread */, PtClass /* klass */) {}
ClassPrepare(PtThread,PtClass)400     virtual void ClassPrepare(PtThread /* thread */, PtClass /* klass */) {}
401 
402     // NOLINTNEXTLINE(performance-unnecessary-value-param)
ExceptionRevoked(ExceptionWrapper,ExceptionID)403     virtual void ExceptionRevoked(ExceptionWrapper /* reason */, ExceptionID /* exceptionId */) {}
404 
405     // NOLINTNEXTLINE(performance-unnecessary-value-param)
ExecutionContextCreated(ExecutionContextWrapper)406     virtual void ExecutionContextCreated(ExecutionContextWrapper /* context */) {}
407 
408     // NOLINTNEXTLINE(performance-unnecessary-value-param)
ExecutionContextDestroyed(ExecutionContextWrapper)409     virtual void ExecutionContextDestroyed(ExecutionContextWrapper /* context */) {}
410 
ExecutionContextsCleared()411     virtual void ExecutionContextsCleared() {}
412 
InspectRequested(PtObject,PtObject)413     virtual void InspectRequested(PtObject /* object */, PtObject /* hints */) {}
414 
415     // * * * * *
416     // Deprecated hooks end
417     // * * * * *
418 
419     virtual ~PtHooks() = default;
420 
421     NO_COPY_SEMANTIC(PtHooks);
422     NO_MOVE_SEMANTIC(PtHooks);
423 };
424 
425 class DebugInterface {
426 public:
427     DebugInterface() = default;
428 
429     /**
430      * @brief Register debug hooks in the runtime
431      * @param hooks Pointer to object that implements PtHooks interface
432      * @return Error if any errors occur
433      */
434     virtual std::optional<Error> RegisterHooks(PtHooks *hooks) = 0;
435 
436     /**
437      * @brief Unregister debug hooks in the runtime
438      * @return Error if any errors occur
439      */
440     virtual std::optional<Error> UnregisterHooks() = 0;
441 
442     /**
443      * @brief Enable all debug hooks in the runtime
444      * @return Error if any errors occur
445      */
446     virtual std::optional<Error> EnableAllGlobalHook() = 0;
447 
448     /**
449      * @brief Disable all debug hooks in the runtime
450      * @return Error if any errors occur
451      */
452     virtual std::optional<Error> DisableAllGlobalHook() = 0;
453 
454     /**
455      * @brief Set notification to hook (enable/disable).
456      * @param thread If thread is NONE, the notification is enabled or disabled globally
457      * @param enable Enable or disable notifications (true - enable, false - disable)
458      * @param hook_type Type of hook that must be enabled or disabled
459      * @return Error if any errors occur
460      */
461     virtual std::optional<Error> SetNotification(PtThread thread, bool enable, PtHookType hookType) = 0;
462 
463     /**
464      * @brief Set breakpoint to @param location
465      * @param location Breakpoint location
466      * @return Error if any errors occur
467      */
468     virtual std::optional<Error> SetBreakpoint(const PtLocation &location) = 0;
469 
470     /**
471      * @brief Remove breakpoint from @param location
472      * @param location Breakpoint location
473      * @return Error if any errors occur
474      */
475     virtual std::optional<Error> RemoveBreakpoint(const PtLocation &location) = 0;
476 
477     /**
478      * @brief Get Frame
479      * @param thread Identifier of the thread
480      * @return Frame object that implements PtFrame or Error if any errors occur
481      */
482     virtual Expected<std::unique_ptr<PtFrame>, Error> GetCurrentFrame(PtThread thread) const = 0;
483 
484     /**
485      * @brief Enumerates managed frames in the thread @param threadId
486      * @param thread Identifier of the thread
487      * @param callback Callback that is called for each frame. Should return true to continue and false to stop
488      * enumerating
489      * @return Error if any errors occur
490      */
491     virtual std::optional<Error> EnumerateFrames(PtThread thread,
492                                                  std::function<bool(const PtFrame &)> callback) const = 0;
493 
494     /**
495      * @brief Suspend thread
496      * @param thread Identifier of the thread
497      * @return Error if any errors occur
498      */
499     virtual std::optional<Error> SuspendThread(PtThread thread) const = 0;
500 
501     /**
502      * @brief Resume thread
503      * @param thread Identifier of the thread
504      * @return Error if any errors occur
505      */
506     virtual std::optional<Error> ResumeThread(PtThread thread) const = 0;
507 
508     virtual ~DebugInterface() = default;
509 
510     virtual PtLangExt *GetLangExtension() const = 0;
511 
512     virtual Expected<PtMethod, Error> GetPtMethod(const PtLocation &location) const = 0;
513 
514     virtual std::optional<Error> GetThreadList(PandaVector<PtThread> *threadList) const = 0;
515 
SetVariable(PtThread,uint32_t,int32_t,const VRegValue &)516     virtual std::optional<Error> SetVariable(PtThread /* thread */, uint32_t /* frameDepth */, int32_t /* regNumber */,
517                                              const VRegValue & /* value */) const
518     {
519         return {};
520     }
521 
GetVariable(PtThread,uint32_t,int32_t,VRegValue *)522     virtual std::optional<Error> GetVariable(PtThread /* thread */, uint32_t /* frameDepth */, int32_t /* regNumber */,
523                                              VRegValue * /* value */) const
524     {
525         return {};
526     }
527 
528     virtual std::optional<Error> GetProperty(PtObject thisObject, PtProperty property, PtValue *value) const = 0;
529 
530     virtual std::optional<Error> SetProperty(PtObject thisObject, PtProperty property, const PtValue &value) const = 0;
531 
532     virtual std::optional<Error> EvaluateExpression(PtThread thread, uint32_t frameNumber, ExpressionWrapper expr,
533                                                     PtValue *result) const = 0;
534 
535     virtual std::optional<Error> GetThreadInfo(PtThread thread, ThreadInfo *infoPtr) const = 0;
536 
537     virtual std::optional<Error> RestartFrame(PtThread thread, uint32_t frameNumber) const = 0;
538 
539     virtual std::optional<Error> SetAsyncCallStackDepth(uint32_t maxDepth) const = 0;
540 
541     virtual std::optional<Error> AwaitPromise(PtObject promiseObject, PtValue *result) const = 0;
542 
543     virtual std::optional<Error> CallFunctionOn(PtObject object, PtMethod method, const PandaVector<PtValue> &arguments,
544                                                 PtValue *result) const = 0;
545 
546     virtual std::optional<Error> GetProperties(uint32_t *countPtr, char ***propertyPtr) const = 0;
547 
548     virtual std::optional<Error> NotifyFramePop(PtThread thread, uint32_t depth) const = 0;
549 
GetThisVariableByFrame(PtThread,uint32_t,ObjectHeader **)550     virtual std::optional<Error> GetThisVariableByFrame(PtThread /* thread */, uint32_t /* frameDepth */,
551                                                         ObjectHeader ** /* this_ptr */)
552     {
553         return {};
554     }
555 
SetPropertyAccessWatch(BaseClass *,PtProperty)556     virtual std::optional<Error> SetPropertyAccessWatch(BaseClass * /* klass */, PtProperty /* property */)
557     {
558         return {};
559     }
560 
ClearPropertyAccessWatch(BaseClass *,PtProperty)561     virtual std::optional<Error> ClearPropertyAccessWatch(BaseClass * /* klass */, PtProperty /* property */)
562     {
563         return {};
564     }
565 
SetPropertyModificationWatch(BaseClass *,PtProperty)566     virtual std::optional<Error> SetPropertyModificationWatch(BaseClass * /* klass */, PtProperty /* property */)
567     {
568         return {};
569     }
570 
ClearPropertyModificationWatch(BaseClass *,PtProperty)571     virtual std::optional<Error> ClearPropertyModificationWatch(BaseClass * /* klass */, PtProperty /* property */)
572     {
573         return {};
574     }
575 
576     // * * * * *
577     // Deprecated API
578     // * * * * *
579     virtual std::optional<Error> GetThisVariableByFrame(PtThread thread, uint32_t frameDepth, PtValue *value) = 0;
580     virtual std::optional<Error> SetPropertyAccessWatch(PtClass klass, PtProperty property) = 0;
581     virtual std::optional<Error> ClearPropertyAccessWatch(PtClass klass, PtProperty property) = 0;
582     virtual std::optional<Error> SetPropertyModificationWatch(PtClass klass, PtProperty property) = 0;
583     virtual std::optional<Error> ClearPropertyModificationWatch(PtClass klass, PtProperty property) = 0;
584     virtual std::optional<Error> RetransformClasses(int classCount, const PtClass *classes) const = 0;
585     virtual std::optional<Error> RedefineClasses(int classCount, const PandaClassDefinition *classes) const = 0;
586     virtual std::optional<Error> SetVariable(PtThread thread, uint32_t frameDepth, int32_t regNumber,
587                                              const PtValue &value) const = 0;
588     virtual std::optional<Error> GetVariable(PtThread thread, uint32_t frameDepth, int32_t regNumber,
589                                              PtValue *value) const = 0;
590 
591     // * * * * *
592     // Deprecated API ends
593     // * * * * *
594 
595     NO_COPY_SEMANTIC(DebugInterface);
596     NO_MOVE_SEMANTIC(DebugInterface);
597 };
598 }  // namespace ark::tooling
599 
600 #endif  // PANDA_RUNTIME_DEBUG_DEBUG_INTERFACE_H
601