aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Wagner <bungeman@chromium.org>2023-04-24 23:41:28 -0400
committerJoshua Peraza <jperaza@chromium.org>2023-04-28 18:35:40 +0000
commitde040fa25de948e71cef9c035ba152fa75bfe0ec (patch)
tree47ae4f32d12a026559bceeb6bb99a7dee1c726bf
parent68f5a4d11a2703f76b9c4312a4a3df699cef41d8 (diff)
downloadgoogle-breakpad-de040fa25de948e71cef9c035ba152fa75bfe0ec.tar.gz
minidump-2-core: Use exception context for crashed thread
Use the exception record's context for the crashed thread instead of the thread's own context. For the crashed thread the thread's own context is the state inside the exception handler. Using it would not result in the expected stack trace from the time of the crash. This change aligns the behavior of minidump-2-core with the behavior of minidump_stackwalk. Bug: google-breakpad:885 Change-Id: I5cd3e9d39807308491b64fcd335f5f85b1dcd084 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4473128 Reviewed-by: Joshua Peraza <jperaza@google.com> Reviewed-by: Joshua Peraza <jperaza@chromium.org>
-rw-r--r--src/tools/linux/md2core/minidump-2-core.cc42
1 files changed, 31 insertions, 11 deletions
diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc
index f12f2841..9d5e5e3f 100644
--- a/src/tools/linux/md2core/minidump-2-core.cc
+++ b/src/tools/linux/md2core/minidump-2-core.cc
@@ -282,7 +282,7 @@ typedef struct prpsinfo { /* Information about process */
// We parse the minidump file and keep the parsed information in this structure
struct CrashedProcess {
CrashedProcess()
- : crashing_tid(-1),
+ : exception{-1},
auxv(NULL),
auxv_length(0) {
memset(&prps, 0, sizeof(prps));
@@ -306,7 +306,6 @@ struct CrashedProcess {
};
std::map<uint64_t, Mapping> mappings;
- pid_t crashing_tid;
int fatal_signal;
struct Thread {
@@ -330,6 +329,7 @@ struct CrashedProcess {
size_t stack_length;
};
std::vector<Thread> threads;
+ Thread exception;
const uint8_t* auxv;
size_t auxv_length;
@@ -999,10 +999,25 @@ ParseDSODebugInfo(const Options& options, CrashedProcess* crashinfo,
static void
ParseExceptionStream(const Options& options, CrashedProcess* crashinfo,
- const MinidumpMemoryRange& range) {
+ const MinidumpMemoryRange& range,
+ const MinidumpMemoryRange& full_file) {
const MDRawExceptionStream* exp = range.GetData<MDRawExceptionStream>(0);
- crashinfo->crashing_tid = exp->thread_id;
+ if (!exp) {
+ return;
+ }
+ if (options.verbose) {
+ fprintf(stderr,
+ "MD_EXCEPTION_STREAM:\n"
+ "Found exception thread %" PRIu32 " \n"
+ "\n\n",
+ exp->thread_id);
+ }
crashinfo->fatal_signal = (int) exp->exception_record.exception_code;
+ crashinfo->exception = {};
+ crashinfo->exception.tid = exp->thread_id;
+ // crashinfo->threads[].tid == crashinfo->exception.tid provides the stack.
+ ParseThreadRegisters(&crashinfo->exception,
+ full_file.Subrange(exp->thread_context));
}
static bool
@@ -1365,7 +1380,7 @@ main(int argc, const char* argv[]) {
break;
case MD_EXCEPTION_STREAM:
ParseExceptionStream(options, &crashinfo,
- dump.Subrange(dirent->location));
+ dump.Subrange(dirent->location), dump);
break;
case MD_MODULE_LIST_STREAM:
ParseModuleStream(options, &crashinfo, dump.Subrange(dirent->location),
@@ -1481,16 +1496,21 @@ main(int argc, const char* argv[]) {
return 1;
}
- for (unsigned i = 0; i < crashinfo.threads.size(); ++i) {
- if (crashinfo.threads[i].tid == crashinfo.crashing_tid) {
- WriteThread(options, crashinfo.threads[i], crashinfo.fatal_signal);
+ for (const auto& current_thread : crashinfo.threads) {
+ if (current_thread.tid == crashinfo.exception.tid) {
+ // Use the exception record's context for the crashed thread instead of
+ // the thread's own context. For the crashed thread the thread's own
+ // context is the state inside the exception handler. Using it would not
+ // result in the expected stack trace from the time of the crash.
+ // The stack memory has already been provided by current_thread.
+ WriteThread(options, crashinfo.exception, crashinfo.fatal_signal);
break;
}
}
- for (unsigned i = 0; i < crashinfo.threads.size(); ++i) {
- if (crashinfo.threads[i].tid != crashinfo.crashing_tid)
- WriteThread(options, crashinfo.threads[i], 0);
+ for (const auto& current_thread : crashinfo.threads) {
+ if (current_thread.tid != crashinfo.exception.tid)
+ WriteThread(options, current_thread, 0);
}
if (note_align) {