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/Demangle.h>
32 #include <unwindstack/DexFiles.h>
33 #include <unwindstack/Error.h>
34 #include <unwindstack/JitDebug.h>
35 #include <unwindstack/Maps.h>
36 #include <unwindstack/Memory.h>
37 #include <unwindstack/Regs.h>
38 #include <unwindstack/RegsGetLocal.h>
39 #include <unwindstack/Unwinder.h>
40
41 #if defined(__BIONIC__)
42 #include <bionic/reserved_signals.h>
43 static constexpr int kThreadUnwindSignal = BIONIC_SIGNAL_BACKTRACE;
44 #else
45 #include <signal.h>
46 static int kThreadUnwindSignal = SIGRTMIN;
47 #endif
48
49 namespace unwindstack {
50
DemangleFunctionNames()51 void AndroidUnwinderData::DemangleFunctionNames() {
52 for (auto& frame : frames) {
53 frame.function_name = DemangleNameIfNeeded(frame.function_name);
54 }
55 }
56
GetErrorString()57 std::string AndroidUnwinderData::GetErrorString() {
58 std::string error_msg(GetErrorCodeString(error.code));
59 if (error.address != 0) {
60 error_msg += android::base::StringPrintf(" at address 0x%" PRIx64, error.address);
61 }
62 return error_msg;
63 }
64
Create(pid_t pid)65 AndroidUnwinder* AndroidUnwinder::Create(pid_t pid) {
66 if (pid == getpid()) {
67 return new AndroidLocalUnwinder;
68 } else {
69 return new AndroidRemoteUnwinder(pid);
70 }
71 }
72
Initialize(ErrorData & error)73 bool AndroidUnwinder::Initialize(ErrorData& error) {
74 // Android stores the jit and dex file location only in the library
75 // libart.so or libartd.so.
76 static std::vector<std::string> search_libs [[clang::no_destroy]] = {"libart.so", "libartd.so"};
77
78 std::call_once(initialize_, [this, &error]() {
79 if (!InternalInitialize(error)) {
80 initialize_status_ = false;
81 return;
82 }
83
84 jit_debug_ = CreateJitDebug(arch_, process_memory_, search_libs);
85
86 #if defined(DEXFILE_SUPPORT)
87 dex_files_ = CreateDexFiles(arch_, process_memory_, search_libs);
88 #endif
89 initialize_status_ = true;
90 });
91
92 return initialize_status_;
93 }
94
FormatFrame(const FrameData & frame) const95 std::string AndroidUnwinder::FormatFrame(const FrameData& frame) const {
96 if (arch_ == ARCH_UNKNOWN) {
97 return "";
98 }
99 return Unwinder::FormatFrame(arch_, frame);
100 }
101
InternalInitialize(ErrorData & error)102 bool AndroidLocalUnwinder::InternalInitialize(ErrorData& error) {
103 arch_ = Regs::CurrentArch();
104
105 maps_.reset(new LocalUpdatableMaps);
106 if (!maps_->Parse()) {
107 error.code = ERROR_MAPS_PARSE;
108 return false;
109 }
110
111 if (process_memory_ == nullptr) {
112 process_memory_ = Memory::CreateProcessMemoryThreadCached(getpid());
113 }
114
115 return true;
116 }
117
BuildFrameFromPcOnly(uint64_t pc)118 FrameData AndroidUnwinder::BuildFrameFromPcOnly(uint64_t pc) {
119 return Unwinder::BuildFrameFromPcOnly(pc, arch_, maps_.get(), jit_debug_.get(), process_memory_,
120 true);
121 }
122
Unwind(AndroidUnwinderData & data)123 bool AndroidUnwinder::Unwind(AndroidUnwinderData& data) {
124 return Unwind(std::nullopt, data);
125 }
126
Unwind(std::optional<pid_t> tid,AndroidUnwinderData & data)127 bool AndroidUnwinder::Unwind(std::optional<pid_t> tid, AndroidUnwinderData& data) {
128 if (!Initialize(data.error)) {
129 return false;
130 }
131
132 return InternalUnwind(tid, data);
133 }
134
Unwind(void * ucontext,AndroidUnwinderData & data)135 bool AndroidUnwinder::Unwind(void* ucontext, AndroidUnwinderData& data) {
136 if (ucontext == nullptr) {
137 data.error.code = ERROR_INVALID_PARAMETER;
138 return false;
139 }
140
141 if (!Initialize(data.error)) {
142 return false;
143 }
144
145 std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(arch_, ucontext));
146 return Unwind(regs.get(), data);
147 }
148
Unwind(Regs * initial_regs,AndroidUnwinderData & data)149 bool AndroidUnwinder::Unwind(Regs* initial_regs, AndroidUnwinderData& data) {
150 if (initial_regs == nullptr) {
151 data.error.code = ERROR_INVALID_PARAMETER;
152 return false;
153 }
154
155 if (!Initialize(data.error)) {
156 return false;
157 }
158
159 if (arch_ != initial_regs->Arch()) {
160 data.error.code = ERROR_BAD_ARCH;
161 return false;
162 }
163
164 std::unique_ptr<Regs> regs(initial_regs->Clone());
165 if (data.saved_initial_regs) {
166 (*data.saved_initial_regs).reset(initial_regs->Clone());
167 }
168 Unwinder unwinder(data.max_frames.value_or(max_frames_), maps_.get(), regs.get(),
169 process_memory_);
170 unwinder.SetJitDebug(jit_debug_.get());
171 unwinder.SetDexFiles(dex_files_.get());
172 unwinder.Unwind(data.show_all_frames ? nullptr : &initial_map_names_to_skip_,
173 &map_suffixes_to_ignore_);
174 data.frames = unwinder.ConsumeFrames();
175 data.error = unwinder.LastError();
176 return data.frames.size() != 0;
177 }
178
InternalUnwind(std::optional<pid_t> tid,AndroidUnwinderData & data)179 bool AndroidLocalUnwinder::InternalUnwind(std::optional<pid_t> tid, AndroidUnwinderData& data) {
180 if (!tid) {
181 tid = android::base::GetThreadId();
182 }
183
184 if (static_cast<uint64_t>(*tid) == android::base::GetThreadId()) {
185 // Unwind current thread.
186 std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
187 RegsGetLocal(regs.get());
188 return AndroidUnwinder::Unwind(regs.get(), data);
189 }
190
191 ThreadUnwinder unwinder(data.max_frames.value_or(max_frames_), maps_.get(), process_memory_);
192 unwinder.SetJitDebug(jit_debug_.get());
193 unwinder.SetDexFiles(dex_files_.get());
194 std::unique_ptr<Regs>* initial_regs = nullptr;
195 if (data.saved_initial_regs) {
196 initial_regs = &data.saved_initial_regs.value();
197 }
198 unwinder.UnwindWithSignal(kThreadUnwindSignal, *tid, initial_regs,
199 data.show_all_frames ? nullptr : &initial_map_names_to_skip_,
200 &map_suffixes_to_ignore_);
201 data.frames = unwinder.ConsumeFrames();
202 data.error = unwinder.LastError();
203 return data.frames.size() != 0;
204 }
205
InternalInitialize(ErrorData & error)206 bool AndroidRemoteUnwinder::InternalInitialize(ErrorData& error) {
207 if (arch_ == ARCH_UNKNOWN) {
208 arch_ = Regs::RemoteGetArch(pid_, &error.code);
209 }
210 if (arch_ == ARCH_UNKNOWN) {
211 return false;
212 }
213
214 maps_.reset(new RemoteMaps(pid_));
215 if (!maps_->Parse()) {
216 error.code = ERROR_MAPS_PARSE;
217 return false;
218 }
219
220 if (process_memory_ == nullptr) {
221 process_memory_ = Memory::CreateProcessMemoryCached(pid_);
222 }
223
224 return true;
225 }
226
InternalUnwind(std::optional<pid_t> tid,AndroidUnwinderData & data)227 bool AndroidRemoteUnwinder::InternalUnwind(std::optional<pid_t> tid, AndroidUnwinderData& data) {
228 if (!tid) {
229 tid = pid_;
230 }
231
232 std::unique_ptr<Regs> regs(Regs::RemoteGet(*tid, &data.error.code));
233 if (regs == nullptr) {
234 return false;
235 }
236 return AndroidUnwinder::Unwind(regs.get(), data);
237 }
238
239 } // namespace unwindstack
240