Implement serialization/deserialization of the Mach exception info.
This commit is contained in:
Родитель
24b6028d63
Коммит
6abfab116e
|
@ -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. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче