1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#ifndef THREAD_CONTEXT_H 17800b99b8Sopenharmony_ci#define THREAD_CONTEXT_H 18800b99b8Sopenharmony_ci 19800b99b8Sopenharmony_ci#include <atomic> 20800b99b8Sopenharmony_ci#include <cstdint> 21800b99b8Sopenharmony_ci#include <condition_variable> 22800b99b8Sopenharmony_ci#include <csignal> 23800b99b8Sopenharmony_ci#include <mutex> 24800b99b8Sopenharmony_ci#include <nocopyable.h> 25800b99b8Sopenharmony_ci#include <string> 26800b99b8Sopenharmony_ci 27800b99b8Sopenharmony_ci#include "dfx_define.h" 28800b99b8Sopenharmony_ci 29800b99b8Sopenharmony_cinamespace OHOS { 30800b99b8Sopenharmony_cinamespace HiviewDFX { 31800b99b8Sopenharmony_cienum ThreadContextStatus : int32_t { 32800b99b8Sopenharmony_ci CONTEXT_UNUSED = -1, 33800b99b8Sopenharmony_ci CONTEXT_READY = -2, 34800b99b8Sopenharmony_ci}; 35800b99b8Sopenharmony_ci 36800b99b8Sopenharmony_cistruct ThreadContext { 37800b99b8Sopenharmony_ci std::atomic<int32_t> tid {ThreadContextStatus::CONTEXT_UNUSED}; 38800b99b8Sopenharmony_ci // for protecting ctx, shared between threads 39800b99b8Sopenharmony_ci std::mutex mtx; 40800b99b8Sopenharmony_ci // the thread should be suspended while unwinding 41800b99b8Sopenharmony_ci // blocked in the signal handler of target thread 42800b99b8Sopenharmony_ci std::condition_variable cv; 43800b99b8Sopenharmony_ci // store unwind context 44800b99b8Sopenharmony_ci ucontext_t* ctx {nullptr}; 45800b99b8Sopenharmony_ci // stack range 46800b99b8Sopenharmony_ci uintptr_t stackBottom; 47800b99b8Sopenharmony_ci uintptr_t stackTop; 48800b99b8Sopenharmony_ci#if defined(__aarch64__) 49800b99b8Sopenharmony_ci // unwind in signal handler by fp 50800b99b8Sopenharmony_ci uintptr_t pcs[DEFAULT_MAX_LOCAL_FRAME_NUM] {0}; 51800b99b8Sopenharmony_ci#endif 52800b99b8Sopenharmony_ci std::atomic<size_t> frameSz {0}; 53800b99b8Sopenharmony_ci // first stack pointer 54800b99b8Sopenharmony_ci uintptr_t firstFrameSp; 55800b99b8Sopenharmony_ci 56800b99b8Sopenharmony_ci ~ThreadContext() 57800b99b8Sopenharmony_ci { 58800b99b8Sopenharmony_ci std::unique_lock<std::mutex> lock(mtx); 59800b99b8Sopenharmony_ci if (ctx != nullptr) { 60800b99b8Sopenharmony_ci delete ctx; 61800b99b8Sopenharmony_ci ctx = nullptr; 62800b99b8Sopenharmony_ci } 63800b99b8Sopenharmony_ci }; 64800b99b8Sopenharmony_ci}; 65800b99b8Sopenharmony_ci 66800b99b8Sopenharmony_ciclass LocalThreadContext { 67800b99b8Sopenharmony_cipublic: 68800b99b8Sopenharmony_ci static LocalThreadContext& GetInstance(); 69800b99b8Sopenharmony_ci 70800b99b8Sopenharmony_ci bool GetStackRange(int32_t tid, uintptr_t& stackBottom, uintptr_t& stackTop); 71800b99b8Sopenharmony_ci std::shared_ptr<ThreadContext> CollectThreadContext(int32_t tid); 72800b99b8Sopenharmony_ci std::shared_ptr<ThreadContext> GetThreadContext(int32_t tid); 73800b99b8Sopenharmony_ci void ReleaseThread(int32_t tid); 74800b99b8Sopenharmony_ci void CleanUp(); 75800b99b8Sopenharmony_ci 76800b99b8Sopenharmony_ciprivate: 77800b99b8Sopenharmony_ci LocalThreadContext() = default; 78800b99b8Sopenharmony_ci DISALLOW_COPY_AND_MOVE(LocalThreadContext); 79800b99b8Sopenharmony_ci 80800b99b8Sopenharmony_ci static void CopyContextAndWaitTimeout(int sig, siginfo_t *si, void *context); 81800b99b8Sopenharmony_ci bool SignalRequestThread(int32_t tid, ThreadContext* ctx); 82800b99b8Sopenharmony_ci void InitSignalHandler(); 83800b99b8Sopenharmony_ci 84800b99b8Sopenharmony_ciprivate: 85800b99b8Sopenharmony_ci std::mutex localMutex_; 86800b99b8Sopenharmony_ci}; 87800b99b8Sopenharmony_ci} // namespace Dfx 88800b99b8Sopenharmony_ci} // namespace OHOS 89800b99b8Sopenharmony_ci#endif 90