/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "dfx_define.h" #include "stack_utils.h" namespace OHOS { namespace HiviewDFX { StackUtils::StackUtils() { ParseSelfMaps(); } StackUtils& StackUtils::Instance() { static StackUtils inst; return inst; } bool StackUtils::GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) const { if (!mainStack_.IsValid()) { return false; } stackBottom = mainStack_.start; stackTop = mainStack_.end; return true; } bool StackUtils::GetArkStackRange(uintptr_t& start, uintptr_t& end) const { if (!arkCode_.IsValid()) { return false; } start = arkCode_.start; end = arkCode_.end; return true; } bool StackUtils::GetSelfStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) { pthread_attr_t tattr; if (pthread_getattr_np(pthread_self(), &tattr) != 0) { return false; } void *base = nullptr; size_t size = 0; bool ret = false; if (pthread_attr_getstack(&tattr, &base, &size) == 0) { stackBottom = reinterpret_cast(base); stackTop = reinterpret_cast(base) + size; ret = true; } pthread_attr_destroy(&tattr); return ret; } void StackUtils::ParseSelfMaps() { std::unique_ptr fp(fopen(PROC_SELF_MAPS_PATH, "r"), [](FILE* fp) { if (fp != nullptr) { fclose(fp); } }); if (fp == nullptr) { return; } auto parser = [] (const char *mapInfo, bool checkExec, MapRange &range) { uint64_t begin = 0; uint64_t end = 0; uint64_t offset = 0; char perms[5] = {0}; // 5:rwxp int pos = 0; if (sscanf_s(mapInfo, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %*x:%*x %*d%n", &begin, &end, &perms, sizeof(perms), &offset, &pos) != 4) { // 4:scan size return; } if (checkExec && strcmp(perms, "r-xp") != 0) { return; } range.start = begin; range.end = end; }; char mapInfo[256] = {0}; // 256: map info size while (fgets(mapInfo, sizeof(mapInfo), fp.get()) != nullptr) { if (mainStack_.IsValid() && arkCode_.IsValid()) { return; } if (!mainStack_.IsValid() && (strstr(mapInfo, "[stack]") != nullptr)) { parser(mapInfo, false, mainStack_); continue; } if (!arkCode_.IsValid() && strstr(mapInfo, "stub.an") != nullptr) { parser(mapInfo, true, arkCode_); } } } } // namespace HiviewDFX } // namespace OHOS