• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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