mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-03-07 14:56:28 +00:00
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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user