Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2016 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 "native_stack_dump.h"
     18 
     19 #include <ostream>
     20 
     21 #include <stdio.h>
     22 
     23 #include "art_method.h"
     24 
     25 // For DumpNativeStack.
     26 #include <backtrace/Backtrace.h>
     27 #include <backtrace/BacktraceMap.h>
     28 
     29 #if defined(__linux__)
     30 
     31 #include <memory>
     32 #include <vector>
     33 
     34 #include <linux/unistd.h>
     35 #include <signal.h>
     36 #include <stdlib.h>
     37 #include <sys/time.h>
     38 #include <sys/types.h>
     39 
     40 #include "android-base/stringprintf.h"
     41 
     42 #include "arch/instruction_set.h"
     43 #include "base/memory_tool.h"
     44 #include "base/mutex.h"
     45 #include "base/unix_file/fd_file.h"
     46 #include "oat_quick_method_header.h"
     47 #include "os.h"
     48 #include "thread-inl.h"
     49 #include "utils.h"
     50 
     51 #endif
     52 
     53 namespace art {
     54 
     55 #if defined(__linux__)
     56 
     57 using android::base::StringPrintf;
     58 
     59 static constexpr bool kUseAddr2line = !kIsTargetBuild;
     60 
     61 ALWAYS_INLINE
     62 static inline void WritePrefix(std::ostream& os, const char* prefix, bool odd) {
     63   if (prefix != nullptr) {
     64     os << prefix;
     65   }
     66   os << "  ";
     67   if (!odd) {
     68     os << " ";
     69   }
     70 }
     71 
     72 // The state of an open pipe to addr2line. In "server" mode, addr2line takes input on stdin
     73 // and prints the result to stdout. This struct keeps the state of the open connection.
     74 struct Addr2linePipe {
     75   Addr2linePipe(int in_fd, int out_fd, const std::string& file_name, pid_t pid)
     76       : in(in_fd, false), out(out_fd, false), file(file_name), child_pid(pid), odd(true) {}
     77 
     78   ~Addr2linePipe() {
     79     kill(child_pid, SIGKILL);
     80   }
     81 
     82   File in;      // The file descriptor that is connected to the output of addr2line.
     83   File out;     // The file descriptor that is connected to the input of addr2line.
     84 
     85   const std::string file;     // The file addr2line is working on, so that we know when to close
     86                               // and restart.
     87   const pid_t child_pid;      // The pid of the child, which we should kill when we're done.
     88   bool odd;                   // Print state for indentation of lines.
     89 };
     90 
     91 static std::unique_ptr<Addr2linePipe> Connect(const std::string& name, const char* args[]) {
     92   int caller_to_addr2line[2];
     93   int addr2line_to_caller[2];
     94 
     95   if (pipe(caller_to_addr2line) == -1) {
     96     return nullptr;
     97   }
     98   if (pipe(addr2line_to_caller) == -1) {
     99     close(caller_to_addr2line[0]);
    100     close(caller_to_addr2line[1]);
    101     return nullptr;
    102   }
    103 
    104   pid_t pid = fork();
    105   if (pid == -1) {
    106     close(caller_to_addr2line[0]);
    107     close(caller_to_addr2line[1]);
    108     close(addr2line_to_caller[0]);
    109     close(addr2line_to_caller[1]);
    110     return nullptr;
    111   }
    112 
    113   if (pid == 0) {
    114     dup2(caller_to_addr2line[0], STDIN_FILENO);
    115     dup2(addr2line_to_caller[1], STDOUT_FILENO);
    116 
    117     close(caller_to_addr2line[0]);
    118     close(caller_to_addr2line[1]);
    119     close(addr2line_to_caller[0]);
    120     close(addr2line_to_caller[1]);
    121 
    122     execv(args[0], const_cast<char* const*>(args));
    123     exit(1);
    124   } else {
    125     close(caller_to_addr2line[0]);
    126     close(addr2line_to_caller[1]);
    127     return std::unique_ptr<Addr2linePipe>(new Addr2linePipe(addr2line_to_caller[0],
    128                                                             caller_to_addr2line[1],
    129                                                             name,
    130                                                             pid));
    131   }
    132 }
    133 
    134 static void Drain(size_t expected,
    135                   const char* prefix,
    136                   std::unique_ptr<Addr2linePipe>* pipe /* inout */,
    137                   std::ostream& os) {
    138   DCHECK(pipe != nullptr);
    139   DCHECK(pipe->get() != nullptr);
    140   int in = pipe->get()->in.Fd();
    141   DCHECK_GE(in, 0);
    142 
    143   bool prefix_written = false;
    144 
    145   for (;;) {
    146     constexpr uint32_t kWaitTimeExpectedMicros = 500 * 1000;
    147     constexpr uint32_t kWaitTimeUnexpectedMicros = 50 * 1000;
    148 
    149     struct timeval tv;
    150     tv.tv_sec = 0;
    151     tv.tv_usec = expected > 0 ? kWaitTimeExpectedMicros : kWaitTimeUnexpectedMicros;
    152 
    153     fd_set rfds;
    154     FD_ZERO(&rfds);
    155     FD_SET(in, &rfds);
    156 
    157     int retval = TEMP_FAILURE_RETRY(select(in + 1, &rfds, nullptr, nullptr, &tv));
    158 
    159     if (retval < 0) {
    160       // Other side may have crashed or other errors.
    161       pipe->reset();
    162       return;
    163     }
    164 
    165     if (retval == 0) {
    166       // Timeout.
    167       return;
    168     }
    169 
    170     DCHECK_EQ(retval, 1);
    171 
    172     constexpr size_t kMaxBuffer = 128;  // Relatively small buffer. Should be OK as we're on an
    173     // alt stack, but just to be sure...
    174     char buffer[kMaxBuffer];
    175     memset(buffer, 0, kMaxBuffer);
    176     int bytes_read = TEMP_FAILURE_RETRY(read(in, buffer, kMaxBuffer - 1));
    177 
    178     if (bytes_read < 0) {
    179       // This should not really happen...
    180       pipe->reset();
    181       return;
    182     }
    183 
    184     char* tmp = buffer;
    185     while (*tmp != 0) {
    186       if (!prefix_written) {
    187         WritePrefix(os, prefix, (*pipe)->odd);
    188         prefix_written = true;
    189       }
    190       char* new_line = strchr(tmp, '\n');
    191       if (new_line == nullptr) {
    192         os << tmp;
    193 
    194         break;
    195       } else {
    196         char saved = *(new_line + 1);
    197         *(new_line + 1) = 0;
    198         os << tmp;
    199         *(new_line + 1) = saved;
    200 
    201         tmp = new_line + 1;
    202         prefix_written = false;
    203         (*pipe)->odd = !(*pipe)->odd;
    204 
    205         if (expected > 0) {
    206           expected--;
    207         }
    208       }
    209     }
    210   }
    211 }
    212 
    213 static void Addr2line(const std::string& map_src,
    214                       uintptr_t offset,
    215                       std::ostream& os,
    216                       const char* prefix,
    217                       std::unique_ptr<Addr2linePipe>* pipe /* inout */) {
    218   DCHECK(pipe != nullptr);
    219 
    220   if (map_src == "[vdso]") {
    221     // Special-case this, our setup has problems with this.
    222     return;
    223   }
    224 
    225   if (*pipe == nullptr || (*pipe)->file != map_src) {
    226     if (*pipe != nullptr) {
    227       Drain(0, prefix, pipe, os);
    228     }
    229     pipe->reset();  // Close early.
    230 
    231     const char* args[7] = {
    232         "/usr/bin/addr2line",
    233         "--functions",
    234         "--inlines",
    235         "--demangle",
    236         "-e",
    237         map_src.c_str(),
    238         nullptr
    239     };
    240     *pipe = Connect(map_src, args);
    241   }
    242 
    243   Addr2linePipe* pipe_ptr = pipe->get();
    244   if (pipe_ptr == nullptr) {
    245     // Failed...
    246     return;
    247   }
    248 
    249   // Send the offset.
    250   const std::string hex_offset = StringPrintf("%zx\n", offset);
    251 
    252   if (!pipe_ptr->out.WriteFully(hex_offset.data(), hex_offset.length())) {
    253     // Error. :-(
    254     pipe->reset();
    255     return;
    256   }
    257 
    258   // Now drain (expecting two lines).
    259   Drain(2U, prefix, pipe, os);
    260 }
    261 
    262 static bool RunCommand(const std::string& cmd) {
    263   FILE* stream = popen(cmd.c_str(), "r");
    264   if (stream) {
    265     pclose(stream);
    266     return true;
    267   } else {
    268     return false;
    269   }
    270 }
    271 
    272 static bool PcIsWithinQuickCode(ArtMethod* method, uintptr_t pc) NO_THREAD_SAFETY_ANALYSIS {
    273   uintptr_t code = reinterpret_cast<uintptr_t>(EntryPointToCodePointer(
    274       method->GetEntryPointFromQuickCompiledCode()));
    275   if (code == 0) {
    276     return pc == 0;
    277   }
    278   uintptr_t code_size = reinterpret_cast<const OatQuickMethodHeader*>(code)[-1].GetCodeSize();
    279   return code <= pc && pc <= (code + code_size);
    280 }
    281 
    282 void DumpNativeStack(std::ostream& os,
    283                      pid_t tid,
    284                      BacktraceMap* existing_map,
    285                      const char* prefix,
    286                      ArtMethod* current_method,
    287                      void* ucontext_ptr) {
    288   // b/18119146
    289   if (RUNNING_ON_MEMORY_TOOL != 0) {
    290     return;
    291   }
    292 
    293   BacktraceMap* map = existing_map;
    294   std::unique_ptr<BacktraceMap> tmp_map;
    295   if (map == nullptr) {
    296     tmp_map.reset(BacktraceMap::Create(getpid()));
    297     map = tmp_map.get();
    298   }
    299   std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid, map));
    300   if (!backtrace->Unwind(0, reinterpret_cast<ucontext*>(ucontext_ptr))) {
    301     os << prefix << "(backtrace::Unwind failed for thread " << tid
    302        << ": " <<  backtrace->GetErrorString(backtrace->GetError()) << ")" << std::endl;
    303     return;
    304   } else if (backtrace->NumFrames() == 0) {
    305     os << prefix << "(no native stack frames for thread " << tid << ")" << std::endl;
    306     return;
    307   }
    308 
    309   // Check whether we have and should use addr2line.
    310   bool use_addr2line;
    311   if (kUseAddr2line) {
    312     // Try to run it to see whether we have it. Push an argument so that it doesn't assume a.out
    313     // and print to stderr.
    314     use_addr2line = (gAborting > 0) && RunCommand("addr2line -h");
    315   } else {
    316     use_addr2line = false;
    317   }
    318 
    319   std::unique_ptr<Addr2linePipe> addr2line_state;
    320 
    321   for (Backtrace::const_iterator it = backtrace->begin();
    322        it != backtrace->end(); ++it) {
    323     // We produce output like this:
    324     // ]    #00 pc 000075bb8  /system/lib/libc.so (unwind_backtrace_thread+536)
    325     // In order for parsing tools to continue to function, the stack dump
    326     // format must at least adhere to this format:
    327     //  #XX pc <RELATIVE_ADDR>  <FULL_PATH_TO_SHARED_LIBRARY> ...
    328     // The parsers require a single space before and after pc, and two spaces
    329     // after the <RELATIVE_ADDR>. There can be any prefix data before the
    330     // #XX. <RELATIVE_ADDR> has to be a hex number but with no 0x prefix.
    331     os << prefix << StringPrintf("#%02zu pc ", it->num);
    332     bool try_addr2line = false;
    333     if (!BacktraceMap::IsValid(it->map)) {
    334       os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIxPTR "  ???"
    335                                                             : "%08" PRIxPTR "  ???",
    336                          it->pc);
    337     } else {
    338       os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIxPTR "  "
    339                                                             : "%08" PRIxPTR "  ",
    340                          BacktraceMap::GetRelativePc(it->map, it->pc));
    341       os << it->map.name;
    342       os << " (";
    343       if (!it->func_name.empty()) {
    344         os << it->func_name;
    345         if (it->func_offset != 0) {
    346           os << "+" << it->func_offset;
    347         }
    348         try_addr2line = true;
    349       } else if (current_method != nullptr &&
    350           Locks::mutator_lock_->IsSharedHeld(Thread::Current()) &&
    351           PcIsWithinQuickCode(current_method, it->pc)) {
    352         const void* start_of_code = current_method->GetEntryPointFromQuickCompiledCode();
    353         os << current_method->JniLongName() << "+"
    354            << (it->pc - reinterpret_cast<uintptr_t>(start_of_code));
    355       } else {
    356         os << "???";
    357       }
    358       os << ")";
    359     }
    360     os << std::endl;
    361     if (try_addr2line && use_addr2line) {
    362       Addr2line(it->map.name, it->pc - it->map.start, os, prefix, &addr2line_state);
    363     }
    364   }
    365 
    366   if (addr2line_state != nullptr) {
    367     Drain(0, prefix, &addr2line_state, os);
    368   }
    369 }
    370 
    371 void DumpKernelStack(std::ostream& os, pid_t tid, const char* prefix, bool include_count) {
    372   if (tid == GetTid()) {
    373     // There's no point showing that we're reading our stack out of /proc!
    374     return;
    375   }
    376 
    377   std::string kernel_stack_filename(StringPrintf("/proc/self/task/%d/stack", tid));
    378   std::string kernel_stack;
    379   if (!ReadFileToString(kernel_stack_filename, &kernel_stack)) {
    380     os << prefix << "(couldn't read " << kernel_stack_filename << ")\n";
    381     return;
    382   }
    383 
    384   std::vector<std::string> kernel_stack_frames;
    385   Split(kernel_stack, '\n', &kernel_stack_frames);
    386   // We skip the last stack frame because it's always equivalent to "[<ffffffff>] 0xffffffff",
    387   // which looking at the source appears to be the kernel's way of saying "that's all, folks!".
    388   kernel_stack_frames.pop_back();
    389   for (size_t i = 0; i < kernel_stack_frames.size(); ++i) {
    390     // Turn "[<ffffffff8109156d>] futex_wait_queue_me+0xcd/0x110"
    391     // into "futex_wait_queue_me+0xcd/0x110".
    392     const char* text = kernel_stack_frames[i].c_str();
    393     const char* close_bracket = strchr(text, ']');
    394     if (close_bracket != nullptr) {
    395       text = close_bracket + 2;
    396     }
    397     os << prefix;
    398     if (include_count) {
    399       os << StringPrintf("#%02zd ", i);
    400     }
    401     os << text << std::endl;
    402   }
    403 }
    404 
    405 #elif defined(__APPLE__)
    406 
    407 void DumpNativeStack(std::ostream& os ATTRIBUTE_UNUSED,
    408                      pid_t tid ATTRIBUTE_UNUSED,
    409                      BacktraceMap* existing_map ATTRIBUTE_UNUSED,
    410                      const char* prefix ATTRIBUTE_UNUSED,
    411                      ArtMethod* current_method ATTRIBUTE_UNUSED,
    412                      void* ucontext_ptr ATTRIBUTE_UNUSED) {
    413 }
    414 
    415 void DumpKernelStack(std::ostream& os ATTRIBUTE_UNUSED,
    416                      pid_t tid ATTRIBUTE_UNUSED,
    417                      const char* prefix ATTRIBUTE_UNUSED,
    418                      bool include_count ATTRIBUTE_UNUSED) {
    419 }
    420 
    421 #else
    422 #error "Unsupported architecture for native stack dumps."
    423 #endif
    424 
    425 }  // namespace art
    426