aboutsummaryrefslogtreecommitdiff
path: root/src/client/mac
diff options
context:
space:
mode:
authornealsid <nealsid@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-11-19 19:07:34 +0000
committernealsid <nealsid@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-11-19 19:07:34 +0000
commite055207058e4449040c8441dea686cd5bd4107f3 (patch)
tree1ce692d103a48c51b16c9c11cc6b355c277bed5d /src/client/mac
parentCommitting an externals directory to pull in google toolbox for mac (diff)
downloadbreakpad-e055207058e4449040c8441dea686cd5bd4107f3.tar.xz
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
Diffstat (limited to 'src/client/mac')
-rw-r--r--src/client/mac/handler/minidump_generator.cc69
1 files changed, 47 insertions, 22 deletions
diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc
index e15f062d..75c32ebc 100644
--- a/src/client/mac/handler/minidump_generator.cc
+++ b/src/client/mac/handler/minidump_generator.cc
@@ -223,12 +223,23 @@ size_t MinidumpGenerator::CalculateStackSize(mach_vm_address_t start_addr) {
vm_region_recurse_info_t region_info;
region_info = reinterpret_cast<vm_region_recurse_info_t>(&submap_info);
+ if (start_addr == 0) {
+ return 0;
+ }
+
kern_return_t result =
mach_vm_region_recurse(crashing_task_, &stack_region_base,
&stack_region_size, &nesting_level,
region_info,
&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) {
// The stack for thread 0 needs to extend all the way to
// 0xc0000000 on 32 bit and 00007fff5fc00000 on 64bit. HOWEVER,
@@ -254,34 +265,48 @@ bool MinidumpGenerator::WriteStackFromStartAddress(
mach_vm_address_t start_addr,
MDMemoryDescriptor *stack_location) {
UntypedMDRVA memory(&writer_);
+
+ bool result = false;
size_t size = CalculateStackSize(start_addr);
- // If there's an error in the calculation, return at least the current
- // stack information
- if (size == 0)
- size = 16;
+ if (size == 0) {
+ // In some situations the stack address for the thread can come back 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;
+ if (!memory.Allocate(size))
+ return false;
- 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;
- bool result;
- if (dynamic_images_) {
+ result = memory.Copy(dummy_stack, size);
+ } else {
- kern_return_t kr;
+ if (!memory.Allocate(size))
+ return false;
- void *stack_memory = ReadTaskMemory(crashing_task_,
- (void*)start_addr,
- size,
- &kr);
+ if (dynamic_images_) {
- if (stack_memory == NULL) {
- return false;
- }
+ kern_return_t kr;
- result = memory.Copy(stack_memory, size);
- free(stack_memory);
- } else {
- result = memory.Copy(reinterpret_cast<const void *>(start_addr), size);
+ void *stack_memory = ReadTaskMemory(crashing_task_,
+ (void*)start_addr,
+ size,
+ &kr);
+
+ if (stack_memory == NULL) {
+ return false;
+ }
+
+ result = memory.Copy(stack_memory, size);
+ free(stack_memory);
+ } else {
+ result = memory.Copy(reinterpret_cast<const void *>(start_addr), size);
+ }
}
stack_location->start_of_memory_range = start_addr;
@@ -335,7 +360,7 @@ bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
#define AddReg(a) context_ptr->a = machine_state->a
#define AddGPR(a) context_ptr->gpr[a] = machine_state->r ## a
#endif
-
+
AddReg(srr0);
AddReg(cr);
AddReg(xer);
@@ -699,7 +724,7 @@ bool MinidumpGenerator::WriteModuleStream(unsigned int index,
module->version_info.file_version_lo |= (modVersion & 0xff00) << 8;
module->version_info.file_version_lo |= (modVersion & 0xff);
}
-
+
if (!WriteCVRecord(module, cpu_type, name)) {
return false;
}