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