1 /** 2 * Copyright (c) 2022-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 16 #ifndef PANDA_TOOLING_INSPECTOR_DEBUGGABLE_THREAD_H 17 #define PANDA_TOOLING_INSPECTOR_DEBUGGABLE_THREAD_H 18 19 #include "runtime/tooling/debugger.h" 20 #include "runtime/tooling/inspector/object_repository.h" 21 #include "runtime/tooling/inspector/thread_state.h" 22 #include "runtime/tooling/inspector/types/numeric_id.h" 23 #include "runtime/tooling/inspector/types/pause_on_exceptions_state.h" 24 25 namespace ark::tooling::inspector { 26 class DebuggableThread final { 27 public: 28 struct SuspensionCallbacks final { 29 std::function<void(ObjectRepository &, const std::vector<BreakpointId> &, ObjectHeader *)> preSuspend; 30 std::function<void(ObjectRepository &, const std::vector<BreakpointId> &, ObjectHeader *)> postSuspend; 31 std::function<void()> preWaitSuspension; 32 std::function<void()> postWaitSuspension; 33 std::function<void()> preResume; 34 std::function<void()> postResume; 35 }; 36 37 public: 38 DebuggableThread(ManagedThread *thread, SuspensionCallbacks &&callbacks); 39 ~DebuggableThread() = default; 40 41 NO_COPY_SEMANTIC(DebuggableThread); 42 NO_MOVE_SEMANTIC(DebuggableThread); 43 44 /// The following methods should be called on the server thread 45 46 // Resets the state on a new connection 47 void Reset(); 48 49 // Tells a newly created thread to pause on the next step 50 void BreakOnStart(); 51 52 // Continues execution of a paused thread 53 void Continue(); 54 55 // Continues execution of a paused thread until it reaches one of the locations 56 void ContinueTo(std::unordered_set<PtLocation, HashLocation> locations); 57 58 // Tells a paused thread to perform a step into 59 void StepInto(std::unordered_set<PtLocation, HashLocation> locations); 60 61 // Tells a paused thread to perform a step over 62 void StepOver(std::unordered_set<PtLocation, HashLocation> locations); 63 64 // Tells a paused thread to perform a step out 65 void StepOut(); 66 67 // Makes a paused thread to resume and suspend back (does nothing for running threads). 68 // Used to notify about thread's state when processing `runIfWaitingForDebugger` 69 void Touch(); 70 71 // Tells a running thread to pause on the next step 72 void Pause(); 73 74 // Enables or disables stops on breakpoints 75 void SetBreakpointsActive(bool active); 76 77 // Sets a breakpoint on the locations. Returns the breakpoint ID 78 BreakpointId SetBreakpoint(const std::vector<PtLocation> &locations); 79 80 // Removes the breakpoint by ID 81 void RemoveBreakpoint(BreakpointId id); 82 83 // Tells when stops should be made on exceptions 84 void SetPauseOnExceptions(PauseOnExceptionsState state); 85 86 // Executes a request to object repository on a paused thread (does nothing for running threads) 87 bool RequestToObjectRepository(std::function<void(ObjectRepository &)> request); 88 89 /// The following methods should be called on an application thread 90 91 // Notification that an exception was thrown. Pauses the thread if necessary 92 void OnException(bool uncaught); 93 94 // Notification that an "interesting" frame was popped 95 void OnFramePop(); 96 97 // Notification that a new frame was pushed. Returns true if we want to be notified about the frame is popped 98 // (i.e. the frame is "interesting"), false otherwise 99 bool OnMethodEntry(); 100 101 // Notification that a next step will be performed. Pauses the thread if necessary 102 void OnSingleStep(const PtLocation &location); 103 104 // Notification that a call to console was performed. Returns its arguments presented as remote objects 105 std::vector<RemoteObject> OnConsoleCall(const PandaVector<TypedValue> &arguments); 106 107 private: 108 // Suspends a paused thread. Should be called on an application thread 109 void Suspend(ObjectRepository &objectRepository, const std::vector<BreakpointId> &hitBreakpoints, 110 ObjectHeader *exception) REQUIRES(mutex_); 111 112 // Marks a paused thread as not suspended. Should be called on the server thread 113 void Resume() REQUIRES(mutex_); 114 115 ManagedThread *thread_; 116 SuspensionCallbacks callbacks_; 117 118 os::memory::Mutex mutex_; 119 ThreadState state_ GUARDED_BY(mutex_); GUARDED_BY(mutex_)120 bool suspended_ GUARDED_BY(mutex_) {false}; 121 std::optional<std::function<void(ObjectRepository &)>> request_ GUARDED_BY(mutex_); 122 os::memory::ConditionVariable requestDone_ GUARDED_BY(mutex_); 123 }; 124 } // namespace ark::tooling::inspector 125 126 #endif // PANDA_TOOLING_INSPECTOR_DEBUGGABLE_THREAD_H 127