Implement serialization/deserialization of the Mach exception info.

This commit is contained in:
Landon Fuller 2013-08-30 19:11:58 -04:00
Родитель 24b6028d63
Коммит 6abfab116e
3 изменённых файлов: 63 добавлений и 2 удалений

Просмотреть файл

@ -260,7 +260,7 @@ message CrashReport {
*/
message MachException {
/* The exception type. These values will generally be common across most Apple platforms. */
required uint32 type = 1;
required uint64 type = 1;
/* The exception codes. Interpretation of these values depends on the exception type, and/or the
* faulting platform. */

Просмотреть файл

@ -178,7 +178,17 @@ enum {
/** CrashReport.signal.address */
PLCRASH_PROTO_SIGNAL_ADDRESS_ID = 3,
/** CrashReport.signal.mach_exception */
PLCRASH_PROTO_SIGNAL_MACH_EXCEPTION_ID = 4,
/** CrashReport.signal.mach_exception.type */
PLCRASH_PROTO_SIGNAL_MACH_EXCEPTION_TYPE_ID = 1,
/** CrashReport.signal.mach_exception.codes */
PLCRASH_PROTO_SIGNAL_MACH_EXCEPTION_CODES_ID = 2,
/** CrashReport.process_info */
PLCRASH_PROTO_PROCESS_INFO_ID = 7,
@ -1050,6 +1060,30 @@ static size_t plcrash_writer_write_exception (plcrash_async_file_t *file, plcras
return rv;
}
/**
* @internal
*
* Write the crash signal's mach exception info.
*
* @param file Output file
* @param siginfo The signal information
*/
static size_t plcrash_writer_write_mach_signal (plcrash_async_file_t *file, plcrash_log_mach_signal_info_t *siginfo) {
size_t rv = 0;
/* Type */
uint64_t type = siginfo->type;
rv += plcrash_writer_pack(file, PLCRASH_PROTO_SIGNAL_MACH_EXCEPTION_TYPE_ID, PLPROTOBUF_C_TYPE_UINT64, &type);
/* Code(s) */
for (mach_msg_type_number_t i = 0; i < siginfo->code_count; i++) {
uint64_t code = siginfo->code[i];
rv += plcrash_writer_pack(file, PLCRASH_PROTO_SIGNAL_MACH_EXCEPTION_CODES_ID, PLPROTOBUF_C_TYPE_UINT64, &code);
}
return rv;
}
/**
* @internal
*
@ -1090,6 +1124,18 @@ static size_t plcrash_writer_write_signal (plcrash_async_file_t *file, plcrash_l
rv += plcrash_writer_pack(file, PLCRASH_PROTO_SIGNAL_NAME_ID, PLPROTOBUF_C_TYPE_STRING, name);
rv += plcrash_writer_pack(file, PLCRASH_PROTO_SIGNAL_CODE_ID, PLPROTOBUF_C_TYPE_STRING, code);
rv += plcrash_writer_pack(file, PLCRASH_PROTO_SIGNAL_ADDRESS_ID, PLPROTOBUF_C_TYPE_UINT64, &addr);
/* Mach exception info */
if (siginfo->mach_info != NULL) {
uint32_t size;
/* Determine size */
size = plcrash_writer_write_mach_signal(NULL, siginfo->mach_info);
/* Write message */
rv += plcrash_writer_pack(file, PLCRASH_PROTO_SIGNAL_MACH_EXCEPTION_ID, PLPROTOBUF_C_TYPE_MESSAGE, &size);
rv += plcrash_writer_write_mach_signal(file, siginfo->mach_info);
}
return rv;
}

Просмотреть файл

@ -295,12 +295,20 @@
/* Initialze faux crash data */
plcrash_log_signal_info_t info;
plcrash_log_bsd_signal_info_t bsd_info;
plcrash_log_mach_signal_info_t mach_info;
mach_exception_data_type_t mach_codes[2];
{
bsd_info.address = (void *) 0x42;
bsd_info.code = SEGV_MAPERR;
bsd_info.signo = SIGSEGV;
info.mach_info = NULL;
mach_info.type = EXC_BAD_ACCESS;
mach_info.code = mach_codes;
mach_info.code_count = sizeof(mach_codes) / sizeof(mach_codes[0]);
mach_codes[0] = KERN_PROTECTION_FAILURE;
mach_codes[1] = 0x42;
info.mach_info = &mach_info;
info.bsd_info = &bsd_info;
/* Steal the test thread's stack for iteration */
@ -367,6 +375,13 @@
STAssertTrue(strcmp(crashReport->signal->name, "SIGSEGV") == 0, @"Signal incorrect");
STAssertTrue(strcmp(crashReport->signal->code, "SEGV_MAPERR") == 0, @"Signal code incorrect");
STAssertEquals((uint64_t) 0x42, crashReport->signal->address, @"Signal address incorrect");
/* Check the mach exception info */
STAssertNotNULL(crashReport->signal->mach_exception, @"Missing mach exceptiond info");
STAssertEquals(crashReport->signal->mach_exception->type, (uint64_t)EXC_BAD_ACCESS, @"Exception type incorrect");
STAssertEquals((size_t)2, crashReport->signal->mach_exception->n_codes, @"Code count incorrect");
STAssertEquals((uint64_t) KERN_PROTECTION_FAILURE, crashReport->signal->mach_exception->codes[0], @"code[0] incorrect");
STAssertEquals((uint64_t) 0x42, crashReport->signal->mach_exception->codes[1], @"code[1] incorrect");
/* Validate the 'crashed' flag is on a thread with the expected PC. */