1 /*
2  * Copyright (c) 2021-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 #include "dfx_frame_formatter.h"
17 
18 #include <sstream>
19 #include <securec.h>
20 
21 #include "dfx_define.h"
22 #include "dfx_log.h"
23 #include "dfx_maps.h"
24 #include "string_printf.h"
25 
26 namespace OHOS {
27 namespace HiviewDFX {
28 namespace {
29 #undef LOG_DOMAIN
30 #undef LOG_TAG
31 #define LOG_DOMAIN 0xD002D11
32 #define LOG_TAG "DfxFrameFormatter"
33 }
34 
GetFrameStr(const DfxFrame & frame)35 std::string DfxFrameFormatter::GetFrameStr(const DfxFrame& frame)
36 {
37     return GetFrameStr(std::make_shared<DfxFrame>(frame));
38 }
39 
GetFrameStr(const std::shared_ptr<DfxFrame> & frame)40 std::string DfxFrameFormatter::GetFrameStr(const std::shared_ptr<DfxFrame>& frame)
41 {
42     if (frame == nullptr) {
43         return "";
44     }
45     std::string data;
46     if (frame->isJsFrame) {
47 #if defined(ENABLE_MIXSTACK)
48         if (frame->funcName.empty()) {
49             std::string mapName = frame->map == nullptr ? "" : frame->map->name;
50             data = StringPrintf("#%02zu at %s", frame->index, mapName.c_str());
51         } else {
52             data = StringPrintf("#%02zu at %s (%s:%d:%d)", frame->index, frame->funcName.c_str(),
53                 frame->mapName.c_str(), frame->line, frame->column);
54         }
55 #endif
56     } else {
57         uint64_t pc = frame->relPc == 0 ? frame->pc : frame->relPc;
58 #ifdef __LP64__
59         data = StringPrintf("#%02zu pc %016" PRIx64, frame->index, pc);
60 #else
61         data = StringPrintf("#%02zu pc %08" PRIx64, frame->index, pc);
62 #endif
63         if (!frame->mapName.empty()) {
64             DfxMaps::UnFormatMapName(frame->mapName);
65             data += " " + frame->mapName;
66         } else {
67             data += " [Unknown]";
68         }
69         if (frame->funcName.length() > MAX_FUNC_NAME_LEN) {
70             DFXLOG_DEBUG("%s", "length of funcName greater than 256 byte, do not display it");
71         } else if (!frame->funcName.empty()) {
72             data += "(" + frame->funcName;
73             data += StringPrintf("+%" PRId64, frame->funcOffset);
74             data += ")";
75         }
76         if (!frame->buildId.empty()) {
77             data += "(" + frame->buildId + ")";
78         }
79     }
80     data += "\n";
81     return data;
82 }
83 
GetFramesStr(const std::vector<DfxFrame> & frames)84 std::string DfxFrameFormatter::GetFramesStr(const std::vector<DfxFrame>& frames)
85 {
86     if (frames.size() == 0) {
87         return "";
88     }
89     std::ostringstream ss;
90     for (const auto& f : frames) {
91         ss << GetFrameStr(f);
92     }
93     return ss.str();
94 }
95 
GetFramesStr(const std::vector<std::shared_ptr<DfxFrame>> & frames)96 std::string DfxFrameFormatter::GetFramesStr(const std::vector<std::shared_ptr<DfxFrame>>& frames)
97 {
98     if (frames.size() == 0) {
99         return "";
100     }
101     std::ostringstream ss;
102     for (const auto& pf : frames) {
103         ss << GetFrameStr(pf);
104     }
105     return ss.str();
106 }
107 
ConvertFrames(const std::vector<DfxFrame> & frames)108 std::vector<std::shared_ptr<DfxFrame>> DfxFrameFormatter::ConvertFrames(const std::vector<DfxFrame>& frames)
109 {
110     std::vector<std::shared_ptr<DfxFrame>> pFrames;
111     for (const auto& frame : frames) {
112         pFrames.emplace_back(std::make_shared<DfxFrame>(frame));
113     }
114     return pFrames;
115 }
116 } // namespace HiviewDFX
117 } // namespace OHOS
118