1 /* 2 * Copyright (c) 2022-2023 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 BACKTRACE_LOCAL_CONTEXT_H 16 #define BACKTRACE_LOCAL_CONTEXT_H 17 18 #include <cinttypes> 19 #include <csignal> 20 #include <mutex> 21 22 #include <libunwind.h> 23 #include <nocopyable.h> 24 25 #include "dfx_define.h" 26 27 namespace OHOS { 28 namespace HiviewDFX { 29 enum ThreadContextStatus { 30 CONTEXT_UNUSED = -1, 31 CONTEXT_READY = -2, 32 }; 33 34 struct ThreadContext { 35 std::atomic<int32_t> tid {ThreadContextStatus::CONTEXT_UNUSED}; 36 // for protecting ctx, shared between threads 37 std::mutex lock; 38 // the thread should be suspended while unwinding 39 // we are blocked in the signal handler of target thread 40 std::condition_variable cv; 41 // store unwind context 42 unw_context_t* ctx {nullptr}; 43 // unwind in signal handler 44 uintptr_t pcs[DEFAULT_MAX_LOCAL_FRAME_NUM] {0}; 45 std::atomic<int32_t> frameSz {0}; ~ThreadContextThreadContext46 ~ThreadContext() 47 { 48 std::unique_lock<std::mutex> mlock(lock); 49 if (ctx != nullptr) { 50 delete ctx; 51 ctx = nullptr; 52 } 53 }; 54 }; 55 56 class BacktraceLocalContext { 57 public: 58 static BacktraceLocalContext& GetInstance(); 59 ~BacktraceLocalContext() = default; 60 // ThreadContext is released after calling ReleaseThread 61 std::shared_ptr<ThreadContext> CollectThreadContext(int32_t tid); 62 std::shared_ptr<ThreadContext> GetThreadContext(int32_t tid); 63 bool ReadUintptrSafe(uintptr_t addr, uintptr_t& value); 64 void ReleaseThread(int32_t tid); 65 void CleanUp(); 66 private: 67 BacktraceLocalContext() = default; 68 DISALLOW_COPY_AND_MOVE(BacktraceLocalContext); 69 static bool CopyContextAndWaitTimeout(int sig, siginfo_t *si, void *context); 70 bool SignalRequestThread(int32_t tid, ThreadContext* ctx); 71 bool Init(); 72 private: 73 bool init_ {false}; 74 int32_t pipe2_[PIPE_NUM_SZ] = {-1, -1}; 75 }; 76 } // namespace HiviewDFX 77 } // namespace OHOS 78 #endif 79