1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2023 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#ifndef STACK_UTIL_H 16800b99b8Sopenharmony_ci#define STACK_UTIL_H 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <cstdio> 19800b99b8Sopenharmony_ci#include <csignal> 20800b99b8Sopenharmony_ci#include <cstring> 21800b99b8Sopenharmony_ci#include <string> 22800b99b8Sopenharmony_ci#include <pthread.h> 23800b99b8Sopenharmony_ci#include "dfx_define.h" 24800b99b8Sopenharmony_ci 25800b99b8Sopenharmony_cinamespace OHOS { 26800b99b8Sopenharmony_cinamespace HiviewDFX { 27800b99b8Sopenharmony_cinamespace { 28800b99b8Sopenharmony_cistatic uintptr_t g_stackMapStart = 0; 29800b99b8Sopenharmony_cistatic uintptr_t g_stackMapEnd = 0; 30800b99b8Sopenharmony_cistatic uintptr_t g_arkMapStart = 0; 31800b99b8Sopenharmony_cistatic uintptr_t g_arkMapEnd = 0; 32800b99b8Sopenharmony_ci 33800b99b8Sopenharmony_cistatic bool ParseSelfMaps() 34800b99b8Sopenharmony_ci{ 35800b99b8Sopenharmony_ci FILE *fp = fopen(PROC_SELF_MAPS_PATH, "r"); 36800b99b8Sopenharmony_ci if (fp == NULL) { 37800b99b8Sopenharmony_ci return false; 38800b99b8Sopenharmony_ci } 39800b99b8Sopenharmony_ci bool ret = false; 40800b99b8Sopenharmony_ci char mapInfo[256] = {0}; // 256: map info size 41800b99b8Sopenharmony_ci int pos = 0; 42800b99b8Sopenharmony_ci uint64_t begin = 0; 43800b99b8Sopenharmony_ci uint64_t end = 0; 44800b99b8Sopenharmony_ci uint64_t offset = 0; 45800b99b8Sopenharmony_ci char perms[5] = {0}; // 5:rwxp 46800b99b8Sopenharmony_ci while (fgets(mapInfo, sizeof(mapInfo), fp) != NULL) { 47800b99b8Sopenharmony_ci if (strstr(mapInfo, "[stack]") != NULL) { 48800b99b8Sopenharmony_ci if (sscanf_s(mapInfo, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %*x:%*x %*d%n", &begin, &end, 49800b99b8Sopenharmony_ci &perms, sizeof(perms), &offset, &pos) != 4) { // 4:scan size 50800b99b8Sopenharmony_ci continue; 51800b99b8Sopenharmony_ci } 52800b99b8Sopenharmony_ci g_stackMapStart = static_cast<uintptr_t>(begin); 53800b99b8Sopenharmony_ci g_stackMapEnd = static_cast<uintptr_t>(end); 54800b99b8Sopenharmony_ci ret = true; 55800b99b8Sopenharmony_ci } 56800b99b8Sopenharmony_ci 57800b99b8Sopenharmony_ci if (strstr(mapInfo, "stub.an") != NULL) { 58800b99b8Sopenharmony_ci if (sscanf_s(mapInfo, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %*x:%*x %*d%n", &begin, &end, 59800b99b8Sopenharmony_ci &perms, sizeof(perms), &offset, &pos) != 4) { // 4:scan size 60800b99b8Sopenharmony_ci continue; 61800b99b8Sopenharmony_ci } 62800b99b8Sopenharmony_ci g_arkMapStart = static_cast<uintptr_t>(begin); 63800b99b8Sopenharmony_ci g_arkMapEnd = static_cast<uintptr_t>(end); 64800b99b8Sopenharmony_ci ret = true; 65800b99b8Sopenharmony_ci } 66800b99b8Sopenharmony_ci } 67800b99b8Sopenharmony_ci (void)fclose(fp); 68800b99b8Sopenharmony_ci return ret; 69800b99b8Sopenharmony_ci}; 70800b99b8Sopenharmony_ci} 71800b99b8Sopenharmony_ci 72800b99b8Sopenharmony_ciAT_UNUSED inline bool GetArkStackRange(uintptr_t& start, uintptr_t& end) 73800b99b8Sopenharmony_ci{ 74800b99b8Sopenharmony_ci if (g_arkMapStart == 0 || g_arkMapEnd == 0) { 75800b99b8Sopenharmony_ci ParseSelfMaps(); 76800b99b8Sopenharmony_ci } 77800b99b8Sopenharmony_ci start = g_arkMapStart; 78800b99b8Sopenharmony_ci end = g_arkMapEnd; 79800b99b8Sopenharmony_ci return (g_arkMapStart != 0 && g_arkMapEnd != 0); 80800b99b8Sopenharmony_ci} 81800b99b8Sopenharmony_ci 82800b99b8Sopenharmony_ciAT_UNUSED inline bool GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) 83800b99b8Sopenharmony_ci{ 84800b99b8Sopenharmony_ci if (g_stackMapStart == 0 || g_stackMapEnd == 0) { 85800b99b8Sopenharmony_ci ParseSelfMaps(); 86800b99b8Sopenharmony_ci } 87800b99b8Sopenharmony_ci stackBottom = g_stackMapStart; 88800b99b8Sopenharmony_ci stackTop = g_stackMapEnd; 89800b99b8Sopenharmony_ci return (g_stackMapStart != 0 && g_stackMapEnd != 0); 90800b99b8Sopenharmony_ci} 91800b99b8Sopenharmony_ci 92800b99b8Sopenharmony_ciAT_UNUSED static bool GetSelfStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) 93800b99b8Sopenharmony_ci{ 94800b99b8Sopenharmony_ci bool ret = false; 95800b99b8Sopenharmony_ci pthread_attr_t tattr; 96800b99b8Sopenharmony_ci void *base = nullptr; 97800b99b8Sopenharmony_ci size_t size = 0; 98800b99b8Sopenharmony_ci if (pthread_getattr_np(pthread_self(), &tattr) != 0) { 99800b99b8Sopenharmony_ci return ret; 100800b99b8Sopenharmony_ci } 101800b99b8Sopenharmony_ci if (pthread_attr_getstack(&tattr, &base, &size) == 0) { 102800b99b8Sopenharmony_ci stackBottom = reinterpret_cast<uintptr_t>(base); 103800b99b8Sopenharmony_ci stackTop = reinterpret_cast<uintptr_t>(base) + size; 104800b99b8Sopenharmony_ci ret = true; 105800b99b8Sopenharmony_ci } 106800b99b8Sopenharmony_ci pthread_attr_destroy(&tattr); 107800b99b8Sopenharmony_ci return ret; 108800b99b8Sopenharmony_ci} 109800b99b8Sopenharmony_ci 110800b99b8Sopenharmony_ciAT_UNUSED static bool GetSigAltStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) 111800b99b8Sopenharmony_ci{ 112800b99b8Sopenharmony_ci bool ret = false; 113800b99b8Sopenharmony_ci stack_t altStack; 114800b99b8Sopenharmony_ci if (sigaltstack(nullptr, &altStack) != -1) { 115800b99b8Sopenharmony_ci if ((static_cast<uint32_t>(altStack.ss_flags) & SS_ONSTACK) != 0) { 116800b99b8Sopenharmony_ci stackBottom = reinterpret_cast<uintptr_t>(altStack.ss_sp); 117800b99b8Sopenharmony_ci stackTop = reinterpret_cast<uintptr_t>(altStack.ss_sp) + altStack.ss_size; 118800b99b8Sopenharmony_ci ret = true; 119800b99b8Sopenharmony_ci } 120800b99b8Sopenharmony_ci } 121800b99b8Sopenharmony_ci return ret; 122800b99b8Sopenharmony_ci} 123800b99b8Sopenharmony_ci} // namespace HiviewDFX 124800b99b8Sopenharmony_ci} // namespace OHOS 125800b99b8Sopenharmony_ci#endif 126