issue 167: reviewed by Benjamin Smedberg
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@174 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
fabb8714a7
commit
026b28ec40
1 changed files with 96 additions and 32 deletions
|
@ -47,28 +47,36 @@ using MacStringUtils::ConvertToString;
|
|||
using MacStringUtils::IntegerValueAtIndex;
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
|
||||
// constructor when generating from within the crashed process
|
||||
MinidumpGenerator::MinidumpGenerator()
|
||||
: exception_type_(0),
|
||||
exception_code_(0),
|
||||
exception_thread_(0),
|
||||
crashing_task_(mach_task_self()),
|
||||
handler_thread_(mach_thread_self()) {
|
||||
dynamic_images_ = new DynamicImages(mach_task_self());
|
||||
handler_thread_(mach_thread_self()),
|
||||
dynamic_images_(NULL) {
|
||||
GatherSystemInformation();
|
||||
}
|
||||
|
||||
// constructor when generating from a different process than the crashed process
|
||||
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_);
|
||||
if (crashing_task != mach_task_self()) {
|
||||
dynamic_images_ = new DynamicImages(crashing_task_);
|
||||
} else {
|
||||
dynamic_images_ = NULL;
|
||||
}
|
||||
|
||||
GatherSystemInformation();
|
||||
}
|
||||
|
||||
MinidumpGenerator::~MinidumpGenerator() {
|
||||
delete dynamic_images_;
|
||||
}
|
||||
|
||||
char MinidumpGenerator::build_string_[16];
|
||||
|
@ -240,12 +248,14 @@ bool MinidumpGenerator::WriteStackFromStartAddress(
|
|||
if (!memory.Allocate(size))
|
||||
return false;
|
||||
|
||||
void *stack_memory = ReadTaskMemory(crashing_task_, (void*)start_addr, size);
|
||||
|
||||
bool result = memory.Copy(stack_memory, size);
|
||||
|
||||
free(stack_memory);
|
||||
|
||||
bool result;
|
||||
if (dynamic_images_) {
|
||||
void *stack_memory = ReadTaskMemory(crashing_task_, (void*)start_addr, size);
|
||||
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;
|
||||
stack_location->memory = memory.location();
|
||||
|
@ -547,42 +557,95 @@ bool MinidumpGenerator::WriteSystemInfoStream(
|
|||
|
||||
bool MinidumpGenerator::WriteModuleStream(unsigned int index,
|
||||
MDRawModule *module) {
|
||||
DynamicImage *image = dynamic_images_->GetImage(index);
|
||||
if (dynamic_images_) {
|
||||
// we're in a different process than the crashed process
|
||||
DynamicImage *image = dynamic_images_->GetImage(index);
|
||||
|
||||
if (!image)
|
||||
return false;
|
||||
if (!image)
|
||||
return false;
|
||||
|
||||
const mach_header *header = image->GetMachHeader();
|
||||
const mach_header *header = image->GetMachHeader();
|
||||
|
||||
if (!header)
|
||||
return false;
|
||||
if (!header)
|
||||
return false;
|
||||
|
||||
int cpu_type = header->cputype;
|
||||
int cpu_type = header->cputype;
|
||||
|
||||
memset(module, 0, sizeof(MDRawModule));
|
||||
memset(module, 0, sizeof(MDRawModule));
|
||||
|
||||
MDLocationDescriptor string_location;
|
||||
MDLocationDescriptor string_location;
|
||||
|
||||
const char* name = image->GetFilePath();
|
||||
if (!writer_.WriteString(name, 0, &string_location))
|
||||
return false;
|
||||
const char* name = image->GetFilePath();
|
||||
if (!writer_.WriteString(name, 0, &string_location))
|
||||
return false;
|
||||
|
||||
module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
|
||||
module->size_of_image = image->GetVMSize();
|
||||
module->module_name_rva = string_location.rva;
|
||||
module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
|
||||
module->size_of_image = image->GetVMSize();
|
||||
module->module_name_rva = string_location.rva;
|
||||
|
||||
if (!WriteCVRecord(module, cpu_type, name)) {
|
||||
return false;
|
||||
if (!WriteCVRecord(module, cpu_type, name)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// we're getting module info in the crashed process
|
||||
const struct mach_header *header = _dyld_get_image_header(index);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
cmd = reinterpret_cast<struct load_command *>((char *)cmd + cmd->cmdsize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int MinidumpGenerator::FindExecutableModule() {
|
||||
int index = dynamic_images_->GetExecutableImageIndex();
|
||||
if (dynamic_images_) {
|
||||
int index = dynamic_images_->GetExecutableImageIndex();
|
||||
|
||||
if (index >= 0) {
|
||||
return index;
|
||||
if (index >= 0) {
|
||||
return index;
|
||||
}
|
||||
} else {
|
||||
int image_count = _dyld_image_count();
|
||||
const struct mach_header *header;
|
||||
|
||||
for (int index = 0; index < image_count; ++index) {
|
||||
header = _dyld_get_image_header(index);
|
||||
|
||||
if (header->filetype == MH_EXECUTE)
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
// failed - just use the first image
|
||||
|
@ -645,7 +708,8 @@ bool MinidumpGenerator::WriteModuleListStream(
|
|||
if (!_dyld_present())
|
||||
return false;
|
||||
|
||||
int image_count = dynamic_images_->GetImageCount();
|
||||
int image_count = dynamic_images_ ?
|
||||
dynamic_images_->GetImageCount() : _dyld_image_count();
|
||||
|
||||
if (!list.AllocateObjectAndArray(image_count, MD_MODULE_SIZE))
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue