1 /* 2 * Copyright (c) 2024 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 THREAD_CONTEXT_H 17 #define THREAD_CONTEXT_H 18 19 #include <atomic> 20 #include <cstdint> 21 #include <condition_variable> 22 #include <csignal> 23 #include <mutex> 24 #include <nocopyable.h> 25 #include <string> 26 27 #include "dfx_define.h" 28 29 namespace OHOS { 30 namespace HiviewDFX { 31 enum ThreadContextStatus : int32_t { 32 CONTEXT_UNUSED = -1, 33 CONTEXT_READY = -2, 34 }; 35 36 struct ThreadContext { 37 std::atomic<int32_t> tid {ThreadContextStatus::CONTEXT_UNUSED}; 38 // for protecting ctx, shared between threads 39 std::mutex mtx; 40 // the thread should be suspended while unwinding 41 // blocked in the signal handler of target thread 42 std::condition_variable cv; 43 // store unwind context 44 ucontext_t* ctx {nullptr}; 45 // stack range 46 uintptr_t stackBottom; 47 uintptr_t stackTop; 48 #if defined(__aarch64__) 49 // unwind in signal handler by fp 50 uintptr_t pcs[DEFAULT_MAX_LOCAL_FRAME_NUM] {0}; 51 #endif 52 std::atomic<size_t> frameSz {0}; 53 // first stack pointer 54 uintptr_t firstFrameSp; 55 ~ThreadContextThreadContext56 ~ThreadContext() 57 { 58 std::unique_lock<std::mutex> lock(mtx); 59 if (ctx != nullptr) { 60 delete ctx; 61 ctx = nullptr; 62 } 63 }; 64 }; 65 66 class LocalThreadContext { 67 public: 68 static LocalThreadContext& GetInstance(); 69 70 bool GetStackRange(int32_t tid, uintptr_t& stackBottom, uintptr_t& stackTop); 71 std::shared_ptr<ThreadContext> CollectThreadContext(int32_t tid); 72 std::shared_ptr<ThreadContext> GetThreadContext(int32_t tid); 73 void ReleaseThread(int32_t tid); 74 void CleanUp(); 75 76 private: 77 LocalThreadContext() = default; 78 DISALLOW_COPY_AND_MOVE(LocalThreadContext); 79 80 static void CopyContextAndWaitTimeout(int sig, siginfo_t *si, void *context); 81 bool SignalRequestThread(int32_t tid, ThreadContext* ctx); 82 void InitSignalHandler(); 83 84 private: 85 std::mutex localMutex_; 86 }; 87 } // namespace Dfx 88 } // namespace OHOS 89 #endif 90