1 /* 2 * Copyright (C) 2017 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 #define _GNU_SOURCE 1 18 #include <stdint.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <memory> 23 #include <set> 24 #include <string> 25 26 #if !defined(__ANDROID__) 27 #include <cutils/threads.h> 28 #endif 29 30 #include <backtrace/Backtrace.h> 31 #include <demangle.h> 32 #include <unwindstack/Elf.h> 33 #include <unwindstack/MapInfo.h> 34 #include <unwindstack/Maps.h> 35 #include <unwindstack/Memory.h> 36 #include <unwindstack/Regs.h> 37 #include <unwindstack/RegsGetLocal.h> 38 39 #if !defined(NO_LIBDEXFILE_SUPPORT) 40 #include <unwindstack/DexFiles.h> 41 #endif 42 #include <unwindstack/Unwinder.h> 43 44 #include "BacktraceLog.h" 45 #include "UnwindStack.h" 46 #include "UnwindStackMap.h" 47 48 bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, 49 std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames, 50 std::vector<std::string>* skip_names, BacktraceUnwindError* error) { 51 UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map); 52 auto process_memory = stack_map->process_memory(); 53 unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(), 54 regs, stack_map->process_memory()); 55 unwinder.SetResolveNames(stack_map->ResolveNames()); 56 if (stack_map->GetJitDebug() != nullptr) { 57 unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch()); 58 } 59 #if !defined(NO_LIBDEXFILE_SUPPORT) 60 if (stack_map->GetDexFiles() != nullptr) { 61 unwinder.SetDexFiles(stack_map->GetDexFiles(), regs->Arch()); 62 } 63 #endif 64 unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore()); 65 if (error != nullptr) { 66 switch (unwinder.LastErrorCode()) { 67 case unwindstack::ERROR_NONE: 68 error->error_code = BACKTRACE_UNWIND_NO_ERROR; 69 break; 70 71 case unwindstack::ERROR_MEMORY_INVALID: 72 error->error_code = BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED; 73 error->error_info.addr = unwinder.LastErrorAddress(); 74 break; 75 76 case unwindstack::ERROR_UNWIND_INFO: 77 error->error_code = BACKTRACE_UNWIND_ERROR_UNWIND_INFO; 78 break; 79 80 case unwindstack::ERROR_UNSUPPORTED: 81 error->error_code = BACKTRACE_UNWIND_ERROR_UNSUPPORTED_OPERATION; 82 break; 83 84 case unwindstack::ERROR_INVALID_MAP: 85 error->error_code = BACKTRACE_UNWIND_ERROR_MAP_MISSING; 86 break; 87 88 case unwindstack::ERROR_MAX_FRAMES_EXCEEDED: 89 error->error_code = BACKTRACE_UNWIND_ERROR_EXCEED_MAX_FRAMES_LIMIT; 90 break; 91 92 case unwindstack::ERROR_REPEATED_FRAME: 93 error->error_code = BACKTRACE_UNWIND_ERROR_REPEATED_FRAME; 94 break; 95 } 96 } 97 98 if (num_ignore_frames >= unwinder.NumFrames()) { 99 frames->resize(0); 100 return true; 101 } 102 103 auto unwinder_frames = unwinder.frames(); 104 frames->resize(unwinder.NumFrames() - num_ignore_frames); 105 size_t cur_frame = 0; 106 for (size_t i = num_ignore_frames; i < unwinder.NumFrames(); i++) { 107 auto frame = &unwinder_frames[i]; 108 109 backtrace_frame_data_t* back_frame = &frames->at(cur_frame); 110 111 back_frame->num = cur_frame++; 112 113 back_frame->rel_pc = frame->rel_pc; 114 back_frame->pc = frame->pc; 115 back_frame->sp = frame->sp; 116 117 back_frame->func_name = demangle(frame->function_name.c_str()); 118 back_frame->func_offset = frame->function_offset; 119 120 back_frame->map.name = frame->map_name; 121 back_frame->map.start = frame->map_start; 122 back_frame->map.end = frame->map_end; 123 back_frame->map.offset = frame->map_offset; 124 back_frame->map.load_bias = frame->map_load_bias; 125 back_frame->map.flags = frame->map_flags; 126 } 127 128 return true; 129 } 130 131 bool Backtrace::UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map, 132 const backtrace_stackinfo_t& stack, 133 std::vector<backtrace_frame_data_t>* frames, 134 BacktraceUnwindError* error) { 135 UnwindStackOfflineMap* offline_map = reinterpret_cast<UnwindStackOfflineMap*>(back_map); 136 // Create the process memory from the stack data since this will almost 137 // always be different each unwind. 138 if (!offline_map->CreateProcessMemory(stack)) { 139 if (error != nullptr) { 140 error->error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; 141 } 142 return false; 143 } 144 return Backtrace::Unwind(regs, back_map, frames, 0U, nullptr, error); 145 } 146 147 UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map) 148 : BacktraceCurrent(pid, tid, map) {} 149 150 std::string UnwindStackCurrent::GetFunctionNameRaw(uint64_t pc, uint64_t* offset) { 151 return GetMap()->GetFunctionName(pc, offset); 152 } 153 154 bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, void* ucontext) { 155 std::unique_ptr<unwindstack::Regs> regs; 156 if (ucontext == nullptr) { 157 regs.reset(unwindstack::Regs::CreateFromLocal()); 158 // Fill in the registers from this function. Do it here to avoid 159 // one extra function call appearing in the unwind. 160 unwindstack::RegsGetLocal(regs.get()); 161 } else { 162 regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext)); 163 } 164 165 std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"}; 166 if (!skip_frames_) { 167 skip_names.clear(); 168 } 169 return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names, &error_); 170 } 171 172 UnwindStackPtrace::UnwindStackPtrace(pid_t pid, pid_t tid, BacktraceMap* map) 173 : BacktracePtrace(pid, tid, map), memory_(pid) {} 174 175 std::string UnwindStackPtrace::GetFunctionNameRaw(uint64_t pc, uint64_t* offset) { 176 return GetMap()->GetFunctionName(pc, offset); 177 } 178 179 bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, void* context) { 180 std::unique_ptr<unwindstack::Regs> regs; 181 if (context == nullptr) { 182 regs.reset(unwindstack::Regs::RemoteGet(Tid())); 183 } else { 184 regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), context)); 185 } 186 187 return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, nullptr, &error_); 188 } 189 190 size_t UnwindStackPtrace::Read(uint64_t addr, uint8_t* buffer, size_t bytes) { 191 return memory_.Read(addr, buffer, bytes); 192 } 193 194 UnwindStackOffline::UnwindStackOffline(ArchEnum arch, pid_t pid, pid_t tid, BacktraceMap* map, 195 bool map_shared) 196 : Backtrace(pid, tid, map), arch_(arch) { 197 map_shared_ = map_shared; 198 } 199 200 bool UnwindStackOffline::Unwind(size_t num_ignore_frames, void* ucontext) { 201 if (ucontext == nullptr) { 202 return false; 203 } 204 205 unwindstack::ArchEnum arch; 206 switch (arch_) { 207 case ARCH_ARM: 208 arch = unwindstack::ARCH_ARM; 209 break; 210 case ARCH_ARM64: 211 arch = unwindstack::ARCH_ARM64; 212 break; 213 case ARCH_X86: 214 arch = unwindstack::ARCH_X86; 215 break; 216 case ARCH_X86_64: 217 arch = unwindstack::ARCH_X86_64; 218 break; 219 default: 220 return false; 221 } 222 223 std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromUcontext(arch, ucontext)); 224 225 return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, nullptr, &error_); 226 } 227 228 std::string UnwindStackOffline::GetFunctionNameRaw(uint64_t, uint64_t*) { 229 return ""; 230 } 231 232 size_t UnwindStackOffline::Read(uint64_t, uint8_t*, size_t) { 233 return 0; 234 } 235 236 bool UnwindStackOffline::ReadWord(uint64_t, word_t*) { 237 return false; 238 } 239 240 Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid, 241 const std::vector<backtrace_map_t>& maps, 242 const backtrace_stackinfo_t& stack) { 243 std::unique_ptr<UnwindStackOfflineMap> map( 244 reinterpret_cast<UnwindStackOfflineMap*>(BacktraceMap::CreateOffline(pid, maps))); 245 if (map.get() == nullptr || !map->CreateProcessMemory(stack)) { 246 return nullptr; 247 } 248 return new UnwindStackOffline(arch, pid, tid, map.release(), false); 249 } 250 251 Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid, BacktraceMap* map) { 252 if (map == nullptr) { 253 return nullptr; 254 } 255 return new UnwindStackOffline(arch, pid, tid, map, true); 256 } 257 258 void Backtrace::SetGlobalElfCache(bool enable) { 259 unwindstack::Elf::SetCachingEnabled(enable); 260 } 261