ART: Add ABI dumping to timeout_dumper
This allows to run the output through stack.
Test: manual
Change-Id: I64659916e00ab0135623e83f34b2f0ae8fcccfeb
diff --git a/tools/timeout_dumper/timeout_dumper.cc b/tools/timeout_dumper/timeout_dumper.cc
index 5de284b..e04aefb 100644
--- a/tools/timeout_dumper/timeout_dumper.cc
+++ b/tools/timeout_dumper/timeout_dumper.cc
@@ -370,6 +370,91 @@
return ret;
}
+void DumpABI(pid_t forked_pid) {
+ enum class ABI { kArm, kArm64, kMips, kMips64, kX86, kX86_64 };
+#if defined(__arm__)
+ constexpr ABI kDumperABI = ABI::kArm;
+#elif defined(__aarch64__)
+ constexpr ABI kDumperABI = ABI::kArm64;
+#elif defined(__mips__) && !defined(__LP64__)
+ constexpr ABI kDumperABI = ABI::kMips;
+#elif defined(__mips__) && defined(__LP64__)
+ constexpr ABI kDumperABI = ABI::kMips64;
+#elif defined(__i386__)
+ constexpr ABI kDumperABI = ABI::kX86;
+#elif defined(__x86_64__)
+ constexpr ABI kDumperABI = ABI::kX86_64;
+#else
+#error Unsupported architecture
+#endif
+
+ char data[1024]; // Should be more than enough.
+ struct iovec io_vec;
+ io_vec.iov_base = &data;
+ io_vec.iov_len = 1024;
+ ABI to_print;
+ if (0 != ::ptrace(PTRACE_GETREGSET, forked_pid, /* NT_PRSTATUS */ 1, &io_vec)) {
+ LOG(ERROR) << "Could not get registers to determine abi.";
+ // Use 64-bit as default.
+ switch (kDumperABI) {
+ case ABI::kArm:
+ case ABI::kArm64:
+ to_print = ABI::kArm64;
+ break;
+ case ABI::kMips:
+ case ABI::kMips64:
+ to_print = ABI::kMips64;
+ break;
+ case ABI::kX86:
+ case ABI::kX86_64:
+ to_print = ABI::kX86_64;
+ break;
+ default:
+ __builtin_unreachable();
+ }
+ } else {
+ // Check the length of the data. Assume that it's the same arch as the tool.
+ switch (kDumperABI) {
+ case ABI::kArm:
+ case ABI::kArm64:
+ to_print = io_vec.iov_len == 18 * sizeof(uint32_t) ? ABI::kArm : ABI::kArm64;
+ break;
+ case ABI::kMips:
+ case ABI::kMips64:
+ to_print = ABI::kMips64; // TODO Figure out how this should work.
+ break;
+ case ABI::kX86:
+ case ABI::kX86_64:
+ to_print = io_vec.iov_len == 17 * sizeof(uint32_t) ? ABI::kX86 : ABI::kX86_64;
+ break;
+ default:
+ __builtin_unreachable();
+ }
+ }
+ std::string abi_str;
+ switch (to_print) {
+ case ABI::kArm:
+ abi_str = "arm";
+ break;
+ case ABI::kArm64:
+ abi_str = "arm64";
+ break;
+ case ABI::kMips:
+ abi_str = "mips";
+ break;
+ case ABI::kMips64:
+ abi_str = "mips64";
+ break;
+ case ABI::kX86:
+ abi_str = "x86";
+ break;
+ case ABI::kX86_64:
+ abi_str = "x86_64";
+ break;
+ }
+ std::cerr << "ABI: '" << abi_str << "'" << std::endl;
+}
+
} // namespace ptrace
template <typename T>
@@ -509,10 +594,14 @@
}
void DumpProcess(pid_t forked_pid, const std::atomic<bool>& saw_wif_stopped_for_main) {
+ LOG(ERROR) << "Timeout for process " << forked_pid;
+
CHECK_EQ(0, ::ptrace(PTRACE_ATTACH, forked_pid, 0, 0));
std::set<pid_t> tids = ptrace::PtraceSiblings(forked_pid);
tids.insert(forked_pid);
+ ptrace::DumpABI(forked_pid);
+
// Check whether we have and should use addr2line.
std::unique_ptr<std::string> addr2line_path;
if (kUseAddr2line) {