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