• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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_json_formatter.h"
17 
18 #include <cstdlib>
19 #include <iostream>
20 #include <ostream>
21 #include <regex>
22 #include <securec.h>
23 #include <sstream>
24 #ifndef is_ohos_lite
25 #include "json/json.h"
26 #endif
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 #ifndef is_ohos_lite
31 namespace {
32 const int FRAME_BUF_LEN = 1024;
FormatJsFrame(const Json::Value & frames,const uint32_t & frameIdx,std::string & outStr)33 static bool FormatJsFrame(const Json::Value& frames, const uint32_t& frameIdx, std::string& outStr)
34 {
35     const int jsIdxLen = 10;
36     char buf[jsIdxLen] = { 0 };
37     char idxFmt[] = "#%02u at ";
38     if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, idxFmt, frameIdx) <= 0) {
39         return false;
40     }
41     outStr = std::string(buf, strlen(buf));
42     std::string symbol = frames[frameIdx]["symbol"].asString();
43     std::string file = frames[frameIdx]["file"].asString();
44     std::string line = frames[frameIdx]["line"].asString();
45     std::string column = frames[frameIdx]["column"].asString();
46     outStr.append(symbol + " (" + file + ":" + line + ":" + column + ")");
47     return true;
48 }
49 
FormatNativeFrame(const Json::Value & frames,const uint32_t & frameIdx,std::string & outStr)50 static bool FormatNativeFrame(const Json::Value& frames, const uint32_t& frameIdx, std::string& outStr)
51 {
52     char buf[FRAME_BUF_LEN] = {0};
53     char format[] = "#%02u pc %s %s";
54     std::string buildId = frames[frameIdx]["buildId"].asString();
55     std::string file = frames[frameIdx]["file"].asString();
56     std::string offset = frames[frameIdx]["offset"].asString();
57     std::string pc = frames[frameIdx]["pc"].asString();
58     std::string symbol = frames[frameIdx]["symbol"].asString();
59     if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, frameIdx, pc.c_str(),
60                    file.empty() ? "Unknown" : file.c_str()) <= 0) {
61         return false;
62     }
63     outStr = std::string(buf, strlen(buf));
64     if (!symbol.empty()) {
65         outStr.append("(" + symbol + "+" + offset + ")");
66     }
67     if (!buildId.empty()) {
68         outStr.append("(" + buildId + ")");
69     }
70     return true;
71 }
72 }
73 
FormatJsonStack(std::string jsonStack,std::string & outStackStr)74 bool DfxJsonFormatter::FormatJsonStack(std::string jsonStack, std::string& outStackStr)
75 {
76     Json::Reader reader;
77     Json::Value threads;
78     if (!(reader.parse(jsonStack, threads))) {
79         outStackStr.append("Failed to parse json stack info.");
80         return false;
81     }
82 
83     for (uint32_t i = 0; i < threads.size(); ++i) {
84         std::ostringstream ss;
85         Json::Value thread = threads[i];
86         if (thread["tid"].isConvertibleTo(Json::stringValue) &&
87             thread["thread_name"].isConvertibleTo(Json::stringValue)) {
88             ss << "Tid:" << thread["tid"].asString() << ", Name:" << thread["thread_name"].asString() << std::endl;
89         }
90         const Json::Value frames = thread["frames"];
91         for (uint32_t j = 0; j < frames.size(); ++j) {
92             std::string frameStr = "";
93             bool formatStatus = false;
94             if (frames[j]["line"].asString().empty()) {
95                 formatStatus = FormatNativeFrame(frames, j, frameStr);
96             } else {
97                 formatStatus = FormatJsFrame(frames, j, frameStr);
98             }
99             if (formatStatus) {
100                 ss << frameStr << std::endl;
101             } else {
102                 // Shall we try to print more information?
103                 outStackStr.append("Frame info is illegal.");
104                 return false;
105             }
106         }
107         outStackStr.append(ss.str());
108     }
109     return true;
110 }
111 #endif
112 } // namespace HiviewDFX
113 } // namespace OHOS
114