1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2021-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#include "dfx_frame_formatter.h"
17800b99b8Sopenharmony_ci
18800b99b8Sopenharmony_ci#include <securec.h>
19800b99b8Sopenharmony_ci
20800b99b8Sopenharmony_ci#include "dfx_define.h"
21800b99b8Sopenharmony_ci#include "dfx_log.h"
22800b99b8Sopenharmony_ci#include "dfx_maps.h"
23800b99b8Sopenharmony_ci#include "string_printf.h"
24800b99b8Sopenharmony_ci
25800b99b8Sopenharmony_cinamespace OHOS {
26800b99b8Sopenharmony_cinamespace HiviewDFX {
27800b99b8Sopenharmony_cinamespace {
28800b99b8Sopenharmony_ci#undef LOG_DOMAIN
29800b99b8Sopenharmony_ci#undef LOG_TAG
30800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11
31800b99b8Sopenharmony_ci#define LOG_TAG "DfxFrameFormatter"
32800b99b8Sopenharmony_ci}
33800b99b8Sopenharmony_ci
34800b99b8Sopenharmony_cistd::string DfxFrameFormatter::GetFrameStr(const DfxFrame& frame)
35800b99b8Sopenharmony_ci{
36800b99b8Sopenharmony_ci    return GetFrameStr(std::make_shared<DfxFrame>(frame));
37800b99b8Sopenharmony_ci}
38800b99b8Sopenharmony_ci
39800b99b8Sopenharmony_cistd::string DfxFrameFormatter::GetFrameStr(const std::shared_ptr<DfxFrame>& frame)
40800b99b8Sopenharmony_ci{
41800b99b8Sopenharmony_ci    if (frame == nullptr) {
42800b99b8Sopenharmony_ci        return "";
43800b99b8Sopenharmony_ci    }
44800b99b8Sopenharmony_ci    std::string data;
45800b99b8Sopenharmony_ci    if (frame->isJsFrame) {
46800b99b8Sopenharmony_ci#if defined(ENABLE_MIXSTACK)
47800b99b8Sopenharmony_ci        if (frame->funcName.empty()) {
48800b99b8Sopenharmony_ci            std::string mapName = frame->map == nullptr ? "" : frame->map->name;
49800b99b8Sopenharmony_ci            data = StringPrintf("#%02zu at %s", frame->index, mapName.c_str());
50800b99b8Sopenharmony_ci        } else {
51800b99b8Sopenharmony_ci            data = StringPrintf("#%02zu at %s (%s:%d:%d)", frame->index, frame->funcName.c_str(),
52800b99b8Sopenharmony_ci                frame->mapName.c_str(), frame->line, frame->column);
53800b99b8Sopenharmony_ci        }
54800b99b8Sopenharmony_ci#endif
55800b99b8Sopenharmony_ci    } else {
56800b99b8Sopenharmony_ci        uint64_t pc = frame->relPc == 0 ? frame->pc : frame->relPc;
57800b99b8Sopenharmony_ci#ifdef __LP64__
58800b99b8Sopenharmony_ci        data = StringPrintf("#%02zu pc %016" PRIx64, frame->index, pc);
59800b99b8Sopenharmony_ci#else
60800b99b8Sopenharmony_ci        data = StringPrintf("#%02zu pc %08" PRIx64, frame->index, pc);
61800b99b8Sopenharmony_ci#endif
62800b99b8Sopenharmony_ci        if (!frame->mapName.empty()) {
63800b99b8Sopenharmony_ci            DfxMap::UnFormatMapName(frame->mapName);
64800b99b8Sopenharmony_ci            data += " " + frame->mapName;
65800b99b8Sopenharmony_ci        } else {
66800b99b8Sopenharmony_ci            data += " [Unknown]";
67800b99b8Sopenharmony_ci        }
68800b99b8Sopenharmony_ci        if (frame->funcName.length() > MAX_FUNC_NAME_LEN) {
69800b99b8Sopenharmony_ci            DFXLOGD("length of funcName greater than 256 byte, do not display it");
70800b99b8Sopenharmony_ci        } else if (!frame->funcName.empty()) {
71800b99b8Sopenharmony_ci            data += "(" + frame->funcName;
72800b99b8Sopenharmony_ci            data += StringPrintf("+%" PRId64, frame->funcOffset);
73800b99b8Sopenharmony_ci            data += ")";
74800b99b8Sopenharmony_ci        }
75800b99b8Sopenharmony_ci        if (!frame->buildId.empty()) {
76800b99b8Sopenharmony_ci            data += "(" + frame->buildId + ")";
77800b99b8Sopenharmony_ci        }
78800b99b8Sopenharmony_ci    }
79800b99b8Sopenharmony_ci    data += "\n";
80800b99b8Sopenharmony_ci    return data;
81800b99b8Sopenharmony_ci}
82800b99b8Sopenharmony_ci
83800b99b8Sopenharmony_cistd::string DfxFrameFormatter::GetFramesStr(const std::vector<DfxFrame>& frames)
84800b99b8Sopenharmony_ci{
85800b99b8Sopenharmony_ci    if (frames.size() == 0) {
86800b99b8Sopenharmony_ci        return "";
87800b99b8Sopenharmony_ci    }
88800b99b8Sopenharmony_ci    std::string ss;
89800b99b8Sopenharmony_ci    for (const auto& f : frames) {
90800b99b8Sopenharmony_ci        ss += GetFrameStr(f);
91800b99b8Sopenharmony_ci    }
92800b99b8Sopenharmony_ci    return ss;
93800b99b8Sopenharmony_ci}
94800b99b8Sopenharmony_ci
95800b99b8Sopenharmony_cistd::string DfxFrameFormatter::GetFramesStr(const std::vector<std::shared_ptr<DfxFrame>>& frames)
96800b99b8Sopenharmony_ci{
97800b99b8Sopenharmony_ci    if (frames.size() == 0) {
98800b99b8Sopenharmony_ci        return "";
99800b99b8Sopenharmony_ci    }
100800b99b8Sopenharmony_ci    std::string ss;
101800b99b8Sopenharmony_ci    for (const auto& pf : frames) {
102800b99b8Sopenharmony_ci        ss += GetFrameStr(pf);
103800b99b8Sopenharmony_ci    }
104800b99b8Sopenharmony_ci    return ss;
105800b99b8Sopenharmony_ci}
106800b99b8Sopenharmony_ci
107800b99b8Sopenharmony_cistd::vector<std::shared_ptr<DfxFrame>> DfxFrameFormatter::ConvertFrames(const std::vector<DfxFrame>& frames)
108800b99b8Sopenharmony_ci{
109800b99b8Sopenharmony_ci    std::vector<std::shared_ptr<DfxFrame>> pFrames;
110800b99b8Sopenharmony_ci    for (const auto& frame : frames) {
111800b99b8Sopenharmony_ci        pFrames.emplace_back(std::make_shared<DfxFrame>(frame));
112800b99b8Sopenharmony_ci    }
113800b99b8Sopenharmony_ci    return pFrames;
114800b99b8Sopenharmony_ci}
115800b99b8Sopenharmony_ci} // namespace HiviewDFX
116800b99b8Sopenharmony_ci} // namespace OHOS
117