1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker *
4*eb293b8fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker *
8*eb293b8fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker *
10*eb293b8fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker */
16*eb293b8fSAndroid Build Coastguard Worker
17*eb293b8fSAndroid Build Coastguard Worker #include <inttypes.h>
18*eb293b8fSAndroid Build Coastguard Worker #include <sys/types.h>
19*eb293b8fSAndroid Build Coastguard Worker #include <unistd.h>
20*eb293b8fSAndroid Build Coastguard Worker
21*eb293b8fSAndroid Build Coastguard Worker #include <memory>
22*eb293b8fSAndroid Build Coastguard Worker #include <mutex>
23*eb293b8fSAndroid Build Coastguard Worker #include <string>
24*eb293b8fSAndroid Build Coastguard Worker #include <vector>
25*eb293b8fSAndroid Build Coastguard Worker
26*eb293b8fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
27*eb293b8fSAndroid Build Coastguard Worker #include <android-base/threads.h>
28*eb293b8fSAndroid Build Coastguard Worker
29*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/AndroidUnwinder.h>
30*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Arch.h>
31*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Demangle.h>
32*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/DexFiles.h>
33*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Error.h>
34*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/JitDebug.h>
35*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Maps.h>
36*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h>
37*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Regs.h>
38*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/RegsGetLocal.h>
39*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Unwinder.h>
40*eb293b8fSAndroid Build Coastguard Worker
41*eb293b8fSAndroid Build Coastguard Worker #if defined(__BIONIC__)
42*eb293b8fSAndroid Build Coastguard Worker #include <bionic/reserved_signals.h>
43*eb293b8fSAndroid Build Coastguard Worker static constexpr int kThreadUnwindSignal = BIONIC_SIGNAL_BACKTRACE;
44*eb293b8fSAndroid Build Coastguard Worker #else
45*eb293b8fSAndroid Build Coastguard Worker #include <signal.h>
46*eb293b8fSAndroid Build Coastguard Worker static int kThreadUnwindSignal = SIGRTMIN;
47*eb293b8fSAndroid Build Coastguard Worker #endif
48*eb293b8fSAndroid Build Coastguard Worker
49*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
50*eb293b8fSAndroid Build Coastguard Worker
DemangleFunctionNames()51*eb293b8fSAndroid Build Coastguard Worker void AndroidUnwinderData::DemangleFunctionNames() {
52*eb293b8fSAndroid Build Coastguard Worker for (auto& frame : frames) {
53*eb293b8fSAndroid Build Coastguard Worker frame.function_name = DemangleNameIfNeeded(frame.function_name);
54*eb293b8fSAndroid Build Coastguard Worker }
55*eb293b8fSAndroid Build Coastguard Worker }
56*eb293b8fSAndroid Build Coastguard Worker
GetErrorString()57*eb293b8fSAndroid Build Coastguard Worker std::string AndroidUnwinderData::GetErrorString() {
58*eb293b8fSAndroid Build Coastguard Worker std::string error_msg(GetErrorCodeString(error.code));
59*eb293b8fSAndroid Build Coastguard Worker if (error.address != 0) {
60*eb293b8fSAndroid Build Coastguard Worker error_msg += android::base::StringPrintf(" at address 0x%" PRIx64, error.address);
61*eb293b8fSAndroid Build Coastguard Worker }
62*eb293b8fSAndroid Build Coastguard Worker return error_msg;
63*eb293b8fSAndroid Build Coastguard Worker }
64*eb293b8fSAndroid Build Coastguard Worker
Create(pid_t pid)65*eb293b8fSAndroid Build Coastguard Worker AndroidUnwinder* AndroidUnwinder::Create(pid_t pid) {
66*eb293b8fSAndroid Build Coastguard Worker if (pid == getpid()) {
67*eb293b8fSAndroid Build Coastguard Worker return new AndroidLocalUnwinder;
68*eb293b8fSAndroid Build Coastguard Worker } else {
69*eb293b8fSAndroid Build Coastguard Worker return new AndroidRemoteUnwinder(pid);
70*eb293b8fSAndroid Build Coastguard Worker }
71*eb293b8fSAndroid Build Coastguard Worker }
72*eb293b8fSAndroid Build Coastguard Worker
Initialize(ErrorData & error)73*eb293b8fSAndroid Build Coastguard Worker bool AndroidUnwinder::Initialize(ErrorData& error) {
74*eb293b8fSAndroid Build Coastguard Worker // Android stores the jit and dex file location only in the library
75*eb293b8fSAndroid Build Coastguard Worker // libart.so or libartd.so.
76*eb293b8fSAndroid Build Coastguard Worker static std::vector<std::string> search_libs [[clang::no_destroy]] = {"libart.so", "libartd.so"};
77*eb293b8fSAndroid Build Coastguard Worker
78*eb293b8fSAndroid Build Coastguard Worker std::call_once(initialize_, [this, &error]() {
79*eb293b8fSAndroid Build Coastguard Worker if (!InternalInitialize(error)) {
80*eb293b8fSAndroid Build Coastguard Worker initialize_status_ = false;
81*eb293b8fSAndroid Build Coastguard Worker return;
82*eb293b8fSAndroid Build Coastguard Worker }
83*eb293b8fSAndroid Build Coastguard Worker
84*eb293b8fSAndroid Build Coastguard Worker jit_debug_ = CreateJitDebug(arch_, process_memory_, search_libs);
85*eb293b8fSAndroid Build Coastguard Worker
86*eb293b8fSAndroid Build Coastguard Worker #if defined(DEXFILE_SUPPORT)
87*eb293b8fSAndroid Build Coastguard Worker dex_files_ = CreateDexFiles(arch_, process_memory_, search_libs);
88*eb293b8fSAndroid Build Coastguard Worker #endif
89*eb293b8fSAndroid Build Coastguard Worker initialize_status_ = true;
90*eb293b8fSAndroid Build Coastguard Worker });
91*eb293b8fSAndroid Build Coastguard Worker
92*eb293b8fSAndroid Build Coastguard Worker return initialize_status_;
93*eb293b8fSAndroid Build Coastguard Worker }
94*eb293b8fSAndroid Build Coastguard Worker
FormatFrame(const FrameData & frame) const95*eb293b8fSAndroid Build Coastguard Worker std::string AndroidUnwinder::FormatFrame(const FrameData& frame) const {
96*eb293b8fSAndroid Build Coastguard Worker if (arch_ == ARCH_UNKNOWN) {
97*eb293b8fSAndroid Build Coastguard Worker return "";
98*eb293b8fSAndroid Build Coastguard Worker }
99*eb293b8fSAndroid Build Coastguard Worker return Unwinder::FormatFrame(arch_, frame);
100*eb293b8fSAndroid Build Coastguard Worker }
101*eb293b8fSAndroid Build Coastguard Worker
InternalInitialize(ErrorData & error)102*eb293b8fSAndroid Build Coastguard Worker bool AndroidLocalUnwinder::InternalInitialize(ErrorData& error) {
103*eb293b8fSAndroid Build Coastguard Worker arch_ = Regs::CurrentArch();
104*eb293b8fSAndroid Build Coastguard Worker
105*eb293b8fSAndroid Build Coastguard Worker maps_.reset(new LocalUpdatableMaps);
106*eb293b8fSAndroid Build Coastguard Worker if (!maps_->Parse()) {
107*eb293b8fSAndroid Build Coastguard Worker error.code = ERROR_MAPS_PARSE;
108*eb293b8fSAndroid Build Coastguard Worker return false;
109*eb293b8fSAndroid Build Coastguard Worker }
110*eb293b8fSAndroid Build Coastguard Worker
111*eb293b8fSAndroid Build Coastguard Worker if (process_memory_ == nullptr) {
112*eb293b8fSAndroid Build Coastguard Worker process_memory_ = Memory::CreateProcessMemoryThreadCached(getpid());
113*eb293b8fSAndroid Build Coastguard Worker }
114*eb293b8fSAndroid Build Coastguard Worker
115*eb293b8fSAndroid Build Coastguard Worker return true;
116*eb293b8fSAndroid Build Coastguard Worker }
117*eb293b8fSAndroid Build Coastguard Worker
BuildFrameFromPcOnly(uint64_t pc)118*eb293b8fSAndroid Build Coastguard Worker FrameData AndroidUnwinder::BuildFrameFromPcOnly(uint64_t pc) {
119*eb293b8fSAndroid Build Coastguard Worker return Unwinder::BuildFrameFromPcOnly(pc, arch_, maps_.get(), jit_debug_.get(), process_memory_,
120*eb293b8fSAndroid Build Coastguard Worker true);
121*eb293b8fSAndroid Build Coastguard Worker }
122*eb293b8fSAndroid Build Coastguard Worker
Unwind(AndroidUnwinderData & data)123*eb293b8fSAndroid Build Coastguard Worker bool AndroidUnwinder::Unwind(AndroidUnwinderData& data) {
124*eb293b8fSAndroid Build Coastguard Worker return Unwind(std::nullopt, data);
125*eb293b8fSAndroid Build Coastguard Worker }
126*eb293b8fSAndroid Build Coastguard Worker
Unwind(std::optional<pid_t> tid,AndroidUnwinderData & data)127*eb293b8fSAndroid Build Coastguard Worker bool AndroidUnwinder::Unwind(std::optional<pid_t> tid, AndroidUnwinderData& data) {
128*eb293b8fSAndroid Build Coastguard Worker if (!Initialize(data.error)) {
129*eb293b8fSAndroid Build Coastguard Worker return false;
130*eb293b8fSAndroid Build Coastguard Worker }
131*eb293b8fSAndroid Build Coastguard Worker
132*eb293b8fSAndroid Build Coastguard Worker return InternalUnwind(tid, data);
133*eb293b8fSAndroid Build Coastguard Worker }
134*eb293b8fSAndroid Build Coastguard Worker
Unwind(void * ucontext,AndroidUnwinderData & data)135*eb293b8fSAndroid Build Coastguard Worker bool AndroidUnwinder::Unwind(void* ucontext, AndroidUnwinderData& data) {
136*eb293b8fSAndroid Build Coastguard Worker if (ucontext == nullptr) {
137*eb293b8fSAndroid Build Coastguard Worker data.error.code = ERROR_INVALID_PARAMETER;
138*eb293b8fSAndroid Build Coastguard Worker return false;
139*eb293b8fSAndroid Build Coastguard Worker }
140*eb293b8fSAndroid Build Coastguard Worker
141*eb293b8fSAndroid Build Coastguard Worker if (!Initialize(data.error)) {
142*eb293b8fSAndroid Build Coastguard Worker return false;
143*eb293b8fSAndroid Build Coastguard Worker }
144*eb293b8fSAndroid Build Coastguard Worker
145*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(arch_, ucontext));
146*eb293b8fSAndroid Build Coastguard Worker return Unwind(regs.get(), data);
147*eb293b8fSAndroid Build Coastguard Worker }
148*eb293b8fSAndroid Build Coastguard Worker
Unwind(Regs * initial_regs,AndroidUnwinderData & data)149*eb293b8fSAndroid Build Coastguard Worker bool AndroidUnwinder::Unwind(Regs* initial_regs, AndroidUnwinderData& data) {
150*eb293b8fSAndroid Build Coastguard Worker if (initial_regs == nullptr) {
151*eb293b8fSAndroid Build Coastguard Worker data.error.code = ERROR_INVALID_PARAMETER;
152*eb293b8fSAndroid Build Coastguard Worker return false;
153*eb293b8fSAndroid Build Coastguard Worker }
154*eb293b8fSAndroid Build Coastguard Worker
155*eb293b8fSAndroid Build Coastguard Worker if (!Initialize(data.error)) {
156*eb293b8fSAndroid Build Coastguard Worker return false;
157*eb293b8fSAndroid Build Coastguard Worker }
158*eb293b8fSAndroid Build Coastguard Worker
159*eb293b8fSAndroid Build Coastguard Worker if (arch_ != initial_regs->Arch()) {
160*eb293b8fSAndroid Build Coastguard Worker data.error.code = ERROR_BAD_ARCH;
161*eb293b8fSAndroid Build Coastguard Worker return false;
162*eb293b8fSAndroid Build Coastguard Worker }
163*eb293b8fSAndroid Build Coastguard Worker
164*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Regs> regs(initial_regs->Clone());
165*eb293b8fSAndroid Build Coastguard Worker if (data.saved_initial_regs) {
166*eb293b8fSAndroid Build Coastguard Worker (*data.saved_initial_regs).reset(initial_regs->Clone());
167*eb293b8fSAndroid Build Coastguard Worker }
168*eb293b8fSAndroid Build Coastguard Worker Unwinder unwinder(data.max_frames.value_or(max_frames_), maps_.get(), regs.get(),
169*eb293b8fSAndroid Build Coastguard Worker process_memory_);
170*eb293b8fSAndroid Build Coastguard Worker unwinder.SetJitDebug(jit_debug_.get());
171*eb293b8fSAndroid Build Coastguard Worker unwinder.SetDexFiles(dex_files_.get());
172*eb293b8fSAndroid Build Coastguard Worker unwinder.Unwind(data.show_all_frames ? nullptr : &initial_map_names_to_skip_,
173*eb293b8fSAndroid Build Coastguard Worker &map_suffixes_to_ignore_);
174*eb293b8fSAndroid Build Coastguard Worker data.frames = unwinder.ConsumeFrames();
175*eb293b8fSAndroid Build Coastguard Worker data.error = unwinder.LastError();
176*eb293b8fSAndroid Build Coastguard Worker return data.frames.size() != 0;
177*eb293b8fSAndroid Build Coastguard Worker }
178*eb293b8fSAndroid Build Coastguard Worker
InternalUnwind(std::optional<pid_t> tid,AndroidUnwinderData & data)179*eb293b8fSAndroid Build Coastguard Worker bool AndroidLocalUnwinder::InternalUnwind(std::optional<pid_t> tid, AndroidUnwinderData& data) {
180*eb293b8fSAndroid Build Coastguard Worker if (!tid) {
181*eb293b8fSAndroid Build Coastguard Worker tid = android::base::GetThreadId();
182*eb293b8fSAndroid Build Coastguard Worker }
183*eb293b8fSAndroid Build Coastguard Worker
184*eb293b8fSAndroid Build Coastguard Worker if (static_cast<uint64_t>(*tid) == android::base::GetThreadId()) {
185*eb293b8fSAndroid Build Coastguard Worker // Unwind current thread.
186*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
187*eb293b8fSAndroid Build Coastguard Worker RegsGetLocal(regs.get());
188*eb293b8fSAndroid Build Coastguard Worker return AndroidUnwinder::Unwind(regs.get(), data);
189*eb293b8fSAndroid Build Coastguard Worker }
190*eb293b8fSAndroid Build Coastguard Worker
191*eb293b8fSAndroid Build Coastguard Worker ThreadUnwinder unwinder(data.max_frames.value_or(max_frames_), maps_.get(), process_memory_);
192*eb293b8fSAndroid Build Coastguard Worker unwinder.SetJitDebug(jit_debug_.get());
193*eb293b8fSAndroid Build Coastguard Worker unwinder.SetDexFiles(dex_files_.get());
194*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Regs>* initial_regs = nullptr;
195*eb293b8fSAndroid Build Coastguard Worker if (data.saved_initial_regs) {
196*eb293b8fSAndroid Build Coastguard Worker initial_regs = &data.saved_initial_regs.value();
197*eb293b8fSAndroid Build Coastguard Worker }
198*eb293b8fSAndroid Build Coastguard Worker unwinder.UnwindWithSignal(kThreadUnwindSignal, *tid, initial_regs,
199*eb293b8fSAndroid Build Coastguard Worker data.show_all_frames ? nullptr : &initial_map_names_to_skip_,
200*eb293b8fSAndroid Build Coastguard Worker &map_suffixes_to_ignore_);
201*eb293b8fSAndroid Build Coastguard Worker data.frames = unwinder.ConsumeFrames();
202*eb293b8fSAndroid Build Coastguard Worker data.error = unwinder.LastError();
203*eb293b8fSAndroid Build Coastguard Worker return data.frames.size() != 0;
204*eb293b8fSAndroid Build Coastguard Worker }
205*eb293b8fSAndroid Build Coastguard Worker
InternalInitialize(ErrorData & error)206*eb293b8fSAndroid Build Coastguard Worker bool AndroidRemoteUnwinder::InternalInitialize(ErrorData& error) {
207*eb293b8fSAndroid Build Coastguard Worker if (arch_ == ARCH_UNKNOWN) {
208*eb293b8fSAndroid Build Coastguard Worker arch_ = Regs::RemoteGetArch(pid_, &error.code);
209*eb293b8fSAndroid Build Coastguard Worker }
210*eb293b8fSAndroid Build Coastguard Worker if (arch_ == ARCH_UNKNOWN) {
211*eb293b8fSAndroid Build Coastguard Worker return false;
212*eb293b8fSAndroid Build Coastguard Worker }
213*eb293b8fSAndroid Build Coastguard Worker
214*eb293b8fSAndroid Build Coastguard Worker maps_.reset(new RemoteMaps(pid_));
215*eb293b8fSAndroid Build Coastguard Worker if (!maps_->Parse()) {
216*eb293b8fSAndroid Build Coastguard Worker error.code = ERROR_MAPS_PARSE;
217*eb293b8fSAndroid Build Coastguard Worker return false;
218*eb293b8fSAndroid Build Coastguard Worker }
219*eb293b8fSAndroid Build Coastguard Worker
220*eb293b8fSAndroid Build Coastguard Worker if (process_memory_ == nullptr) {
221*eb293b8fSAndroid Build Coastguard Worker process_memory_ = Memory::CreateProcessMemoryCached(pid_);
222*eb293b8fSAndroid Build Coastguard Worker }
223*eb293b8fSAndroid Build Coastguard Worker
224*eb293b8fSAndroid Build Coastguard Worker return true;
225*eb293b8fSAndroid Build Coastguard Worker }
226*eb293b8fSAndroid Build Coastguard Worker
InternalUnwind(std::optional<pid_t> tid,AndroidUnwinderData & data)227*eb293b8fSAndroid Build Coastguard Worker bool AndroidRemoteUnwinder::InternalUnwind(std::optional<pid_t> tid, AndroidUnwinderData& data) {
228*eb293b8fSAndroid Build Coastguard Worker if (!tid) {
229*eb293b8fSAndroid Build Coastguard Worker tid = pid_;
230*eb293b8fSAndroid Build Coastguard Worker }
231*eb293b8fSAndroid Build Coastguard Worker
232*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Regs> regs(Regs::RemoteGet(*tid, &data.error.code));
233*eb293b8fSAndroid Build Coastguard Worker if (regs == nullptr) {
234*eb293b8fSAndroid Build Coastguard Worker return false;
235*eb293b8fSAndroid Build Coastguard Worker }
236*eb293b8fSAndroid Build Coastguard Worker return AndroidUnwinder::Unwind(regs.get(), data);
237*eb293b8fSAndroid Build Coastguard Worker }
238*eb293b8fSAndroid Build Coastguard Worker
239*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack
240