Home | History | Annotate | Download | only in libbacktrace
      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