1 /** 2 * Copyright (c) 2022-2025 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_INSPECTOR_H 17 #define PANDA_TOOLING_INSPECTOR_INSPECTOR_H 18 19 #include <atomic> 20 #include <cstddef> 21 #include <optional> 22 #include <set> 23 #include <string_view> 24 #include <thread> 25 #include <vector> 26 27 #include "include/tooling/debug_interface.h" 28 #include "include/tooling/pt_thread.h" 29 30 #include "debugger/breakpoint_storage.h" 31 #include "debugger/debug_info_cache.h" 32 #include "debugger/debuggable_thread.h" 33 #include "debugger/object_repository.h" 34 35 #include "common.h" 36 #include "inspector_server.h" 37 #include "runtime/tooling/tools.h" 38 #include "os/mutex.h" 39 #include "types/evaluation_result.h" 40 #include "types/numeric_id.h" 41 #include "types/pause_on_exceptions_state.h" 42 #include "types/profile_result.h" 43 #include "types/property_descriptor.h" 44 #include "types/remote_object.h" 45 46 namespace ark::tooling { 47 class DebugInterface; 48 49 namespace inspector { 50 // NOLINTNEXTLINE(fuchsia-virtual-inheritance) 51 class Server; 52 53 class Inspector final : public PtHooks { 54 public: 55 Inspector(Server &server, DebugInterface &debugger, bool breakOnStart); 56 ~Inspector() override; 57 58 NO_COPY_SEMANTIC(Inspector); 59 NO_MOVE_SEMANTIC(Inspector); 60 61 void ConsoleCall(PtThread thread, ConsoleCallType type, uint64_t timestamp, 62 const PandaVector<TypedValue> &arguments) override; 63 // CC-OFFNXT(G.FUN.01-CPP) Decreasing the number of arguments will decrease the clarity of the code. 64 void Exception(PtThread thread, Method *method, const PtLocation &location, ObjectHeader *exception, 65 Method *catchMethod, const PtLocation &catchLocation) override; 66 void FramePop(PtThread thread, Method *method, bool wasPoppedByException) override; 67 void MethodEntry(PtThread thread, Method *method) override; 68 void LoadModule(std::string_view fileName) override; 69 void SingleStep(PtThread thread, Method *method, const PtLocation &location) override; 70 void ThreadStart(PtThread thread) override; 71 void ThreadEnd(PtThread thread) override; 72 void VmDeath() override; 73 74 void Run(const std::string& msg); 75 void Stop(); 76 void WaitForDebugger(); 77 78 private: 79 void RuntimeEnable(PtThread thread); 80 81 void RunIfWaitingForDebugger(PtThread thread); 82 83 void Pause(PtThread thread); 84 void Continue(PtThread thread); 85 void Disable(PtThread thread); 86 void ClientDisconnect(PtThread thread); 87 void SetAsyncCallStackDepth(PtThread thread); 88 void SetBlackboxPatterns(PtThread thread); 89 void SmartStepInto(PtThread thread); 90 void DropFrame(PtThread thread); 91 void SetNativeRange(PtThread thread); 92 void ReplyNativeCalling(PtThread thread); 93 void SetBreakpointsActive(PtThread thread, bool active); 94 void SetSkipAllPauses(PtThread thread, bool skip); 95 void SetMixedDebugEnabled(PtThread thread, bool mixedDebugEnabled); 96 std::set<size_t> GetPossibleBreakpoints(std::string_view sourceFile, size_t startLine, size_t endLine, 97 bool restrictToFunction); 98 std::optional<BreakpointId> SetBreakpoint(PtThread thread, SourceFileFilter &&sourceFilesFilter, size_t lineNumber, 99 std::set<std::string_view> &sourceFiles, const std::string *condition); 100 void RemoveBreakpoint(PtThread thread, BreakpointId id); 101 void RemoveBreakpoints(PtThread thread, const SourceFileFilter &sourceFilesFilter); 102 103 void SetPauseOnExceptions(PtThread thread, PauseOnExceptionsState state); 104 105 void StepInto(PtThread thread); 106 void StepOver(PtThread thread); 107 void StepOut(PtThread thread); 108 void ContinueToLocation(PtThread thread, std::string_view sourceFile, size_t lineNumber); 109 110 void RestartFrame(PtThread thread, FrameId frameId); 111 112 std::vector<PropertyDescriptor> GetProperties(PtThread thread, RemoteObjectId objectId, bool generatePreview); 113 std::string GetSourceCode(std::string_view sourceFile); 114 115 void DebuggableThreadPostSuspend(PtThread thread, ObjectRepository &objectRepository, 116 const std::vector<BreakpointId> &hitBreakpoints, ObjectHeader *exception, 117 PauseReason pauseReason); 118 119 void NotifyExecutionEnded(); 120 121 Expected<EvaluationResult, std::string> Evaluate(PtThread thread, const std::string &bytecodeBase64, 122 size_t frameNumber); 123 void ProfilerSetSamplingInterval(int32_t interval); 124 Expected<bool, std::string> ProfilerStart(); 125 Expected<Profile, std::string> ProfilerStop(); 126 CheckVmDead()127 ALWAYS_INLINE bool CheckVmDead() REQUIRES_SHARED(vmDeathLock_) 128 { 129 if (UNLIKELY(isVmDead_)) { 130 LOG(WARNING, DEBUGGER) << "Killing inspector server after VM death"; 131 inspectorServer_.Kill(); 132 return true; 133 } 134 return false; 135 } 136 137 /// @brief Get verbose information about the raised exception. 138 std::optional<ExceptionDetails> CreateExceptionDetails(PtThread thread, RemoteObject &&exception); 139 140 size_t GetNewExceptionId(); 141 142 DebuggableThread *GetDebuggableThread(PtThread thread); 143 144 void RegisterMethodHandlers(); 145 146 void ResolveBreakpoints(const panda_file::File &file, const panda_file::DebugInfoExtractor *debugInfoCache); 147 void CollectModules(); 148 void DebuggerEnable(); 149 void SourceNameInsert(const panda_file::DebugInfoExtractor *extractor); 150 151 private: 152 bool breakOnStart_; 153 154 os::memory::RWLock debuggerEventsLock_; 155 bool connecting_ {false}; // Should be accessed only from the server thread 156 157 InspectorServer inspectorServer_; // NOLINT(misc-non-private-member-variables-in-classes) 158 DebugInterface &debugger_; 159 DebugInfoCache debugInfoCache_; 160 std::map<PtThread, DebuggableThread> threads_; 161 162 std::atomic_size_t currentExceptionId_ {0}; 163 164 os::memory::RWLock vmDeathLock_; GUARDED_BY(vmDeathLock_)165 bool isVmDead_ GUARDED_BY(vmDeathLock_) {false}; 166 167 BreakpointStorage breakpointStorage_; 168 169 std::thread serverThread_; 170 uint32_t samplingInterval_ {0}; 171 std::shared_ptr<sampler::SamplesRecord> profileInfoBuffer_ = nullptr; 172 bool cpuProfilerStarted_ = false; 173 os::memory::Mutex waitDebuggerMutex_; 174 os::memory::ConditionVariable waitDebuggerCond_ GUARDED_BY(waitDebuggerMutex_); 175 }; 176 } // namespace inspector 177 } // namespace ark::tooling 178 179 #endif // PANDA_TOOLING_INSPECTOR_INSPECTOR_H 180