summaryrefslogtreecommitdiff
path: root/runtime/utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/utils.cc')
-rw-r--r--runtime/utils.cc212
1 files changed, 0 insertions, 212 deletions
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 3f779df15a..515ba9f9e3 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -46,20 +46,12 @@
#include <sys/syscall.h>
#endif
-// For DumpNativeStack.
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
-
#if defined(__linux__)
#include <linux/unistd.h>
#endif
namespace art {
-#if defined(__linux__)
-static constexpr bool kUseAddr2line = !kIsTargetBuild;
-#endif
-
pid_t GetTid() {
#if defined(__APPLE__)
uint64_t owner;
@@ -1026,210 +1018,6 @@ std::string GetSchedulerGroupName(pid_t tid) {
return "";
}
-#if defined(__linux__)
-
-ALWAYS_INLINE
-static inline void WritePrefix(std::ostream* os, const char* prefix, bool odd) {
- if (prefix != nullptr) {
- *os << prefix;
- }
- *os << " ";
- if (!odd) {
- *os << " ";
- }
-}
-
-static bool RunCommand(std::string cmd, std::ostream* os, const char* prefix) {
- FILE* stream = popen(cmd.c_str(), "r");
- if (stream) {
- if (os != nullptr) {
- bool odd_line = true; // We indent them differently.
- bool wrote_prefix = false; // Have we already written a prefix?
- constexpr size_t kMaxBuffer = 128; // Relatively small buffer. Should be OK as we're on an
- // alt stack, but just to be sure...
- char buffer[kMaxBuffer];
- while (!feof(stream)) {
- if (fgets(buffer, kMaxBuffer, stream) != nullptr) {
- // Split on newlines.
- char* tmp = buffer;
- for (;;) {
- char* new_line = strchr(tmp, '\n');
- if (new_line == nullptr) {
- // Print the rest.
- if (*tmp != 0) {
- if (!wrote_prefix) {
- WritePrefix(os, prefix, odd_line);
- }
- wrote_prefix = true;
- *os << tmp;
- }
- break;
- }
- if (!wrote_prefix) {
- WritePrefix(os, prefix, odd_line);
- }
- char saved = *(new_line + 1);
- *(new_line + 1) = 0;
- *os << tmp;
- *(new_line + 1) = saved;
- tmp = new_line + 1;
- odd_line = !odd_line;
- wrote_prefix = false;
- }
- }
- }
- }
- pclose(stream);
- return true;
- } else {
- return false;
- }
-}
-
-static void Addr2line(const std::string& map_src, uintptr_t offset, std::ostream& os,
- const char* prefix) {
- std::string cmdline(StringPrintf("addr2line --functions --inlines --demangle -e %s %zx",
- map_src.c_str(), offset));
- RunCommand(cmdline.c_str(), &os, prefix);
-}
-
-static bool PcIsWithinQuickCode(ArtMethod* method, uintptr_t pc) NO_THREAD_SAFETY_ANALYSIS {
- uintptr_t code = reinterpret_cast<uintptr_t>(EntryPointToCodePointer(
- method->GetEntryPointFromQuickCompiledCode()));
- if (code == 0) {
- return pc == 0;
- }
- uintptr_t code_size = reinterpret_cast<const OatQuickMethodHeader*>(code)[-1].code_size_;
- return code <= pc && pc <= (code + code_size);
-}
-#endif
-
-void DumpNativeStack(std::ostream& os, pid_t tid, BacktraceMap* existing_map, const char* prefix,
- ArtMethod* current_method, void* ucontext_ptr) {
-#if __linux__
- // b/18119146
- if (RUNNING_ON_MEMORY_TOOL != 0) {
- return;
- }
-
- BacktraceMap* map = existing_map;
- std::unique_ptr<BacktraceMap> tmp_map;
- if (map == nullptr) {
- tmp_map.reset(BacktraceMap::Create(getpid()));
- map = tmp_map.get();
- }
- std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid, map));
- if (!backtrace->Unwind(0, reinterpret_cast<ucontext*>(ucontext_ptr))) {
- os << prefix << "(backtrace::Unwind failed for thread " << tid
- << ": " << backtrace->GetErrorString(backtrace->GetError()) << ")\n";
- return;
- } else if (backtrace->NumFrames() == 0) {
- os << prefix << "(no native stack frames for thread " << tid << ")\n";
- return;
- }
-
- // Check whether we have and should use addr2line.
- bool use_addr2line;
- if (kUseAddr2line) {
- // Try to run it to see whether we have it. Push an argument so that it doesn't assume a.out
- // and print to stderr.
- use_addr2line = (gAborting > 0) && RunCommand("addr2line -h", nullptr, nullptr);
- } else {
- use_addr2line = false;
- }
-
- for (Backtrace::const_iterator it = backtrace->begin();
- it != backtrace->end(); ++it) {
- // We produce output like this:
- // ] #00 pc 000075bb8 /system/lib/libc.so (unwind_backtrace_thread+536)
- // In order for parsing tools to continue to function, the stack dump
- // format must at least adhere to this format:
- // #XX pc <RELATIVE_ADDR> <FULL_PATH_TO_SHARED_LIBRARY> ...
- // The parsers require a single space before and after pc, and two spaces
- // after the <RELATIVE_ADDR>. There can be any prefix data before the
- // #XX. <RELATIVE_ADDR> has to be a hex number but with no 0x prefix.
- os << prefix << StringPrintf("#%02zu pc ", it->num);
- bool try_addr2line = false;
- if (!BacktraceMap::IsValid(it->map)) {
- os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIxPTR " ???"
- : "%08" PRIxPTR " ???",
- it->pc);
- } else {
- os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIxPTR " "
- : "%08" PRIxPTR " ",
- BacktraceMap::GetRelativePc(it->map, it->pc));
- os << it->map.name;
- os << " (";
- if (!it->func_name.empty()) {
- os << it->func_name;
- if (it->func_offset != 0) {
- os << "+" << it->func_offset;
- }
- try_addr2line = true;
- } else if (current_method != nullptr &&
- Locks::mutator_lock_->IsSharedHeld(Thread::Current()) &&
- PcIsWithinQuickCode(current_method, it->pc)) {
- const void* start_of_code = current_method->GetEntryPointFromQuickCompiledCode();
- os << JniLongName(current_method) << "+"
- << (it->pc - reinterpret_cast<uintptr_t>(start_of_code));
- } else {
- os << "???";
- }
- os << ")";
- }
- os << "\n";
- if (try_addr2line && use_addr2line) {
- Addr2line(it->map.name, it->pc - it->map.start, os, prefix);
- }
- }
-#else
- UNUSED(os, tid, existing_map, prefix, current_method, ucontext_ptr);
-#endif
-}
-
-#if defined(__APPLE__)
-
-// TODO: is there any way to get the kernel stack on Mac OS?
-void DumpKernelStack(std::ostream&, pid_t, const char*, bool) {}
-
-#else
-
-void DumpKernelStack(std::ostream& os, pid_t tid, const char* prefix, bool include_count) {
- if (tid == GetTid()) {
- // There's no point showing that we're reading our stack out of /proc!
- return;
- }
-
- std::string kernel_stack_filename(StringPrintf("/proc/self/task/%d/stack", tid));
- std::string kernel_stack;
- if (!ReadFileToString(kernel_stack_filename, &kernel_stack)) {
- os << prefix << "(couldn't read " << kernel_stack_filename << ")\n";
- return;
- }
-
- std::vector<std::string> kernel_stack_frames;
- Split(kernel_stack, '\n', &kernel_stack_frames);
- // We skip the last stack frame because it's always equivalent to "[<ffffffff>] 0xffffffff",
- // which looking at the source appears to be the kernel's way of saying "that's all, folks!".
- kernel_stack_frames.pop_back();
- for (size_t i = 0; i < kernel_stack_frames.size(); ++i) {
- // Turn "[<ffffffff8109156d>] futex_wait_queue_me+0xcd/0x110"
- // into "futex_wait_queue_me+0xcd/0x110".
- const char* text = kernel_stack_frames[i].c_str();
- const char* close_bracket = strchr(text, ']');
- if (close_bracket != nullptr) {
- text = close_bracket + 2;
- }
- os << prefix;
- if (include_count) {
- os << StringPrintf("#%02zd ", i);
- }
- os << text << "\n";
- }
-}
-
-#endif
-
const char* GetAndroidRoot() {
const char* android_root = getenv("ANDROID_ROOT");
if (android_root == nullptr) {