| Index: tools/mac/catch_exception_tool.cc
|
| diff --git a/tools/mac/catch_exception_tool.cc b/tools/mac/catch_exception_tool.cc
|
| index d3b2dd58854fe4d6bcb15cac5746b77fcf507480..902010be57d8243602091cbc5d8aa5ac5488bdb5 100644
|
| --- a/tools/mac/catch_exception_tool.cc
|
| +++ b/tools/mac/catch_exception_tool.cc
|
| @@ -79,20 +79,34 @@ class ExceptionServer : public UniversalMachExcServer::Interface {
|
| ++*exceptions_handled_;
|
|
|
| fprintf(options_.file,
|
| - "%s: behavior %s, ",
|
| + "%s: behavior %s",
|
| me_.c_str(),
|
| ExceptionBehaviorToString(
|
| behavior, kUseFullName | kUnknownIsNumeric | kUseOr).c_str());
|
|
|
| kern_return_t kr;
|
| if (ExceptionBehaviorHasIdentity(behavior)) {
|
| - pid_t pid;
|
| - kr = pid_for_task(task, &pid);
|
| - if (kr != KERN_SUCCESS) {
|
| - MACH_LOG(ERROR, kr) << "pid_for_task";
|
| - return KERN_FAILURE;
|
| + // It’s not possible to call pid_for_task() once EXC_CORPSE_NOTIFY has
|
| + // been generated. It is possible to obtain the process ID by mapping the
|
| + // corpse kcdata area from the task’s address space at code[0] (size
|
| + // code[1]) and locating TASK_CRASHINFO_PID within that area. This area
|
| + // also includes TASK_CRASHINFO_CRASHED_THREADID which could be used
|
| + // instead of thread_info() below, and TASK_CRASHINFO_EXCEPTION_CODES
|
| + // which could be used to recover the exception codes passed to the
|
| + // EXC_CRASH handler. None of this is currently done because corpses are a
|
| + // new 10.11-only feature. See 10.11 <corpses/task_corpse.h> and
|
| + // <kern/kern_cdata.h>.
|
| + if (exception != EXC_CORPSE_NOTIFY) {
|
| + pid_t pid;
|
| + kr = pid_for_task(task, &pid);
|
| + if (kr != KERN_SUCCESS) {
|
| + fprintf(options_.file, "\n");
|
| + fflush(options_.file);
|
| + MACH_LOG(ERROR, kr) << "pid_for_task";
|
| + return KERN_FAILURE;
|
| + }
|
| + fprintf(options_.file, ", pid %d", pid);
|
| }
|
| - fprintf(options_.file, "pid %d, ", pid);
|
|
|
| thread_identifier_info identifier_info;
|
| mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
|
| @@ -101,23 +115,25 @@ class ExceptionServer : public UniversalMachExcServer::Interface {
|
| reinterpret_cast<thread_info_t>(&identifier_info),
|
| &count);
|
| if (kr != KERN_SUCCESS) {
|
| + fprintf(options_.file, "\n");
|
| + fflush(options_.file);
|
| MACH_LOG(ERROR, kr) << "thread_info";
|
| return KERN_FAILURE;
|
| }
|
| - fprintf(options_.file, "thread %lld, ", identifier_info.thread_id);
|
| + fprintf(options_.file, ", thread %lld", identifier_info.thread_id);
|
| }
|
|
|
| fprintf(
|
| options_.file,
|
| - "exception %s, codes[%d] ",
|
| + ", exception %s, codes[%d]",
|
| ExceptionToString(exception, kUseFullName | kUnknownIsNumeric).c_str(),
|
| code_count);
|
|
|
| for (size_t index = 0; index < code_count; ++index) {
|
| fprintf(options_.file,
|
| - "%#llx%s",
|
| - code[index],
|
| - index != code_count - 1 ? ", " : "");
|
| + "%s %#llx",
|
| + index != 0 ? "," : "",
|
| + code[index]);
|
| }
|
|
|
| if (exception == EXC_CRASH) {
|
| @@ -153,7 +169,7 @@ class ExceptionServer : public UniversalMachExcServer::Interface {
|
| ExcServerCopyState(
|
| behavior, old_state, old_state_count, new_state, new_state_count);
|
|
|
| - return ExcServerSuccessfulReturnValue(behavior, false);
|
| + return ExcServerSuccessfulReturnValue(exception, behavior, false);
|
| }
|
|
|
| private:
|
|
|