mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-09-03 19:31:02 +00:00
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
|
@ -47,28 +47,36 @@ using MacStringUtils::ConvertToString;
|
||||||
using MacStringUtils::IntegerValueAtIndex;
|
using MacStringUtils::IntegerValueAtIndex;
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
|
// constructor when generating from within the crashed process
|
||||||
MinidumpGenerator::MinidumpGenerator()
|
MinidumpGenerator::MinidumpGenerator()
|
||||||
: exception_type_(0),
|
: exception_type_(0),
|
||||||
exception_code_(0),
|
exception_code_(0),
|
||||||
exception_thread_(0),
|
exception_thread_(0),
|
||||||
crashing_task_(mach_task_self()),
|
crashing_task_(mach_task_self()),
|
||||||
handler_thread_(mach_thread_self()) {
|
handler_thread_(mach_thread_self()),
|
||||||
dynamic_images_ = new DynamicImages(mach_task_self());
|
dynamic_images_(NULL) {
|
||||||
GatherSystemInformation();
|
GatherSystemInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constructor when generating from a different process than the crashed process
|
||||||
MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task, mach_port_t handler_thread)
|
MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task, mach_port_t handler_thread)
|
||||||
: exception_type_(0),
|
: exception_type_(0),
|
||||||
exception_code_(0),
|
exception_code_(0),
|
||||||
exception_thread_(0),
|
exception_thread_(0),
|
||||||
crashing_task_(crashing_task),
|
crashing_task_(crashing_task),
|
||||||
handler_thread_(handler_thread) {
|
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();
|
GatherSystemInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
MinidumpGenerator::~MinidumpGenerator() {
|
MinidumpGenerator::~MinidumpGenerator() {
|
||||||
|
delete dynamic_images_;
|
||||||
}
|
}
|
||||||
|
|
||||||
char MinidumpGenerator::build_string_[16];
|
char MinidumpGenerator::build_string_[16];
|
||||||
|
@ -240,12 +248,14 @@ bool MinidumpGenerator::WriteStackFromStartAddress(
|
||||||
if (!memory.Allocate(size))
|
if (!memory.Allocate(size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
void *stack_memory = ReadTaskMemory(crashing_task_, (void*)start_addr, size);
|
bool result;
|
||||||
|
if (dynamic_images_) {
|
||||||
bool result = memory.Copy(stack_memory, size);
|
void *stack_memory = ReadTaskMemory(crashing_task_, (void*)start_addr, size);
|
||||||
|
result = memory.Copy(stack_memory, size);
|
||||||
free(stack_memory);
|
free(stack_memory);
|
||||||
|
} else {
|
||||||
|
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();
|
||||||
|
@ -547,42 +557,95 @@ bool MinidumpGenerator::WriteSystemInfoStream(
|
||||||
|
|
||||||
bool MinidumpGenerator::WriteModuleStream(unsigned int index,
|
bool MinidumpGenerator::WriteModuleStream(unsigned int index,
|
||||||
MDRawModule *module) {
|
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)
|
if (!image)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const mach_header *header = image->GetMachHeader();
|
const mach_header *header = image->GetMachHeader();
|
||||||
|
|
||||||
if (!header)
|
if (!header)
|
||||||
return false;
|
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();
|
const char* name = image->GetFilePath();
|
||||||
if (!writer_.WriteString(name, 0, &string_location))
|
if (!writer_.WriteString(name, 0, &string_location))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
|
module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
|
||||||
module->size_of_image = image->GetVMSize();
|
module->size_of_image = image->GetVMSize();
|
||||||
module->module_name_rva = string_location.rva;
|
module->module_name_rva = string_location.rva;
|
||||||
|
|
||||||
if (!WriteCVRecord(module, cpu_type, name)) {
|
if (!WriteCVRecord(module, cpu_type, name)) {
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MinidumpGenerator::FindExecutableModule() {
|
int MinidumpGenerator::FindExecutableModule() {
|
||||||
int index = dynamic_images_->GetExecutableImageIndex();
|
if (dynamic_images_) {
|
||||||
|
int index = dynamic_images_->GetExecutableImageIndex();
|
||||||
|
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
return index;
|
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
|
// failed - just use the first image
|
||||||
|
@ -645,7 +708,8 @@ bool MinidumpGenerator::WriteModuleListStream(
|
||||||
if (!_dyld_present())
|
if (!_dyld_present())
|
||||||
return false;
|
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))
|
if (!list.AllocateObjectAndArray(image_count, MD_MODULE_SIZE))
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue