aboutsummaryrefslogtreecommitdiff
path: root/src/client/mac/handler/minidump_generator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/mac/handler/minidump_generator.cc')
-rw-r--r--src/client/mac/handler/minidump_generator.cc98
1 files changed, 54 insertions, 44 deletions
diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc
index 5cddf88d..bdabc1f4 100644
--- a/src/client/mac/handler/minidump_generator.cc
+++ b/src/client/mac/handler/minidump_generator.cc
@@ -50,7 +50,21 @@ namespace google_breakpad {
MinidumpGenerator::MinidumpGenerator()
: exception_type_(0),
exception_code_(0),
- exception_thread_(0) {
+ exception_thread_(0),
+ crashing_task_(mach_task_self()),
+ handler_thread_(mach_thread_self()) {
+ dynamic_images_ = new DynamicImages(mach_task_self());
+ GatherSystemInformation();
+}
+
+MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task, mach_port_t handler_thread)
+ : exception_type_(0),
+ exception_code_(0),
+ exception_thread_(0),
+ crashing_task_(crashing_task),
+ handler_thread_(handler_thread) {
+ dynamic_images_ = new DynamicImages(crashing_task_);
+ GatherSystemInformation();
}
MinidumpGenerator::~MinidumpGenerator() {
@@ -184,14 +198,14 @@ bool MinidumpGenerator::Write(const char *path) {
return result;
}
-static size_t CalculateStackSize(vm_address_t start_addr) {
+size_t MinidumpGenerator::CalculateStackSize(vm_address_t start_addr) {
vm_address_t stack_region_base = start_addr;
vm_size_t stack_region_size;
natural_t nesting_level = 0;
vm_region_submap_info submap_info;
mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT;
kern_return_t result =
- vm_region_recurse(mach_task_self(), &stack_region_base, &stack_region_size,
+ vm_region_recurse(crashing_task_, &stack_region_base, &stack_region_size,
&nesting_level,
reinterpret_cast<vm_region_recurse_info_t>(&submap_info),
&info_count);
@@ -225,7 +239,13 @@ bool MinidumpGenerator::WriteStackFromStartAddress(
if (!memory.Allocate(size))
return false;
- bool result = memory.Copy(reinterpret_cast<const void *>(start_addr), size);
+ void *stack_memory = ReadTaskMemory(crashing_task_, (void*)start_addr, size);
+
+ bool result = memory.Copy(stack_memory, size);
+
+ free(stack_memory);
+
+
stack_location->start_of_memory_range = start_addr;
stack_location->memory = memory.location();
@@ -384,7 +404,7 @@ bool MinidumpGenerator::WriteThreadListStream(
mach_msg_type_number_t thread_count;
int non_generator_thread_count;
- if (task_threads(mach_task_self(), &threads_for_task, &thread_count))
+ if (task_threads(crashing_task_, &threads_for_task, &thread_count))
return false;
// Don't include the generator thread
@@ -404,7 +424,7 @@ bool MinidumpGenerator::WriteThreadListStream(
for (unsigned int i = 0; i < thread_count; ++i) {
memset(&thread, 0, sizeof(MDRawThread));
- if (threads_for_task[i] != mach_thread_self()) {
+ if (threads_for_task[i] != handler_thread_) {
if (!WriteThreadStream(threads_for_task[i], &thread))
return false;
@@ -496,57 +516,45 @@ bool MinidumpGenerator::WriteSystemInfoStream(
bool MinidumpGenerator::WriteModuleStream(unsigned int index,
MDRawModule *module) {
- const struct mach_header *header = _dyld_get_image_header(index);
+ DynamicImage *image = dynamic_images_->GetImage(index);
+
+ if (!image)
+ return false;
+
+ const mach_header *header = image->GetMachHeader();
if (!header)
return false;
int cpu_type = header->cputype;
- unsigned long slide = _dyld_get_image_vmaddr_slide(index);
- const char* name = _dyld_get_image_name(index);
- const struct load_command *cmd =
- reinterpret_cast<const struct load_command *>(header + 1);
memset(module, 0, sizeof(MDRawModule));
- for (unsigned int i = 0; cmd && (i < header->ncmds); i++) {
- if (cmd->cmd == LC_SEGMENT) {
- const struct segment_command *seg =
- reinterpret_cast<const struct segment_command *>(cmd);
- if (!strcmp(seg->segname, "__TEXT")) {
- MDLocationDescriptor string_location;
-
- if (!writer_.WriteString(name, 0, &string_location))
- return false;
+ MDLocationDescriptor string_location;
- module->base_of_image = seg->vmaddr + slide;
- module->size_of_image = seg->vmsize;
- module->module_name_rva = string_location.rva;
-
- if (!WriteCVRecord(module, cpu_type, name))
- return false;
+ const char* name = image->GetFilePath();
+ if (!writer_.WriteString(name, 0, &string_location))
+ return false;
- return true;
- }
- }
+ module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
+ module->size_of_image = image->GetVMSize();
+ module->module_name_rva = string_location.rva;
- cmd = reinterpret_cast<struct load_command *>((char *)cmd + cmd->cmdsize);
+ if (!WriteCVRecord(module, cpu_type, name)) {
+ return false;
}
return true;
}
-static int FindExecutableModule() {
- int image_count = _dyld_image_count();
- const struct mach_header *header;
+int MinidumpGenerator::FindExecutableModule() {
+ int index = dynamic_images_->GetExecutableImageIndex();
- for (int i = 0; i < image_count; ++i) {
- header = _dyld_get_image_header(i);
-
- if (header->filetype == MH_EXECUTE)
- return i;
+ if (index >= 0) {
+ return index;
}
-
+
+ // failed - just use the first image
return 0;
}
@@ -606,7 +614,7 @@ bool MinidumpGenerator::WriteModuleListStream(
if (!_dyld_present())
return false;
- int image_count = _dyld_image_count();
+ int image_count = dynamic_images_->GetImageCount();
if (!list.AllocateObjectAndArray(image_count, MD_MODULE_SIZE))
return false;
@@ -619,16 +627,18 @@ bool MinidumpGenerator::WriteModuleListStream(
MDRawModule module;
int executableIndex = FindExecutableModule();
- if (!WriteModuleStream(executableIndex, &module))
+ if (!WriteModuleStream(executableIndex, &module)) {
return false;
+ }
list.CopyIndexAfterObject(0, &module, MD_MODULE_SIZE);
int destinationIndex = 1; // Write all other modules after this one
for (int i = 0; i < image_count; ++i) {
if (i != executableIndex) {
- if (!WriteModuleStream(i, &module))
+ if (!WriteModuleStream(i, &module)) {
return false;
+ }
list.CopyIndexAfterObject(destinationIndex++, &module, MD_MODULE_SIZE);
}
@@ -701,11 +711,11 @@ bool MinidumpGenerator::WriteBreakpadInfoStream(
if (exception_thread_ && exception_type_) {
info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID |
MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID;
- info_ptr->dump_thread_id = mach_thread_self();
+ info_ptr->dump_thread_id = handler_thread_;
info_ptr->requesting_thread_id = exception_thread_;
} else {
info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID;
- info_ptr->dump_thread_id = mach_thread_self();
+ info_ptr->dump_thread_id = handler_thread_;
info_ptr->requesting_thread_id = 0;
}