Adjust MD_CONTEXT_CPU_MASK to reflect reality, fix some code so it can handle dumps using the old value for MD_CONTEXT_ARM

The value of MD_CONTEXT_CPU_MASK in use assumes that only the lower 6 bits are used for flags, and the upper 26 bits are for the CPU type. However, as of Windows 7 SP1, the 7th bit is being used as a flag (per http://msdn.microsoft.com/en-us/library/hh134238%28v=vs.85%29.aspx and the Windows SDK headers). Adjusting MD_CONTEXT_CPU_MASK works, but unfortunately that masks off the existing value of MD_CONTEXT_ARM. This patch also changes the value of MD_CONTEXT_ARM and adjusts the minidump context reading machinery to gracefully handle minidumps with the old value.
R=mark at http://breakpad.appspot.com/302001

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@831 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek 2011-08-30 22:22:08 +00:00
parent 8ade75f955
commit 1a1890a52a
10 changed files with 658 additions and 42 deletions

View file

@ -410,6 +410,17 @@ bool MinidumpContext::Read(u_int32_t expected_size) {
Swap(&context_flags);
u_int32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
if (cpu_type == 0) {
// Unfortunately the flag for MD_CONTEXT_ARM that was taken
// from a Windows CE SDK header conflicts in practice with
// the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered,
// but handle dumps with the legacy value gracefully here.
if (context_flags & MD_CONTEXT_ARM_OLD) {
context_flags |= MD_CONTEXT_ARM;
context_flags &= ~MD_CONTEXT_ARM_OLD;
cpu_type = MD_CONTEXT_ARM;
}
}
// Allocate the context structure for the correct CPU and fill it. The
// casts are slightly unorthodox, but it seems better to do that than to

View file

@ -46,6 +46,7 @@ namespace {
using google_breakpad::Minidump;
using google_breakpad::MinidumpContext;
using google_breakpad::MinidumpException;
using google_breakpad::MinidumpMemoryInfo;
using google_breakpad::MinidumpMemoryInfoList;
using google_breakpad::MinidumpMemoryList;
@ -57,6 +58,7 @@ using google_breakpad::MinidumpThread;
using google_breakpad::MinidumpThreadList;
using google_breakpad::SynthMinidump::Context;
using google_breakpad::SynthMinidump::Dump;
using google_breakpad::SynthMinidump::Exception;
using google_breakpad::SynthMinidump::Memory;
using google_breakpad::SynthMinidump::Module;
using google_breakpad::SynthMinidump::Stream;
@ -588,4 +590,318 @@ TEST(Dump, OneMemoryInfo) {
ASSERT_EQ(kRegionSize, info2->GetSize());
}
TEST(Dump, OneExceptionX86) {
Dump dump(0, kLittleEndian);
MDRawContextX86 raw_context;
raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
raw_context.edi = 0x3ecba80d;
raw_context.esi = 0x382583b9;
raw_context.ebx = 0x7fccc03f;
raw_context.edx = 0xf62f8ec2;
raw_context.ecx = 0x46a6a6a8;
raw_context.eax = 0x6a5025e2;
raw_context.ebp = 0xd9fabb4a;
raw_context.eip = 0x6913f540;
raw_context.cs = 0xbffe6eda;
raw_context.eflags = 0xb2ce1e2d;
raw_context.esp = 0x659caaa4;
raw_context.ss = 0x2e951ef7;
Context context(dump, raw_context);
Exception exception(dump, context,
0x1234abcd, // thread id
0xdcba4321, // exception code
0xf0e0d0c0, // exception flags
0x0919a9b9c9d9e9f9ULL); // exception address
dump.Add(&context);
dump.Add(&exception);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
MinidumpException *md_exception = minidump.GetException();
ASSERT_TRUE(md_exception != NULL);
u_int32_t thread_id;
ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
ASSERT_EQ(0x1234abcd, thread_id);
const MDRawExceptionStream* raw_exception = md_exception->exception();
ASSERT_TRUE(raw_exception != NULL);
EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
raw_exception->exception_record.exception_address);
MinidumpContext *md_context = md_exception->GetContext();
ASSERT_TRUE(md_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
ASSERT_TRUE(md_raw_context != NULL);
ASSERT_EQ((u_int32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
(md_raw_context->context_flags
& (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
EXPECT_EQ(0x3ecba80dU, raw_context.edi);
EXPECT_EQ(0x382583b9U, raw_context.esi);
EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
EXPECT_EQ(0x6a5025e2U, raw_context.eax);
EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
EXPECT_EQ(0x6913f540U, raw_context.eip);
EXPECT_EQ(0xbffe6edaU, raw_context.cs);
EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
EXPECT_EQ(0x659caaa4U, raw_context.esp);
EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}
TEST(Dump, OneExceptionX86XState) {
Dump dump(0, kLittleEndian);
MDRawContextX86 raw_context;
raw_context.context_flags = MD_CONTEXT_X86_INTEGER |
MD_CONTEXT_X86_CONTROL | MD_CONTEXT_X86_XSTATE;
raw_context.edi = 0x3ecba80d;
raw_context.esi = 0x382583b9;
raw_context.ebx = 0x7fccc03f;
raw_context.edx = 0xf62f8ec2;
raw_context.ecx = 0x46a6a6a8;
raw_context.eax = 0x6a5025e2;
raw_context.ebp = 0xd9fabb4a;
raw_context.eip = 0x6913f540;
raw_context.cs = 0xbffe6eda;
raw_context.eflags = 0xb2ce1e2d;
raw_context.esp = 0x659caaa4;
raw_context.ss = 0x2e951ef7;
Context context(dump, raw_context);
Exception exception(dump, context,
0x1234abcd, // thread id
0xdcba4321, // exception code
0xf0e0d0c0, // exception flags
0x0919a9b9c9d9e9f9ULL); // exception address
dump.Add(&context);
dump.Add(&exception);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
MinidumpException *md_exception = minidump.GetException();
ASSERT_TRUE(md_exception != NULL);
u_int32_t thread_id;
ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
ASSERT_EQ(0x1234abcd, thread_id);
const MDRawExceptionStream* raw_exception = md_exception->exception();
ASSERT_TRUE(raw_exception != NULL);
EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
raw_exception->exception_record.exception_address);
MinidumpContext *md_context = md_exception->GetContext();
ASSERT_TRUE(md_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
ASSERT_TRUE(md_raw_context != NULL);
ASSERT_EQ((u_int32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
(md_raw_context->context_flags
& (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
EXPECT_EQ(0x3ecba80dU, raw_context.edi);
EXPECT_EQ(0x382583b9U, raw_context.esi);
EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
EXPECT_EQ(0x6a5025e2U, raw_context.eax);
EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
EXPECT_EQ(0x6913f540U, raw_context.eip);
EXPECT_EQ(0xbffe6edaU, raw_context.cs);
EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
EXPECT_EQ(0x659caaa4U, raw_context.esp);
EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}
TEST(Dump, OneExceptionARM) {
Dump dump(0, kLittleEndian);
MDRawContextARM raw_context;
raw_context.context_flags = MD_CONTEXT_ARM_INTEGER;
raw_context.iregs[0] = 0x3ecba80d;
raw_context.iregs[1] = 0x382583b9;
raw_context.iregs[2] = 0x7fccc03f;
raw_context.iregs[3] = 0xf62f8ec2;
raw_context.iregs[4] = 0x46a6a6a8;
raw_context.iregs[5] = 0x6a5025e2;
raw_context.iregs[6] = 0xd9fabb4a;
raw_context.iregs[7] = 0x6913f540;
raw_context.iregs[8] = 0xbffe6eda;
raw_context.iregs[9] = 0xb2ce1e2d;
raw_context.iregs[10] = 0x659caaa4;
raw_context.iregs[11] = 0xf0e0d0c0;
raw_context.iregs[12] = 0xa9b8c7d6;
raw_context.iregs[13] = 0x12345678;
raw_context.iregs[14] = 0xabcd1234;
raw_context.iregs[15] = 0x10203040;
raw_context.cpsr = 0x2e951ef7;
Context context(dump, raw_context);
Exception exception(dump, context,
0x1234abcd, // thread id
0xdcba4321, // exception code
0xf0e0d0c0, // exception flags
0x0919a9b9c9d9e9f9ULL); // exception address
dump.Add(&context);
dump.Add(&exception);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
MinidumpException *md_exception = minidump.GetException();
ASSERT_TRUE(md_exception != NULL);
u_int32_t thread_id;
ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
ASSERT_EQ(0x1234abcd, thread_id);
const MDRawExceptionStream* raw_exception = md_exception->exception();
ASSERT_TRUE(raw_exception != NULL);
EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
raw_exception->exception_record.exception_address);
MinidumpContext *md_context = md_exception->GetContext();
ASSERT_TRUE(md_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
const MDRawContextARM *md_raw_context = md_context->GetContextARM();
ASSERT_TRUE(md_raw_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM_INTEGER,
(md_raw_context->context_flags
& MD_CONTEXT_ARM_INTEGER));
EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
}
TEST(Dump, OneExceptionARMOldFlags) {
Dump dump(0, kLittleEndian);
MDRawContextARM raw_context;
// MD_CONTEXT_ARM_INTEGER, but with _OLD
raw_context.context_flags = MD_CONTEXT_ARM_OLD | 0x00000002;
raw_context.iregs[0] = 0x3ecba80d;
raw_context.iregs[1] = 0x382583b9;
raw_context.iregs[2] = 0x7fccc03f;
raw_context.iregs[3] = 0xf62f8ec2;
raw_context.iregs[4] = 0x46a6a6a8;
raw_context.iregs[5] = 0x6a5025e2;
raw_context.iregs[6] = 0xd9fabb4a;
raw_context.iregs[7] = 0x6913f540;
raw_context.iregs[8] = 0xbffe6eda;
raw_context.iregs[9] = 0xb2ce1e2d;
raw_context.iregs[10] = 0x659caaa4;
raw_context.iregs[11] = 0xf0e0d0c0;
raw_context.iregs[12] = 0xa9b8c7d6;
raw_context.iregs[13] = 0x12345678;
raw_context.iregs[14] = 0xabcd1234;
raw_context.iregs[15] = 0x10203040;
raw_context.cpsr = 0x2e951ef7;
Context context(dump, raw_context);
Exception exception(dump, context,
0x1234abcd, // thread id
0xdcba4321, // exception code
0xf0e0d0c0, // exception flags
0x0919a9b9c9d9e9f9ULL); // exception address
dump.Add(&context);
dump.Add(&exception);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
MinidumpException *md_exception = minidump.GetException();
ASSERT_TRUE(md_exception != NULL);
u_int32_t thread_id;
ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
ASSERT_EQ(0x1234abcd, thread_id);
const MDRawExceptionStream* raw_exception = md_exception->exception();
ASSERT_TRUE(raw_exception != NULL);
EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
raw_exception->exception_record.exception_address);
MinidumpContext *md_context = md_exception->GetContext();
ASSERT_TRUE(md_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
const MDRawContextARM *md_raw_context = md_context->GetContextARM();
ASSERT_TRUE(md_raw_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM_INTEGER,
(md_raw_context->context_flags
& MD_CONTEXT_ARM_INTEGER));
EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
}
} // namespace

View file

@ -170,6 +170,25 @@ Context::Context(const Dump &dump, const MDRawContextX86 &context)
assert(Size() == sizeof(MDRawContextX86));
}
Context::Context(const Dump &dump, const MDRawContextARM &context)
: Section(dump) {
// The caller should have properly set the CPU type flag.
assert((context.context_flags & MD_CONTEXT_ARM) ||
(context.context_flags & MD_CONTEXT_ARM_OLD));
// It doesn't make sense to store ARM registers in big-endian form.
assert(dump.endianness() == kLittleEndian);
D32(context.context_flags);
for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i)
D32(context.iregs[i]);
D32(context.cpsr);
D64(context.float_save.fpscr);
for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; ++i)
D64(context.float_save.regs[i]);
for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; ++i)
D32(context.float_save.extra[i]);
assert(Size() == sizeof(MDRawContextARM));
}
Thread::Thread(const Dump &dump,
u_int32_t thread_id, const Memory &stack, const Context &context,
u_int32_t suspend_count, u_int32_t priority_class,
@ -231,7 +250,28 @@ const MDVSFixedFileInfo Module::stock_version_info = {
MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN, // file_subtype
0, // file_date_hi
0 // file_date_lo
};
};
Exception::Exception(const Dump &dump,
const Context &context,
u_int32_t thread_id,
u_int32_t exception_code,
u_int32_t exception_flags,
u_int64_t exception_address)
: Stream(dump, MD_EXCEPTION_STREAM) {
D32(thread_id);
D32(0); // __align
D32(exception_code);
D32(exception_flags);
D64(0); // exception_record
D64(exception_address);
D32(0); // number_parameters
D32(0); // __align
for (int i = 0; i < MD_EXCEPTION_MAXIMUM_PARAMETERS; ++i)
D64(0); // exception_information
context.CiteLocationIn(this);
assert(Size() == sizeof(MDRawExceptionStream));
}
Dump::Dump(u_int64_t flags,
Endianness endianness,

View file

@ -196,7 +196,7 @@ class SystemInfo: public Stream {
static const string windows_x86_csd_version;
};
// An MDString: a string predeced by a 32-bit length.
// An MDString: a string preceded by a 32-bit length.
class String: public Section {
public:
String(const Dump &dump, const string &value);
@ -227,6 +227,7 @@ class Context: public Section {
public:
// Create a context belonging to DUMP whose contents are a copy of CONTEXT.
Context(const Dump &dump, const MDRawContextX86 &context);
Context(const Dump &dump, const MDRawContextARM &context);
// Add constructors for other architectures here. Remember to byteswap.
};
@ -266,6 +267,16 @@ class Module: public Section {
static const MDVSFixedFileInfo stock_version_info;
};
class Exception : public Stream {
public:
Exception(const Dump &dump,
const Context &context,
u_int32_t thread_id = 0,
u_int32_t exception_code = 0,
u_int32_t exception_flags = 0,
u_int64_t exception_address = 0);
};
// A list of entries starting with a 32-bit count, like a memory list
// or a thread list.
template<typename Element>

View file

@ -42,6 +42,7 @@
using google_breakpad::SynthMinidump::Context;
using google_breakpad::SynthMinidump::Dump;
using google_breakpad::SynthMinidump::Exception;
using google_breakpad::SynthMinidump::List;
using google_breakpad::SynthMinidump::Memory;
using google_breakpad::SynthMinidump::Module;
@ -133,6 +134,17 @@ TEST(Context, X86) {
== 0);
}
TEST(Context, ARM) {
Dump dump(0, kLittleEndian);
assert(arm_raw_context.context_flags & MD_CONTEXT_ARM);
Context context(dump, arm_raw_context);
string contents;
ASSERT_TRUE(context.GetContents(&contents));
EXPECT_EQ(sizeof(arm_expected_contents), contents.size());
EXPECT_TRUE(memcmp(contents.data(), arm_expected_contents, contents.size())
== 0);
}
TEST(ContextDeathTest, X86BadFlags) {
Dump dump(0, kLittleEndian);
MDRawContextX86 raw;
@ -179,6 +191,49 @@ TEST(Thread, Simple) {
EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0);
}
TEST(Exception, Simple) {
Dump dump(0, kLittleEndian);
Context context(dump, x86_raw_context);
context.Finish(0x8665da0c);
Exception exception(dump, context,
0x1234abcd, // thread id
0xdcba4321, // exception code
0xf0e0d0c0, // exception flags
0x0919a9b9c9d9e9f9ULL); // exception address
string contents;
ASSERT_TRUE(exception.GetContents(&contents));
static const u_int8_t expected_bytes[] = {
0xcd, 0xab, 0x34, 0x12, // thread id
0x00, 0x00, 0x00, 0x00, // __align
0x21, 0x43, 0xba, 0xdc, // exception code
0xc0, 0xd0, 0xe0, 0xf0, // exception flags
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception record
0xf9, 0xe9, 0xd9, 0xc9, 0xb9, 0xa9, 0x19, 0x09, // exception address
0x00, 0x00, 0x00, 0x00, // number parameters
0x00, 0x00, 0x00, 0x00, // __align
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
0xcc, 0x02, 0x00, 0x00, // context size
0x0c, 0xda, 0x65, 0x86 // context MDRVA
};
EXPECT_EQ(sizeof(expected_bytes), contents.size());
EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0);
}
TEST(String, Simple) {
Dump dump(0, kBigEndian);
String s(dump, "All mimsy were the borogoves");

View file

@ -43,7 +43,7 @@ static const MDRawContextX86 x86_raw_context = {
0x84c53a90, // cr0_npx_state
},
0x79f71e76, // gs
0x8107bd25, // fs
0x452d2921, // es
@ -131,20 +131,20 @@ static const MDRawContextX86 x86_raw_context = {
};
static const u_int8_t x86_expected_contents[] = {
0x1b, 0xd7, 0xd5, 0xde,
0x2e, 0x43, 0xdb, 0x9f,
0x1a, 0xa8, 0xb7, 0x26,
0x48, 0xe3, 0xc7, 0xca,
0x09, 0xec, 0x99, 0xcf,
0xcd, 0xc2, 0xc8, 0x7d,
0x80, 0xb8, 0xde, 0x21,
0xb0, 0x2b, 0x5d, 0x8a,
0xc9, 0xc4, 0x86, 0x02,
0x21, 0xea, 0xfe, 0xf1,
0x76, 0x05, 0xd4, 0xb2,
0xde, 0x6c, 0x14, 0x48,
0x21, 0x9b, 0x3f, 0x98,
0x2c, 0xe1, 0x5b, 0x47,
0x1b, 0xd7, 0xd5, 0xde,
0x2e, 0x43, 0xdb, 0x9f,
0x1a, 0xa8, 0xb7, 0x26,
0x48, 0xe3, 0xc7, 0xca,
0x09, 0xec, 0x99, 0xcf,
0xcd, 0xc2, 0xc8, 0x7d,
0x80, 0xb8, 0xde, 0x21,
0xb0, 0x2b, 0x5d, 0x8a,
0xc9, 0xc4, 0x86, 0x02,
0x21, 0xea, 0xfe, 0xf1,
0x76, 0x05, 0xd4, 0xb2,
0xde, 0x6c, 0x14, 0x48,
0x21, 0x9b, 0x3f, 0x98,
0x2c, 0xe1, 0x5b, 0x47,
// float_save.register_area --- unswapped
0xd9, 0x04, 0x20, 0x6b, 0x88, 0x3a, 0x3f, 0xd5,
@ -158,23 +158,23 @@ static const u_int8_t x86_expected_contents[] = {
0xc7, 0x8d, 0x17, 0xb6, 0xe5, 0x0b, 0x94, 0xf7,
0x78, 0x9b, 0x63, 0x49, 0xba, 0xfc, 0x08, 0x4d,
0x90, 0x3a, 0xc5, 0x84,
0x76, 0x1e, 0xf7, 0x79,
0x25, 0xbd, 0x07, 0x81,
0x21, 0x29, 0x2d, 0x45,
0x75, 0x28, 0xec, 0x87,
0xf5, 0x73, 0xbb, 0xf8,
0x88, 0xbb, 0x3e, 0xa6,
0xbe, 0x5e, 0xd3, 0x95,
0x56, 0x24, 0xaa, 0x17,
0x08, 0xa2, 0x5f, 0x13,
0xe6, 0x15, 0x06, 0x50,
0x05, 0x42, 0xd1, 0x66,
0xa5, 0x19, 0x07, 0x00,
0x1b, 0x48, 0x7b, 0x47,
0xba, 0xdf, 0x84, 0x86,
0xdf, 0xcd, 0x3c, 0xe3,
0x33, 0x5d, 0xe6, 0xc0,
0x90, 0x3a, 0xc5, 0x84,
0x76, 0x1e, 0xf7, 0x79,
0x25, 0xbd, 0x07, 0x81,
0x21, 0x29, 0x2d, 0x45,
0x75, 0x28, 0xec, 0x87,
0xf5, 0x73, 0xbb, 0xf8,
0x88, 0xbb, 0x3e, 0xa6,
0xbe, 0x5e, 0xd3, 0x95,
0x56, 0x24, 0xaa, 0x17,
0x08, 0xa2, 0x5f, 0x13,
0xe6, 0x15, 0x06, 0x50,
0x05, 0x42, 0xd1, 0x66,
0xa5, 0x19, 0x07, 0x00,
0x1b, 0x48, 0x7b, 0x47,
0xba, 0xdf, 0x84, 0x86,
0xdf, 0xcd, 0x3c, 0xe3,
0x33, 0x5d, 0xe6, 0xc0,
// extended_registers --- unswapped
0x68, 0x63, 0xdf, 0x50, 0xf7, 0x3b, 0xe8, 0xe5,
@ -243,4 +243,170 @@ static const u_int8_t x86_expected_contents[] = {
0xb2, 0xc7, 0x3a, 0x6c, 0x8a, 0x35, 0xe1, 0xba
};
static const MDRawContextARM arm_raw_context = {
// context_flags
0x591b9e6a,
// iregs
0xa21594de,
0x820d8a25,
0xc4e133b2,
0x173a1c02,
0x105fb175,
0xe871793f,
0x5def70b3,
0xcee3a623,
0x7b3aa9b8,
0x52518537,
0x627012c5,
0x22723dcc,
0x16fcc971,
0x20988bcb,
0xf1ab806b,
0x99d5fc03,
// cpsr
0xb70df511,
// float_save
{
// fpscr
0xa1e1f7ce1077e6b5,
// regs
0xbcb8d002eed7fbde,
0x4dd26a43b96ae97f,
0x8eec22db8b31741c,
0xfd634bd7c5ad66a0,
0x1681da0daeb3debe,
0x474a32bdf72d0b71,
0xcaf464f8b1044834,
0xcaa6592ae5c7582a,
0x4ee46889d877c3db,
0xf8930cf301645cf5,
0x4da7e9ebba27f7c7,
0x69a7b02761944da3,
0x2cda2b2e78195c06,
0x66b227ab9b460a42,
0x7e77e49e52ee0849,
0xd62cd9663e76f255,
0xe9370f082451514b,
0x50a1c674dd1b6029,
0x405db4575829eac4,
0x67b948764649eee7,
0x93731885419229d4,
0xdb0338bad72a4ce7,
0xa0a451f996fca4c8,
0xb4508ea668400a45,
0xbff28c5c7a142423,
0x4f31b42b96f3a431,
0x2ce6789d4ea1ff37,
0xfa150b52e4f82a3c,
0xe9ec40449e6ed4f3,
0x5ceca87836fe2251,
0x66f50de463ee238c,
0x42823efcd59ab511,
// extra
0xe9e14cd2,
0x865bb640,
0x9f3f0b3e,
0x94a71c52,
0x3c012f19,
0x6436637c,
0x46ccedcb,
0x7b341be7
}
};
static const u_int8_t arm_expected_contents[] = {
0x6a, 0x9e, 0x1b, 0x59,
0xde, 0x94, 0x15, 0xa2,
0x25, 0x8a, 0x0d, 0x82,
0xb2, 0x33, 0xe1, 0xc4,
0x02, 0x1c, 0x3a, 0x17,
0x75, 0xb1, 0x5f, 0x10,
0x3f, 0x79, 0x71, 0xe8,
0xb3, 0x70, 0xef, 0x5d,
0x23, 0xa6, 0xe3, 0xce,
0xb8, 0xa9, 0x3a, 0x7b,
0x37, 0x85, 0x51, 0x52,
0xc5, 0x12, 0x70, 0x62,
0xcc, 0x3d, 0x72, 0x22,
0x71, 0xc9, 0xfc, 0x16,
0xcb, 0x8b, 0x98, 0x20,
0x6b, 0x80, 0xab, 0xf1,
0x03, 0xfc, 0xd5, 0x99,
0x11, 0xf5, 0x0d, 0xb7,
0xb5, 0xe6, 0x77, 0x10,
0xce, 0xf7, 0xe1, 0xa1,
0xde, 0xfb, 0xd7, 0xee,
0x02, 0xd0, 0xb8, 0xbc,
0x7f, 0xe9, 0x6a, 0xb9,
0x43, 0x6a, 0xd2, 0x4d,
0x1c, 0x74, 0x31, 0x8b,
0xdb, 0x22, 0xec, 0x8e,
0xa0, 0x66, 0xad, 0xc5,
0xd7, 0x4b, 0x63, 0xfd,
0xbe, 0xde, 0xb3, 0xae,
0x0d, 0xda, 0x81, 0x16,
0x71, 0x0b, 0x2d, 0xf7,
0xbd, 0x32, 0x4a, 0x47,
0x34, 0x48, 0x04, 0xb1,
0xf8, 0x64, 0xf4, 0xca,
0x2a, 0x58, 0xc7, 0xe5,
0x2a, 0x59, 0xa6, 0xca,
0xdb, 0xc3, 0x77, 0xd8,
0x89, 0x68, 0xe4, 0x4e,
0xf5, 0x5c, 0x64, 0x01,
0xf3, 0x0c, 0x93, 0xf8,
0xc7, 0xf7, 0x27, 0xba,
0xeb, 0xe9, 0xa7, 0x4d,
0xa3, 0x4d, 0x94, 0x61,
0x27, 0xb0, 0xa7, 0x69,
0x06, 0x5c, 0x19, 0x78,
0x2e, 0x2b, 0xda, 0x2c,
0x42, 0x0a, 0x46, 0x9b,
0xab, 0x27, 0xb2, 0x66,
0x49, 0x08, 0xee, 0x52,
0x9e, 0xe4, 0x77, 0x7e,
0x55, 0xf2, 0x76, 0x3e,
0x66, 0xd9, 0x2c, 0xd6,
0x4b, 0x51, 0x51, 0x24,
0x08, 0x0f, 0x37, 0xe9,
0x29, 0x60, 0x1b, 0xdd,
0x74, 0xc6, 0xa1, 0x50,
0xc4, 0xea, 0x29, 0x58,
0x57, 0xb4, 0x5d, 0x40,
0xe7, 0xee, 0x49, 0x46,
0x76, 0x48, 0xb9, 0x67,
0xd4, 0x29, 0x92, 0x41,
0x85, 0x18, 0x73, 0x93,
0xe7, 0x4c, 0x2a, 0xd7,
0xba, 0x38, 0x03, 0xdb,
0xc8, 0xa4, 0xfc, 0x96,
0xf9, 0x51, 0xa4, 0xa0,
0x45, 0x0a, 0x40, 0x68,
0xa6, 0x8e, 0x50, 0xb4,
0x23, 0x24, 0x14, 0x7a,
0x5c, 0x8c, 0xf2, 0xbf,
0x31, 0xa4, 0xf3, 0x96,
0x2b, 0xb4, 0x31, 0x4f,
0x37, 0xff, 0xa1, 0x4e,
0x9d, 0x78, 0xe6, 0x2c,
0x3c, 0x2a, 0xf8, 0xe4,
0x52, 0x0b, 0x15, 0xfa,
0xf3, 0xd4, 0x6e, 0x9e,
0x44, 0x40, 0xec, 0xe9,
0x51, 0x22, 0xfe, 0x36,
0x78, 0xa8, 0xec, 0x5c,
0x8c, 0x23, 0xee, 0x63,
0xe4, 0x0d, 0xf5, 0x66,
0x11, 0xb5, 0x9a, 0xd5,
0xfc, 0x3e, 0x82, 0x42,
0xd2, 0x4c, 0xe1, 0xe9,
0x40, 0xb6, 0x5b, 0x86,
0x3e, 0x0b, 0x3f, 0x9f,
0x52, 0x1c, 0xa7, 0x94,
0x19, 0x2f, 0x01, 0x3c,
0x7c, 0x63, 0x36, 0x64,
0xcb, 0xed, 0xcc, 0x46,
0xe7, 0x1b, 0x34, 0x7b
};
#endif // PROCESSOR_SYNTH_MINIDUMP_UNITTEST_DATA_H_