• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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