Added some sanity checks when iterating over threads in a crashed process. In same cases the ESP could be 0. In other cases it would be borked completely(i.e. pointing to an invalid range).

R=Jeremy Moskovich



git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@295 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
nealsid 2008-11-19 19:07:34 +00:00
parent f32d028110
commit e055207058

View file

@ -223,12 +223,23 @@ size_t MinidumpGenerator::CalculateStackSize(mach_vm_address_t start_addr) {
vm_region_recurse_info_t region_info; vm_region_recurse_info_t region_info;
region_info = reinterpret_cast<vm_region_recurse_info_t>(&submap_info); region_info = reinterpret_cast<vm_region_recurse_info_t>(&submap_info);
if (start_addr == 0) {
return 0;
}
kern_return_t result = kern_return_t result =
mach_vm_region_recurse(crashing_task_, &stack_region_base, mach_vm_region_recurse(crashing_task_, &stack_region_base,
&stack_region_size, &nesting_level, &stack_region_size, &nesting_level,
region_info, region_info,
&info_count); &info_count);
if (start_addr < stack_region_base) {
// probably stack corruption, since mach_vm_region had to go
// higher in the process address space to find a valid region.
return 0;
}
if ((stack_region_base + stack_region_size) == TOP_OF_THREAD0_STACK) { if ((stack_region_base + stack_region_size) == TOP_OF_THREAD0_STACK) {
// The stack for thread 0 needs to extend all the way to // The stack for thread 0 needs to extend all the way to
// 0xc0000000 on 32 bit and 00007fff5fc00000 on 64bit. HOWEVER, // 0xc0000000 on 32 bit and 00007fff5fc00000 on 64bit. HOWEVER,
@ -254,17 +265,30 @@ bool MinidumpGenerator::WriteStackFromStartAddress(
mach_vm_address_t start_addr, mach_vm_address_t start_addr,
MDMemoryDescriptor *stack_location) { MDMemoryDescriptor *stack_location) {
UntypedMDRVA memory(&writer_); UntypedMDRVA memory(&writer_);
bool result = false;
size_t size = CalculateStackSize(start_addr); size_t size = CalculateStackSize(start_addr);
// If there's an error in the calculation, return at least the current if (size == 0) {
// stack information // In some situations the stack address for the thread can come back 0.
if (size == 0) // In these cases we skip over the threads in question and stuff the
// stack with a clearly borked value.
start_addr = 0xDEADBEEF;
size = 16; size = 16;
if (!memory.Allocate(size))
return false;
unsigned long long dummy_stack[2]; // Fill dummy stack with 16 bytes of
// junk.
dummy_stack[0] = 0xDEADBEEF;
dummy_stack[1] = 0xDEADBEEF;
result = memory.Copy(dummy_stack, size);
} else {
if (!memory.Allocate(size)) if (!memory.Allocate(size))
return false; return false;
bool result;
if (dynamic_images_) { if (dynamic_images_) {
kern_return_t kr; kern_return_t kr;
@ -283,6 +307,7 @@ bool MinidumpGenerator::WriteStackFromStartAddress(
} else { } else {
result = memory.Copy(reinterpret_cast<const void *>(start_addr), size); result = memory.Copy(reinterpret_cast<const void *>(start_addr), size);
} }
}
stack_location->start_of_memory_range = start_addr; stack_location->start_of_memory_range = start_addr;
stack_location->memory = memory.location(); stack_location->memory = memory.location();