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_USING = -2, 30 CONTEXT_READY = -3, 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 class BacktraceLocalContext { 51 public: 52 static BacktraceLocalContext& GetInstance(); 53 ~BacktraceLocalContext() = default; 54 // ThreadContext is released after calling ReleaseThread 55 std::shared_ptr<ThreadContext> GetThreadContext(int32_t tid); 56 void ReleaseThread(int32_t tid); 57 void CleanUp(); 58 private: 59 BacktraceLocalContext() = default; 60 DISALLOW_COPY_AND_MOVE(BacktraceLocalContext); 61 static void CopyContextAndWaitTimeout(int sig, siginfo_t *si, void *context); 62 bool InstallSigHandler(); 63 void UninstallSigHandler(); 64 bool SignalRequestThread(int32_t tid, ThreadContext* ctx); 65 }; 66 } // namespace HiviewDFX 67 } // namespace OHOS 68 #endif 69