1 /*
2 * Copyright (c) 2023 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 "printer.h"
17
18 #include <cinttypes>
19 #include <dlfcn.h>
20 #include <map>
21 #include <string>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include "dfx_config.h"
25 #include "dfx_logger.h"
26 #include "dfx_frame_format.h"
27 #include "dfx_ring_buffer_wrapper.h"
28 #include "dfx_signal.h"
29 #include "dfx_util.h"
30
31 namespace OHOS {
32 namespace HiviewDFX {
PrintDumpHeader(std::shared_ptr<ProcessDumpRequest> request,std::shared_ptr<DfxProcess> process)33 void Printer::PrintDumpHeader(std::shared_ptr<ProcessDumpRequest> request, std::shared_ptr<DfxProcess> process)
34 {
35 bool isCrash = (request->siginfo.si_signo != SIGDUMP);
36 if (isCrash) {
37 DfxRingBufferWrapper::GetInstance().AppendMsg("Timestamp:" + GetCurrentTimeStr(request->timeStamp));
38 } else {
39 DfxRingBufferWrapper::GetInstance().AppendMsg("Timestamp:" + GetCurrentTimeStr());
40 }
41 DfxRingBufferWrapper::GetInstance().AppendBuf("Pid:%d\n", process->processInfo_.pid);
42 DfxRingBufferWrapper::GetInstance().AppendBuf("Uid:%d\n", process->processInfo_.uid);
43 DfxRingBufferWrapper::GetInstance().AppendBuf("Process name:%s\n", process->processInfo_.processName.c_str());
44
45 if (isCrash) {
46 DfxRingBufferWrapper::GetInstance().AppendMsg("Reason:");
47 DfxRingBufferWrapper::GetInstance().AppendMsg(DfxSignal::PrintSignal(request->siginfo));
48 auto msg = process->GetFatalMessage();
49 if (!msg.empty()) {
50 DfxRingBufferWrapper::GetInstance().AppendBuf("LastFatalMessage:%s\n", msg.c_str());
51 }
52
53 auto traceId = request->traceInfo;
54 if (traceId.chainId != 0) {
55 DfxRingBufferWrapper::GetInstance().AppendBuf("TraceId:%llx\n",
56 static_cast<unsigned long long>(traceId.chainId));
57 }
58
59 if (process->vmThread_ != nullptr) {
60 DfxRingBufferWrapper::GetInstance().AppendMsg("Fault thread Info:\n");
61 }
62 }
63 }
64
PrintProcessMapsByConfig(std::shared_ptr<DfxProcess> process)65 void Printer::PrintProcessMapsByConfig(std::shared_ptr<DfxProcess> process)
66 {
67 if (DfxConfig::GetConfig().displayMaps) {
68 process->InitProcessMaps();
69 if (process->GetMaps() == nullptr) {
70 DFXLOG_WARN("Pid:%d maps is null", process->processInfo_.pid);
71 return;
72 }
73 DfxRingBufferWrapper::GetInstance().AppendMsg("\nMaps:\n");
74 auto maps = process->GetMaps()->GetMaps();
75 for (auto iter = maps.begin(); iter != maps.end(); iter++) {
76 DfxRingBufferWrapper::GetInstance().AppendMsg((*iter)->PrintMap());
77 }
78 }
79 }
80
PrintOtherThreadHeaderByConfig()81 void Printer::PrintOtherThreadHeaderByConfig()
82 {
83 if (DfxConfig::GetConfig().displayBacktrace) {
84 DfxRingBufferWrapper::GetInstance().AppendMsg("\nOther thread info:\n");
85 }
86 }
87
PrintThreadHeaderByConfig(std::shared_ptr<DfxThread> thread)88 void Printer::PrintThreadHeaderByConfig(std::shared_ptr<DfxThread> thread)
89 {
90 if (DfxConfig::GetConfig().displayBacktrace) {
91 DfxRingBufferWrapper::GetInstance().AppendBuf("Tid:%d, Name:%s\n",\
92 thread->threadInfo_.tid, thread->threadInfo_.threadName.c_str());
93 }
94 }
95
PrintThreadBacktraceByConfig(std::shared_ptr<DfxThread> thread)96 void Printer::PrintThreadBacktraceByConfig(std::shared_ptr<DfxThread> thread)
97 {
98 if (DfxConfig::GetConfig().displayBacktrace) {
99 const auto& frames = thread->GetFrames();
100 if (frames.size() == 0) {
101 DFXLOG_WARN("Tid:%d frame is null", thread->threadInfo_.tid);
102 return;
103 }
104 for (const auto& frame : frames) {
105 DfxRingBufferWrapper::GetInstance().AppendMsg(DfxFrameFormat::GetFrameStr(frame));
106 }
107 }
108 }
109
PrintThreadRegsByConfig(std::shared_ptr<DfxThread> thread)110 void Printer::PrintThreadRegsByConfig(std::shared_ptr<DfxThread> thread)
111 {
112 if (DfxConfig::GetConfig().displayRegister) {
113 std::shared_ptr<DfxRegs> regs = thread->GetThreadRegs();
114 if (regs != nullptr) {
115 DfxRingBufferWrapper::GetInstance().AppendMsg(regs->PrintRegs());
116 }
117 }
118 }
119
PrintThreadFaultStackByConfig(std::shared_ptr<DfxProcess> process,std::shared_ptr<DfxThread> thread)120 void Printer::PrintThreadFaultStackByConfig(std::shared_ptr<DfxProcess> process, std::shared_ptr<DfxThread> thread)
121 {
122 if (DfxConfig::GetConfig().displayFaultStack) {
123 auto faultstack = std::unique_ptr<FaultStack>(new FaultStack(thread->threadInfo_.nsTid));
124 if (faultstack == nullptr) {
125 return;
126 }
127 faultstack->CollectStackInfo(thread->GetFrames());
128 process->InitProcessMaps();
129 faultstack->CollectRegistersBlock(thread->GetThreadRegs(), process->GetMaps());
130 faultstack->Print();
131 }
132 }
133 } // namespace HiviewDFX
134 } // namespace OHOS
135