Encode the process' start time in the crash report.

This can be compared against the report timestamp to determine whether
the process crashed shortly after launch.
This commit is contained in:
Landon Fuller 2013-07-10 16:30:35 -04:00
Родитель e909fc6a6f
Коммит 8a284e4046
5 изменённых файлов: 36 добавлений и 9 удалений

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

@ -280,6 +280,9 @@ message CrashReport {
/** If false, the process is being run via process-level CPU emulation (such as Rosetta). */
required bool native = 6;
/** The start time of the process (as seconds since UNIX epoch). Required for all v1.2+ crash reports. */
optional uint64 start_time = 7;
}
/* The process info. Required for all v1.1+ crash reports. */

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

@ -183,16 +183,19 @@ message CrashReport_V2 {
/* Application process path */
optional string path = 3;
/** The start time of the process (as seconds since UNIX epoch). */
required uint64 start_time = 4;
/* Application parent process name */
optional string parent_name = 4;
optional string parent_name = 5;
/* Application parent process ID */
required uint64 parent_pid = 5;
required uint64 parent_pid = 6;
/** If false, the process is being run via process-level CPU emulation (such as Rosetta). If unknown, this
* value must be ommitted. */
optional bool native = 6;
optional bool native = 7;
}
/* The process info. */

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

@ -111,6 +111,9 @@ typedef struct plcrash_log_writer {
/** Process path (may be null) */
char *process_path;
/** Process start time */
time_t start_time;
/** Parent process name (may be null) */
char *parent_process_name;

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

@ -198,6 +198,9 @@ enum {
/** CrashReport.process_info.native */
PLCRASH_PROTO_PROCESS_INFO_NATIVE_ID = 6,
/** CrashReport.process_info.start_time */
PLCRASH_PROTO_PROCESS_INFO_START_TIME_ID = 7,
/** CrashReport.Processor.encoding */
@ -278,12 +281,14 @@ plcrash_error_t plcrash_log_writer_init (plcrash_log_writer_t *writer,
/* Retrieve PID */
writer->process_info.process_id = getpid();
/* Retrieve name */
/* Retrieve name and start time. */
process_info_mib[3] = writer->process_info.process_id;
if (sysctl(process_info_mib, process_info_mib_len, &process_info, &process_info_len, NULL, 0) == 0) {
writer->process_info.process_name = strdup(process_info.kp_proc.p_comm);
writer->process_info.start_time = process_info.kp_proc.p_starttime.tv_sec;
} else {
PLCF_DEBUG("Could not retreive process name: %s", strerror(errno));
return PLCRASH_EINTERNAL;
}
/* Retrieve path */
@ -635,13 +640,15 @@ static size_t plcrash_writer_write_app_info (plcrash_async_file_t *file, const c
* @param parent_process_name Parent process name
* @param parent_process_id Parent process ID
* @param native If false, process is running under emulation.
* @param start_time The start time of the process.
*/
static size_t plcrash_writer_write_process_info (plcrash_async_file_t *file, const char *process_name,
static size_t plcrash_writer_write_process_info (plcrash_async_file_t *file, const char *process_name,
const pid_t process_id, const char *process_path,
const char *parent_process_name, const pid_t parent_process_id,
bool native)
bool native, time_t start_time)
{
size_t rv = 0;
uint64_t tval;
/*
* In the current crash reporter serialization format, pid values are serialized as unsigned 32-bit integers. This
@ -665,10 +672,11 @@ static size_t plcrash_writer_write_process_info (plcrash_async_file_t *file, con
/* Process path */
if (process_path != NULL)
rv += plcrash_writer_pack(file, PLCRASH_PROTO_PROCESS_INFO_PROCESS_PATH_ID, PLPROTOBUF_C_TYPE_STRING, process_path);
/* Parent process name */
if (parent_process_name != NULL)
rv += plcrash_writer_pack(file, PLCRASH_PROTO_PROCESS_INFO_PARENT_PROCESS_NAME_ID, PLPROTOBUF_C_TYPE_STRING, parent_process_name);
/* Parent process ID */
pidval = parent_process_id;
@ -676,6 +684,10 @@ static size_t plcrash_writer_write_process_info (plcrash_async_file_t *file, con
/* Native process. */
rv += plcrash_writer_pack(file, PLCRASH_PROTO_PROCESS_INFO_NATIVE_ID, PLPROTOBUF_C_TYPE_BOOL, &native);
/* Start time */
tval = start_time;
rv += plcrash_writer_pack(file, PLCRASH_PROTO_PROCESS_INFO_START_TIME_ID, PLPROTOBUF_C_TYPE_UINT64, &tval);
return rv;
}
@ -1199,13 +1211,15 @@ plcrash_error_t plcrash_log_writer_write (plcrash_log_writer_t *writer,
/* Determine size */
size = plcrash_writer_write_process_info(NULL, writer->process_info.process_name, writer->process_info.process_id,
writer->process_info.process_path, writer->process_info.parent_process_name,
writer->process_info.parent_process_id, writer->process_info.native);
writer->process_info.parent_process_id, writer->process_info.native,
writer->process_info.start_time);
/* Write message */
plcrash_writer_pack(file, PLCRASH_PROTO_PROCESS_INFO_ID, PLPROTOBUF_C_TYPE_MESSAGE, &size);
plcrash_writer_write_process_info(file, writer->process_info.process_name, writer->process_info.process_id,
writer->process_info.process_path, writer->process_info.parent_process_name,
writer->process_info.parent_process_id, writer->process_info.native);
writer->process_info.parent_process_id, writer->process_info.native,
writer->process_info.start_time);
}
/* Threads */

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

@ -123,6 +123,10 @@
STAssertEquals((pid_t)procInfo->process_id, getpid(), @"Incorrect process id written");
STAssertEquals((pid_t)procInfo->parent_process_id, getppid(), @"Incorrect parent process id written");
STAssertTrue(procInfo->has_start_time, @"Missing start time value");
STAssertTrue(time(NULL) >= procInfo->start_time, @"Recorded time occured in the future");
STAssertTrue(time(NULL) - procInfo->start_time <= 60, @"Recorded time differs from the current time by more than 1 minute");
int retval;
if (plcrash_sysctl_int("sysctl.proc_native", &retval)) {