1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. 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 STACK_BUILDER_H 16 #define STACK_BUILDER_H 17 18 #include "hook_common.h" 19 #include "hook_record.h" 20 #include "virtual_runtime.h" 21 #include "native_hook_config.pb.h" 22 namespace OHOS::Developtools::NativeDaemon { 23 24 class StackBuilder { 25 public: 26 StackBuilder() = delete; StackBuilder(NativeHookConfig * config,std::shared_ptr<VirtualRuntime> runtime,std::mutex & mtx)27 StackBuilder(NativeHookConfig* config, std::shared_ptr<VirtualRuntime> runtime, std::mutex& mtx) 28 : hookConfig_(config), runtimeInstance_(runtime), mtx_(mtx) {}; 29 virtual ~StackBuilder() = default; PrepareUnwind(HookRecordPtr hookRecord)30 virtual void PrepareUnwind(HookRecordPtr hookRecord) {}; 31 virtual void FillIps(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) = 0; 32 virtual void FillJsSymbols(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) = 0; 33 virtual void FillNativeSymbols(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) = 0; 34 void FillStatsVirtualFrames(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord); 35 virtual bool IsRecordInfoValid(HookRecordPtr hookRecord) = 0; ReplaceErrStack(std::vector<CallFrame> & callFrames)36 virtual void ReplaceErrStack(std::vector<CallFrame>& callFrames) {}; 37 38 protected: 39 NativeHookConfig* hookConfig_{nullptr}; 40 std::shared_ptr<VirtualRuntime> runtimeInstance_{nullptr}; 41 std::mutex& mtx_; 42 }; 43 44 class FpStackBuilder : public StackBuilder { 45 public: 46 FpStackBuilder() = delete; 47 FpStackBuilder(NativeHookConfig* config, std::shared_ptr<VirtualRuntime> runtime, std::mutex& mtx); 48 void PrepareUnwind(HookRecordPtr hookRecord) override; 49 void FillIps(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) override; 50 void FillJsSymbols(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) override; 51 void FillNativeSymbols(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) override; 52 bool IsRecordInfoValid(HookRecordPtr hookRecord) override; 53 void FillJsFrame(CallFrame& jsCallFrame); 54 }; 55 56 class DwarfStackBuilder : public StackBuilder { 57 public: 58 DwarfStackBuilder() = delete; 59 DwarfStackBuilder(NativeHookConfig* config, std::shared_ptr<VirtualRuntime> runtime, std::mutex& mtx); 60 void FillIps(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) override; 61 void FillJsSymbols(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) override; 62 void FillNativeSymbols(std::vector<CallFrame>& callFrames, HookRecordPtr hookRecord) override; 63 bool IsRecordInfoValid(HookRecordPtr hookRecord) override; 64 void ReplaceErrStack(std::vector<CallFrame>& callFrames) override; 65 66 private: 67 size_t stackDepth_ = 0; 68 size_t minStackDepth_ = 0; 69 }; 70 71 class BuildStackDirector { 72 public: 73 BuildStackDirector() = delete; 74 BuildStackDirector(NativeHookConfig* config, std::shared_ptr<VirtualRuntime> runtime, std::mutex& mtx); 75 std::vector<CallFrame>& ConstructCallFrames(HookRecordPtr hookRecord); SetBuilder(std::shared_ptr<StackBuilder> builder)76 void SetBuilder(std::shared_ptr<StackBuilder> builder) 77 { 78 builder_ = builder; 79 } 80 bool IsRecordUnwindable(HookRecordPtr); 81 82 private: 83 std::shared_ptr<StackBuilder> builder_{nullptr}; 84 NativeHookConfig* hookConfig_{nullptr}; 85 std::vector<CallFrame> callFrames_; 86 }; 87 } 88 89 #endif