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-current-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 it->rel_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