From 947ef27362c91002d933088a61eeef60b104da40 Mon Sep 17 00:00:00 2001 From: "ivan.penkov@gmail.com" Date: Sat, 8 Dec 2012 03:18:52 +0000 Subject: The Google-breakpad processor rejects (ignores) context records that lack CPU type information in their context_flags fields. Such context records can be valid (e.g. contexts captured by ::RtlCaptureContext). http://code.google.com/p/google-breakpad/issues/detail?id=493 http://breakpad.appspot.com/500002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1088 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/processor/minidump.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'src/processor/minidump.cc') diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 0c13e00e..0bd1f6ba 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -286,8 +286,8 @@ MinidumpStream::MinidumpStream(Minidump* minidump) MinidumpContext::MinidumpContext(Minidump* minidump) : MinidumpStream(minidump), - context_flags_(0), - context_() { + context_(), + context_flags_(0) { } @@ -318,6 +318,14 @@ bool MinidumpContext::Read(u_int32_t expected_size) { Swap(&context_amd64->context_flags); u_int32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK; + if (cpu_type == 0) { + if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { + context_amd64->context_flags |= cpu_type; + } else { + BPLOG(ERROR) << "Failed to preserve the current stream position"; + return false; + } + } if (cpu_type != MD_CONTEXT_AMD64) { //TODO: fall through to switch below? @@ -422,6 +430,15 @@ bool MinidumpContext::Read(u_int32_t expected_size) { } } + if (cpu_type == 0) { + if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { + context_flags |= cpu_type; + } else { + BPLOG(ERROR) << "Failed to preserve the current stream position"; + return false; + } + } + // 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 // maintain a separate pointer for each type of CPU context structure @@ -3816,6 +3833,72 @@ bool Minidump::Open() { return true; } +bool Minidump::GetContextCPUFlagsFromSystemInfo(u_int32_t *context_cpu_flags) { + // Initialize output parameters + *context_cpu_flags = 0; + + // Save the current stream position + off_t saved_position = Tell(); + if (saved_position == -1) { + // Failed to save the current stream position. + // Returns true because the current position of the stream is preserved. + return true; + } + + const MDRawSystemInfo* system_info = + GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; + + if (system_info != NULL) { + switch (system_info->processor_architecture) { + case MD_CPU_ARCHITECTURE_X86: + *context_cpu_flags = MD_CONTEXT_X86; + break; + case MD_CPU_ARCHITECTURE_MIPS: + *context_cpu_flags = MD_CONTEXT_MIPS; + break; + case MD_CPU_ARCHITECTURE_ALPHA: + *context_cpu_flags = MD_CONTEXT_ALPHA; + break; + case MD_CPU_ARCHITECTURE_PPC: + *context_cpu_flags = MD_CONTEXT_PPC; + break; + case MD_CPU_ARCHITECTURE_SHX: + *context_cpu_flags = MD_CONTEXT_SHX; + break; + case MD_CPU_ARCHITECTURE_ARM: + *context_cpu_flags = MD_CONTEXT_ARM; + break; + case MD_CPU_ARCHITECTURE_IA64: + *context_cpu_flags = MD_CONTEXT_IA64; + break; + case MD_CPU_ARCHITECTURE_ALPHA64: + *context_cpu_flags = 0; + break; + case MD_CPU_ARCHITECTURE_MSIL: + *context_cpu_flags = 0; + break; + case MD_CPU_ARCHITECTURE_AMD64: + *context_cpu_flags = MD_CONTEXT_AMD64; + break; + case MD_CPU_ARCHITECTURE_X86_WIN64: + *context_cpu_flags = 0; + break; + case MD_CPU_ARCHITECTURE_SPARC: + *context_cpu_flags = MD_CONTEXT_SPARC; + break; + case MD_CPU_ARCHITECTURE_UNKNOWN: + *context_cpu_flags = 0; + break; + default: + *context_cpu_flags = 0; + break; + } + } + + // Restore position and return + return SeekSet(saved_position); +} + bool Minidump::Read() { // Invalidate cached data. -- cgit v1.2.1