• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "decorative_dump_info.h"
16 #ifndef is_ohos_lite
17 #include "async_stack.h"
18 #endif
19 #include "dfx_dump_request.h"
20 #include "dfx_process.h"
21 #include "dfx_log.h"
22 #include "dump_utils.h"
23 #include "unwinder.h"
24 #ifndef is_ohos_lite
25 #include "unique_stack_table.h"
26 #endif
27 #include "dfx_util.h"
28 #include "dfx_buffer_writer.h"
29 namespace OHOS {
30 namespace HiviewDFX {
31 REGISTER_DUMP_INFO_CLASS(SubmitterStack);
32 
Print(DfxProcess & process,const ProcessDumpRequest & request,Unwinder & unwinder)33 void SubmitterStack::Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder)
34 {
35     DecorativeDumpInfo::Print(process, request, unwinder);
36     auto thread = process.GetKeyThread();
37     std::vector<DfxFrame> submitterFrames;
38     GetSubmitterStack(thread->GetThreadInfo().nsTid, request.stackId, unwinder, submitterFrames);
39     if (submitterFrames.empty()) {
40         return;
41     }
42     thread->SetSubmitterFrames(submitterFrames);
43     std::string stackStr = "========SubmitterStacktrace========\n";
44     stackStr += DumpUtils::GetStackTrace(submitterFrames);
45     DfxBufferWriter::GetInstance().WriteMsg(stackStr);
46     DfxBufferWriter::GetInstance().AppendBriefDumpInfo(stackStr);
47 }
48 
GetSubmitterStack(pid_t tid,uint64_t stackId,Unwinder & unwinder,std::vector<DfxFrame> & submitterFrames)49 void SubmitterStack::GetSubmitterStack(pid_t tid, uint64_t stackId, Unwinder& unwinder,
50     std::vector<DfxFrame>& submitterFrames)
51 {
52 #ifndef is_ohos_lite
53     if (stackId == 0) {
54         DFXLOGW("stackId has not been initialized!");
55         return;
56     }
57     const std::shared_ptr<DfxMaps>& maps = unwinder.GetMaps();
58     if (maps == nullptr) {
59         DFXLOGE("maps is nullptr!");
60         return;
61     }
62     std::vector<std::shared_ptr<DfxMap>> mapVec;
63     if (!maps->FindMapsByName("[anon:async_stack_table]", mapVec)) {
64         DFXLOGE("can not find map of async stack table!");
65         return;
66     }
67     auto map = mapVec.front();
68     size_t size = map->end - map->begin;
69     auto tableData = std::make_shared<std::vector<uint8_t>>(size);
70     size_t byte = ReadProcMemByPid(tid, map->begin, tableData->data(), size);
71     if (byte != size) {
72         DFXLOGE("Failed to read unique_table from target");
73         return;
74     }
75     UniqueStackTable stackTable(tableData->data(), size, false);
76     std::vector<uintptr_t> pcs;
77     StackId id;
78     id.value = stackId;
79     if (!stackTable.GetPcsByStackId(id, pcs)) {
80         DFXLOGW("Failed to get pcs by stackId");
81         return;
82     }
83     unwinder.EnableParseNativeSymbol(true);
84     unwinder.GetFramesByPcs(submitterFrames, pcs);
85     unwinder.EnableParseNativeSymbol(false);
86 #endif
87 }
88 }
89 }