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