Allow breakpad to read extended x86 contexts

Minidumps can contain extended contexts with xstate data for amd64 and
x86.

Support for amd64 contexts was added in
fe35cd43f2.

With this change, breakpad can now read x86 minidumps that contain
extended xstate data. Similar to the previously mentioned commit, this
change does not yet add processing for this extra data, but will allow
the minidumps to be read.

Change-Id: Ie96e91168def774092e05908535a70fc5e2427e9
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5154022
Reviewed-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
Nathan Moinvaziri 2024-01-03 12:34:03 -08:00 committed by Mike Frysinger
parent 225ed9172e
commit 7fb7589914
3 changed files with 42 additions and 3 deletions

View file

@ -817,9 +817,19 @@ bool MinidumpContext::Read(uint32_t expected_size) {
switch (cpu_type) {
case MD_CONTEXT_X86: {
if (expected_size != sizeof(MDRawContextX86)) {
BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " <<
expected_size << " != " << sizeof(MDRawContextX86);
return false;
// Context may include xsave registers and so be larger than
// sizeof(MDRawContextX86). For now we skip this extended data.
if (context_flags & MD_CONTEXT_X86_XSTATE) {
size_t bytes_left = expected_size - sizeof(MDRawContextX86);
if (bytes_left > kMaxXSaveAreaSize) {
BPLOG(ERROR) << "MinidumpContext oversized xstate area";
return false;
}
} else {
BPLOG(ERROR) << "MinidumpContext x86 size mismatch, "
<< expected_size << " != " << sizeof(MDRawContextX86);
return false;
}
}
scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86());
@ -885,6 +895,12 @@ bool MinidumpContext::Read(uint32_t expected_size) {
SetContextX86(context_x86.release());
// Skip extended xstate data if present in X86 context.
if (context_flags & MD_CONTEXT_X86_XSTATE) {
minidump_->SeekSet((minidump_->Tell() - sizeof(MDRawContextX86)) +
expected_size);
}
break;
}

View file

@ -764,6 +764,29 @@ TEST_F(MinidumpProcessorTest, Test32BitCrashingAddress) {
ASSERT_EQ(state.crash_address(), 0x45U);
}
TEST_F(MinidumpProcessorTest, TestXStateX86ContextMinidump) {
// This tests if we can passively process a minidump with cet registers in its
// context. Dump is captured from a toy executable and is readable by windbg.
MinidumpProcessor processor(nullptr, nullptr /*&supplier, &resolver*/);
string minidump_file = GetTestDataPath()
+ "tiny-exe-with-cet-xsave-x86.dmp";
ProcessState state;
ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_OK);
ASSERT_EQ(state.system_info()->os, "Windows NT");
ASSERT_EQ(state.system_info()->os_version, "10.0.22631 ");
ASSERT_EQ(state.system_info()->cpu, "x86");
ASSERT_EQ(state.system_info()->cpu_info,
"GenuineIntel family 6 model 151 stepping 2");
ASSERT_FALSE(state.crashed());
ASSERT_EQ(state.threads()->size(), size_t(3));
// TODO: verify cetumsr and cetussp once these are supported by
// breakpad.
}
TEST_F(MinidumpProcessorTest, TestXStateAmd64ContextMinidump) {
// This tests if we can passively process a minidump with cet registers in its
// context. Dump is captured from a toy executable and is readable by windbg.

Binary file not shown.