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
This commit is contained in:
ivan.penkov@gmail.com
2012-12-08 03:18:52 +00:00
parent bf6d350a68
commit 947ef27362
7 changed files with 262 additions and 12 deletions

View File

@@ -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.