diff options
| -rw-r--r-- | tools/timeout_dumper/timeout_dumper.cc | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/tools/timeout_dumper/timeout_dumper.cc b/tools/timeout_dumper/timeout_dumper.cc index 5de284b948..e04aefb26c 100644 --- a/tools/timeout_dumper/timeout_dumper.cc +++ b/tools/timeout_dumper/timeout_dumper.cc @@ -370,6 +370,91 @@ std::set<pid_t> PtraceSiblings(pid_t pid) { 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 DumpThread(pid_t pid, } 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) { |