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