diff --git a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s b/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s --- a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s +++ b/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s @@ -2,7 +2,7 @@ # RUN: llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess | FileCheck %s -# CHECK: error: 'The benchmarking subprocess sent unexpected signal: Segmentation fault' +# CHECK: error: A segmentation fault occurred at address 20000 -# LLVM-EXEGESIS-DEFREG RBX 0 +# LLVM-EXEGESIS-DEFREG RBX 20000 movq (%rbx), %rax diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -334,6 +334,9 @@ Twine(strerror(errno))); } + if (ChildSignalInfo.si_signo == SIGSEGV) + return make_error(ChildSignalInfo.si_addr); + return make_error( "The benchmarking subprocess sent unexpected signal: " + Twine(strsignal(ChildSignalInfo.si_signo))); @@ -526,7 +529,7 @@ auto NewMeasurements = runMeasurements(**Executor); if (Error E = NewMeasurements.takeError()) { - if (!E.isA()) + if (!E.isA() && !E.isA()) return std::move(E); InstrBenchmark.Error = toString(std::move(E)); return std::move(InstrBenchmark); diff --git a/llvm/tools/llvm-exegesis/lib/Error.h b/llvm/tools/llvm-exegesis/lib/Error.h --- a/llvm/tools/llvm-exegesis/lib/Error.h +++ b/llvm/tools/llvm-exegesis/lib/Error.h @@ -51,6 +51,21 @@ std::string Msg; }; +// A class representing segmentation faults specifically. Holds information +// about where specifically the segmentation fault occurred. +class SnippetSegfaultCrash : public ErrorInfo { +public: + static char ID; + SnippetSegfaultCrash(const void *Addr) : Address((intptr_t)Addr) {} + + void log(raw_ostream &OS) const override; + + std::error_code convertToErrorCode() const override; + +private: + intptr_t Address; +}; + } // namespace exegesis } // namespace llvm diff --git a/llvm/tools/llvm-exegesis/lib/Error.cpp b/llvm/tools/llvm-exegesis/lib/Error.cpp --- a/llvm/tools/llvm-exegesis/lib/Error.cpp +++ b/llvm/tools/llvm-exegesis/lib/Error.cpp @@ -27,5 +27,15 @@ return inconvertibleErrorCode(); } +char SnippetSegfaultCrash::ID; + +void SnippetSegfaultCrash::log(raw_ostream &OS) const { + OS << "A segmentation fault occurred at address " + Twine::utohexstr(Address); +} + +std::error_code SnippetSegfaultCrash::convertToErrorCode() const { + return inconvertibleErrorCode(); +} + } // namespace exegesis } // namespace llvm