gems-kernel/source/THIRDPARTY/xnu/libkern/os/system_event_log.c
2024-06-03 11:29:39 -05:00

92 lines
2.2 KiB
C

/* Copyright (c) 2021 Apple Inc. All rights reserved. */
#include <kern/clock.h>
#include <libkern/libkern.h>
#include <machine/machine_routines.h>
#include <os/system_event_log.h>
static const char *
convert_subsystem_to_string(uint8_t subsystem)
{
switch (subsystem) {
case SYSTEM_EVENT_SUBSYSTEM_LAUNCHD:
return "launchd";
case SYSTEM_EVENT_SUBSYSTEM_TEST:
return "test";
case SYSTEM_EVENT_SUBSYSTEM_NVRAM:
return "nvram";
case SYSTEM_EVENT_SUBSYSTEM_PROCESS:
return "process";
case SYSTEM_EVENT_SUBSYSTEM_PMRD:
return "iopmrd";
default:
break;
}
return "UNKNOWN";
}
static const char *
convert_type_to_string(uint8_t type)
{
switch (type) {
case SYSTEM_EVENT_TYPE_INFO:
return "INFO";
case SYSTEM_EVENT_TYPE_ERROR:
return "ERROR";
default:
break;
}
return "UNKNOWN";
}
/* We don't want to interfere with critical tasks.
* Skip recording this event if:
* 1. Interrupts are disabled.
* 2. We are not in a panic.
* A suggested improvement is adding events to an MPSC queue to log later on (rdar://84678724).
*/
static bool
is_recording_allowed(void)
{
return ml_get_interrupts_enabled() || panic_active();
}
static void
_record_system_event_internal(uint8_t type, uint8_t subsystem, const char *event, const char *payload)
{
const char *type_string = convert_type_to_string(type);
const char *subsystem_string = convert_subsystem_to_string(subsystem);
uint64_t nanosecs;
const uint64_t timestamp = mach_continuous_time();
absolutetime_to_nanoseconds(timestamp, &nanosecs);
printf("[System Event] [%llu] [%s] [Subsystem: %s] [Event: %.*s] %s\n", timestamp, type_string, subsystem_string, SYSTEM_EVENT_EVENT_MAX, event, payload);
}
void
record_system_event(uint8_t type, uint8_t subsystem, const char *event, const char *format, ...)
{
if (!is_recording_allowed()) {
return;
}
va_list args;
va_start(args, format);
char payload[SYSTEM_EVENT_PAYLOAD_MAX];
vsnprintf(payload, sizeof(payload), format, args);
va_end(args);
_record_system_event_internal(type, subsystem, event, payload);
}
void
record_system_event_no_varargs(uint8_t type, uint8_t subsystem, const char *event, const char *payload)
{
if (!is_recording_allowed()) {
return;
}
_record_system_event_internal(type, subsystem, event, payload);
}