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 namespace OHOS { 26 namespace HiviewDFX { 27 enum ThreadContextStatus { 28 CONTEXT_UNUSED = -1, 29 CONTEXT_READY = -2, 30 }; 31 32 struct ThreadContext { 33 std::atomic<int32_t> tid {ThreadContextStatus::CONTEXT_UNUSED}; 34 // for protecting ctx, shared between threads 35 std::mutex lock; 36 // the thread should be suspended while unwinding 37 // we are blocked in the signal handler of target thread 38 std::condition_variable cv; 39 // store unwind context 40 unw_context_t* ctx {nullptr}; ~ThreadContextThreadContext41 ~ThreadContext() 42 { 43 std::unique_lock<std::mutex> mlock(lock); 44 if (ctx != nullptr) { 45 delete ctx; 46 ctx = nullptr; 47 } 48 }; 49 }; 50 51 class BacktraceLocalContext { 52 public: 53 static BacktraceLocalContext& GetInstance(); 54 ~BacktraceLocalContext() = default; 55 // ThreadContext is released after calling ReleaseThread 56 std::shared_ptr<ThreadContext> GetThreadContext(int32_t tid); 57 void ReleaseThread(int32_t tid); 58 void CleanUp(); 59 private: 60 BacktraceLocalContext() = default; 61 DISALLOW_COPY_AND_MOVE(BacktraceLocalContext); 62 static void CopyContextAndWaitTimeout(int sig, siginfo_t *si, void *context); 63 bool InstallSigHandler(); 64 void UninstallSigHandler(); 65 bool SignalRequestThread(int32_t tid, ThreadContext* ctx); 66 }; 67 } // namespace HiviewDFX 68 } // namespace OHOS 69 #endif 70