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 }