mdbg: switch klog monitoring to debug log snapshots

This commit is contained in:
Roman Tarasov committed 2026-04-17 01:51:45 +03:00
1 parent c37088543d
commit a8f1a216bd
5 files changed
+279 -168

No files matched your search

+1 -1
View File
@@ -64,7 +64,7 @@ jobs:
- name: Build payload
run: |
make clean all
make clean all PS5_SCE_STUBS_DIR="$GITHUB_WORKSPACE/pacbrew-repo/sdk/sce_stubs"
- name: Create release archive
id: package
+11 -4
View File
@@ -11,7 +11,10 @@ CFLAGS += -DSHADOWMOUNT_VERSION=\"$(VERSION_TAG)\"
LDFLAGS := -flto=thin -Wl,--gc-sections
# Standard Libraries Only
LIBS := -lkernel_sys -lSceNotification -lSceSystemService -lSceUserService -lSceAppInstUtil -lsqlite3
LIBS := -lSceNotification -lSceSystemService -lSceUserService -lSceAppInstUtil -lsqlite3
PS5_SCE_STUBS_DIR ?= $(PS5_PAYLOAD_SDK)/src/sce_stubs
KERNEL_SYS_STUB_SO := src/libkernel_sys_ext.so
KERNEL_SYS_STUB_SRCS := $(PS5_SCE_STUBS_DIR)/libkernel_sys.c src/libkernel_sys_ext.c
ASSET_SRCS := src/notify_icon_asset.c src/config_ini_example_asset.c
SRCS := src/main.c $(wildcard src/sm_*.c) $(ASSET_SRCS)
@@ -22,11 +25,15 @@ HEADERS := $(wildcard include/*.h)
all: shadowmountplus.elf
# Build Daemon
shadowmountplus.elf: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
shadowmountplus.elf: $(OBJS) $(KERNEL_SYS_STUB_SO)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(KERNEL_SYS_STUB_SO) $(LIBS)
$(PS5_PAYLOAD_SDK)/bin/prospero-strip --strip-all $@
rm -f src/notify_icon_asset.c src/config_ini_example_asset.c
$(KERNEL_SYS_STUB_SO): $(KERNEL_SYS_STUB_SRCS)
test -f "$(PS5_SCE_STUBS_DIR)/libkernel_sys.c"
$(CC) -shared -Wl,-soname=libkernel_sys.sprx -o $@ $^
src/notify_icon_asset.c: smp_icon.png
xxd -i $< > $@
@@ -37,4 +44,4 @@ src/%.o: src/%.c $(HEADERS)
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f shadowmountplus.elf kill.elf src/*.o src/notify_icon_asset.c src/config_ini_example_asset.c
rm -f shadowmountplus.elf kill.elf src/*.o $(KERNEL_SYS_STUB_SO) src/notify_icon_asset.c src/config_ini_example_asset.c
+3
View File
@@ -0,0 +1,3 @@
asm(".global \"C49jelxiaVE\"\n"
".type \"C49jelxiaVE\" @function\n"
"\"C49jelxiaVE\":\n");
+4 -1
View File
@@ -34,7 +34,10 @@
#define RESTART_WAIT_MAX_US 60000000u
#define KINFO_PID_OFFSET 72
#define KINFO_TDNAME_OFFSET 447
#define AUTHID_BASE 0x4801000000000013L
//#define AUTHID_BASE 0x4801000000000013L
#define AUTHID_BASE 0x4800000000000006ull
static volatile sig_atomic_t g_stop_requested = 0;
static atomic_bool g_shutdown_on_going_stop_requested = false;
+260 -162
View File
@@ -13,7 +13,12 @@
#include "sm_time.h"
#include "sm_types.h"
#define SCE_AUTHID_COREDUMP 0x4800000000000006ull
int sceKernelDebugGetPrivateLogText(void *buffer, size_t buffer_size,
char **text, uint64_t *text_size);
int sceKernelDebugGetSdkLogText(void *buffer, size_t buffer_size,
char **text, uint64_t *text_size);
uint64_t sceKernelDebugGetLogBufferSize(void) __asm__("C49jelxiaVE");
#define SYS_mdbg_call 573
#define MDBG_CMD_TYPE_SERVICE 1ull
@@ -23,9 +28,20 @@
#define MDBG_FLAG_EXCEPTION_STOP 0x00080000ull
#define MDBG_AUTOTUNE_WINDOW_US (300ull * 1000000ull)
#define KLOG_DEVICE_PATH "/dev/klog"
#define KLOG_POLL_CHUNK_SIZE 512u
#define KLOG_LINE_BUFFER_SIZE 512u
#define MDBG_LOG_LINE_BUFFER_SIZE 512u
#define MDBG_RTLD_ERROR_PREFIX_SIZE 32u
#ifndef MDBG_USE_PRIVATE_LOG_TEXT
#define MDBG_USE_PRIVATE_LOG_TEXT 0
#endif
#ifndef MDBG_SKIP_PRIVILEGE_ELEVATION
#define MDBG_SKIP_PRIVILEGE_ELEVATION 0
#endif
#if MDBG_USE_PRIVATE_LOG_TEXT
#define MDBG_FETCH_LOG_TEXT sceKernelDebugGetPrivateLogText
#else
#define MDBG_FETCH_LOG_TEXT sceKernelDebugGetSdkLogText
#endif
typedef struct {
uint64_t type;
@@ -47,7 +63,7 @@ typedef struct {
typedef struct {
bool active;
bool klog_monitoring_active;
bool log_monitoring_active;
bool pause_seen;
pid_t pid;
uint32_t pause_delay_seconds;
@@ -56,22 +72,27 @@ typedef struct {
uint64_t next_poll_us;
char title_id[MAX_TITLE_ID];
char comm[32];
char rtld_error_prefix[MDBG_RTLD_ERROR_PREFIX_SIZE];
} mdbg_game_state_t;
typedef struct {
bool privilege_probe_done;
bool privilege_ready;
bool klog_open_failed_logged;
int klog_fd;
size_t klog_line_length;
char klog_line[KLOG_LINE_BUFFER_SIZE];
size_t log_buffer_size;
size_t log_snapshot_length;
size_t log_line_length;
char *log_snapshot;
char *log_storage;
char log_line[MDBG_LOG_LINE_BUFFER_SIZE];
mdbg_game_state_t game;
} sm_mdbg_state_t;
static sm_mdbg_state_t g_mdbg;
static bool sm_mdbg_enabled(void);
#if !MDBG_SKIP_PRIVILEGE_ELEVATION
static int elevate_to_coredump(void);
#endif
static bool ensure_mdbg_privileges(void);
static int mdbg_call_raw(int64_t pid, uint64_t subcmd, uint64_t arg,
int64_t *status_out, uint64_t *value_out);
@@ -80,24 +101,25 @@ static int query_mdbg_state3(pid_t pid, uint32_t *state_flags_out,
uint32_t *stop_reason_out);
static bool read_proc_info(pid_t pid, struct kinfo_proc *ki);
static bool is_mdbg_process_gone_error(int ret);
static void reset_tracked_game(mdbg_game_state_t *game);
static void reset_klog_buffer(void);
static bool open_klog_device(void);
static void close_klog_device(void);
static void reset_log_line_buffer(void);
static void reset_log_snapshot(void);
static void free_log_buffers(void);
static bool ensure_log_buffers(void);
static int fetch_log_text(const char **text_out, size_t *text_len_out);
static size_t find_log_overlap(const char *current, size_t current_len);
static void update_log_snapshot(const char *text, size_t text_len);
static void clear_tracked_game(void);
static void capture_process_comm(const struct kinfo_proc *ki);
static bool parse_klog_rtld_error(const char *line, pid_t *pid_out);
static bool klog_line_matches_tracked_load_error(const char *line);
static bool log_line_matches_tracked_load_error(const char *line);
static bool reason_is_rtld_error(const char *reason);
static void summarize_failure_reason(const char *reason, char *summary_out,
size_t summary_out_size);
static void handle_pre_pause_failure(const char *reason);
static void handle_post_pause_failure(const char *reason, uint64_t now_us);
static void process_klog_line(const char *line, uint64_t now_us);
static void append_klog_char(char ch, uint64_t now_us);
static void drain_klog_monitor(void);
static void poll_klog_monitor(uint64_t now_us);
static void start_klog_monitoring(void);
static void process_log_line(const char *line, uint64_t now_us);
static void append_log_char(char ch, uint64_t now_us);
static void drain_log_monitor(void);
static void poll_log_monitor(uint64_t now_us);
static void start_log_monitoring(void);
static void handle_crash_candidate(uint64_t flags, uint32_t state_flags,
uint32_t stop_reason, uint64_t now_us);
@@ -106,6 +128,8 @@ static bool sm_mdbg_enabled(void) {
runtime_config()->kstuff_game_auto_toggle;
}
#if !MDBG_SKIP_PRIVILEGE_ELEVATION
#define SCE_AUTHID_COREDUMP 0x4800000000000006ull
static int elevate_to_coredump(void) {
static const uint8_t k_priv_caps[16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -119,19 +143,25 @@ static int elevate_to_coredump(void) {
return 0;
}
#endif
static bool ensure_mdbg_privileges(void) {
if (g_mdbg.privilege_probe_done)
return g_mdbg.privilege_ready;
g_mdbg.privilege_probe_done = true;
#if MDBG_SKIP_PRIVILEGE_ELEVATION
g_mdbg.privilege_ready = true;
log_debug(" [MDBG] coredump privilege probe skipped");
#else
g_mdbg.privilege_ready = elevate_to_coredump() == 0;
if (g_mdbg.privilege_ready) {
log_debug(" [MDBG] coredump privileges enabled");
} else {
log_debug(" [MDBG] failed to enable coredump privileges; mdbg polling "
"disabled, klog monitoring will continue");
"disabled, log monitoring disabled");
}
#endif
return g_mdbg.privilege_ready;
}
@@ -214,95 +244,141 @@ static bool is_mdbg_process_gone_error(int ret) {
return ret == -ESRCH || ret == -ENOENT || ret == ESRCH || ret == ENOENT;
}
static void reset_tracked_game(mdbg_game_state_t *game) {
if (!game)
return;
memset(game, 0, sizeof(*game));
static void reset_log_line_buffer(void) {
g_mdbg.log_line_length = 0;
g_mdbg.log_line[0] = '\0';
}
static void reset_klog_buffer(void) {
g_mdbg.klog_line_length = 0;
g_mdbg.klog_line[0] = '\0';
static void reset_log_snapshot(void) {
g_mdbg.log_snapshot_length = 0;
reset_log_line_buffer();
}
static bool open_klog_device(void) {
if (g_mdbg.klog_fd >= 0)
static void free_log_buffers(void) {
free(g_mdbg.log_snapshot);
free(g_mdbg.log_storage);
g_mdbg.log_snapshot = NULL;
g_mdbg.log_storage = NULL;
g_mdbg.log_buffer_size = 0;
reset_log_snapshot();
}
static bool ensure_log_buffers(void) {
if (g_mdbg.log_storage && g_mdbg.log_snapshot && g_mdbg.log_buffer_size != 0)
return true;
int open_flags = O_RDONLY | O_NONBLOCK;
#ifdef O_SHLOCK
open_flags |= O_SHLOCK;
#endif
free_log_buffers();
int fd = open(KLOG_DEVICE_PATH, open_flags);
if (fd < 0) {
if (!g_mdbg.klog_open_failed_logged) {
log_debug(" [MDBG] failed to open %s for %s: %s", KLOG_DEVICE_PATH,
g_mdbg.game.title_id[0] != '\0' ? g_mdbg.game.title_id : "?",
strerror(errno));
g_mdbg.klog_open_failed_logged = true;
}
const char *title_id =
g_mdbg.game.title_id[0] != '\0' ? g_mdbg.game.title_id : "?";
uint64_t raw_size = sceKernelDebugGetLogBufferSize();
if (raw_size == 0) {
log_debug(" [MDBG] invalid log buffer size for %s: 0x%016" PRIx64,
title_id,
raw_size);
return false;
}
g_mdbg.klog_fd = fd;
g_mdbg.klog_open_failed_logged = false;
size_t buffer_size = (size_t)raw_size;
char *storage = malloc(buffer_size);
char *snapshot = malloc(buffer_size);
if (!storage || !snapshot) {
free(storage);
free(snapshot);
log_debug(" [MDBG] failed to allocate log buffers for %s: size=0x%zx",
title_id,
buffer_size);
return false;
}
g_mdbg.log_storage = storage;
g_mdbg.log_snapshot = snapshot;
g_mdbg.log_buffer_size = buffer_size;
reset_log_snapshot();
log_debug(" [MDBG] log monitor ready: %s buffer_size=0x%zx", title_id,
buffer_size);
return true;
}
static void close_klog_device(void) {
if (g_mdbg.klog_fd < 0)
static int fetch_log_text(const char **text_out, size_t *text_len_out) {
char *raw_text = NULL;
uint64_t raw_len = 0;
if (!text_out || !text_len_out || !g_mdbg.log_storage ||
g_mdbg.log_buffer_size == 0) {
return -EINVAL;
}
*text_out = NULL;
*text_len_out = 0;
int ret =
MDBG_FETCH_LOG_TEXT(g_mdbg.log_storage, g_mdbg.log_buffer_size, &raw_text,
&raw_len);
if (ret < 0)
return ret;
if (!raw_text || raw_len == 0) {
*text_out = "";
return 0;
}
if (raw_len > g_mdbg.log_buffer_size)
return -EOVERFLOW;
*text_out = raw_text;
*text_len_out = (size_t)raw_len;
return 0;
}
static size_t find_log_overlap(const char *current, size_t current_len) {
if (!g_mdbg.log_snapshot || g_mdbg.log_snapshot_length == 0 || !current ||
current_len == 0) {
return 0;
}
size_t max_overlap = g_mdbg.log_snapshot_length < current_len
? g_mdbg.log_snapshot_length
: current_len;
for (size_t overlap = max_overlap; overlap > 0; --overlap) {
if (!memcmp(g_mdbg.log_snapshot + g_mdbg.log_snapshot_length - overlap,
current, overlap)) {
return overlap;
}
}
return 0;
}
static void update_log_snapshot(const char *text, size_t text_len) {
if (!g_mdbg.log_snapshot || g_mdbg.log_buffer_size == 0)
return;
close(g_mdbg.klog_fd);
g_mdbg.klog_fd = -1;
reset_klog_buffer();
g_mdbg.klog_open_failed_logged = false;
if (!text || text_len == 0) {
g_mdbg.log_snapshot_length = 0;
return;
}
if (text_len > g_mdbg.log_buffer_size)
text_len = g_mdbg.log_buffer_size;
memcpy(g_mdbg.log_snapshot, text, text_len);
g_mdbg.log_snapshot_length = text_len;
}
static void clear_tracked_game(void) {
reset_tracked_game(&g_mdbg.game);
reset_klog_buffer();
memset(&g_mdbg.game, 0, sizeof(g_mdbg.game));
free_log_buffers();
}
static void capture_process_comm(const struct kinfo_proc *ki) {
if (!ki)
return;
(void)strlcpy(g_mdbg.game.comm, ki->ki_comm, sizeof(g_mdbg.game.comm));
}
static bool parse_klog_rtld_error(const char *line, pid_t *pid_out) {
if (!line || line[0] == '\0')
return false;
if (strstr(line, "[rtld]") == NULL || strstr(line, "ERROR") == NULL)
return false;
const char *open = strchr(line, '<');
if (!open)
return false;
char *end = NULL;
long parsed_pid = strtol(open + 1, &end, 10);
if (end == open + 1 || !end || *end != '>' || parsed_pid <= 0)
return false;
if (pid_out)
*pid_out = (pid_t)parsed_pid;
return true;
}
static bool klog_line_matches_tracked_load_error(const char *line) {
pid_t line_pid = 0;
return parse_klog_rtld_error(line, &line_pid) && g_mdbg.game.active &&
g_mdbg.game.pid == line_pid;
static bool log_line_matches_tracked_load_error(const char *line) {
return line && g_mdbg.game.active &&
g_mdbg.game.rtld_error_prefix[0] != '\0' &&
strstr(line, g_mdbg.game.rtld_error_prefix) != NULL;
}
static bool reason_is_rtld_error(const char *reason) {
return parse_klog_rtld_error(reason, NULL);
return reason && g_mdbg.game.rtld_error_prefix[0] != '\0' &&
strstr(reason, g_mdbg.game.rtld_error_prefix) != NULL;
}
static void summarize_failure_reason(const char *reason, char *summary_out,
@@ -374,7 +450,7 @@ static void handle_post_pause_failure(const char *reason, uint64_t now_us) {
if (reason_summary[0] != '\0')
log_debug(" [MDBG] autotune trigger: %s", reason_summary);
if (reason_is_rtld_error(reason)) {
notify_system_info("%s: %s. Delay increased to %us.",
notify_system_info("%s: %s. Delay increased to %us.\nLaunch the game again.",
g_mdbg.game.title_id,
reason_summary[0] != '\0' ? reason_summary
: "Can't load module after "
@@ -397,96 +473,114 @@ static void handle_post_pause_failure(const char *reason, uint64_t now_us) {
clear_tracked_game();
}
static void process_klog_line(const char *line, uint64_t now_us) {
if (!klog_line_matches_tracked_load_error(line))
static void process_log_line(const char *line, uint64_t now_us) {
if (!log_line_matches_tracked_load_error(line))
return;
log_debug(" [MDBG] klog load error for %s: %s", g_mdbg.game.title_id, line);
log_debug(" [MDBG] log load error for %s: %s", g_mdbg.game.title_id, line);
handle_post_pause_failure(line, now_us);
}
static void append_klog_char(char ch, uint64_t now_us) {
static void append_log_char(char ch, uint64_t now_us) {
if (!g_mdbg.game.active)
return;
if (ch == '\r' || ch == '\n') {
if (g_mdbg.klog_line_length == 0)
if (g_mdbg.log_line_length == 0)
return;
g_mdbg.klog_line[g_mdbg.klog_line_length] = '\0';
process_klog_line(g_mdbg.klog_line, now_us);
reset_klog_buffer();
g_mdbg.log_line[g_mdbg.log_line_length] = '\0';
process_log_line(g_mdbg.log_line, now_us);
reset_log_line_buffer();
return;
}
if (g_mdbg.klog_line_length + 1u >= sizeof(g_mdbg.klog_line)) {
g_mdbg.klog_line[g_mdbg.klog_line_length] = '\0';
process_klog_line(g_mdbg.klog_line, now_us);
reset_klog_buffer();
if (g_mdbg.log_line_length + 1u >= sizeof(g_mdbg.log_line)) {
g_mdbg.log_line[g_mdbg.log_line_length] = '\0';
process_log_line(g_mdbg.log_line, now_us);
reset_log_line_buffer();
}
g_mdbg.klog_line[g_mdbg.klog_line_length++] = ch;
g_mdbg.log_line[g_mdbg.log_line_length++] = ch;
}
static void drain_klog_monitor(void) {
if (g_mdbg.klog_fd < 0)
static void drain_log_monitor(void) {
if (!g_mdbg.game.log_monitoring_active)
return;
char chunk[KLOG_POLL_CHUNK_SIZE];
for (;;) {
ssize_t read_size = read(g_mdbg.klog_fd, chunk, sizeof(chunk));
if (read_size <= 0) {
if (read_size < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
log_debug(" [MDBG] /dev/klog initial drain failed for %s: %s",
g_mdbg.game.title_id, strerror(errno));
g_mdbg.game.klog_monitoring_active = false;
}
break;
if (!ensure_log_buffers()) {
g_mdbg.game.log_monitoring_active = false;
return;
}
const char *text = NULL;
size_t text_len = 0;
int ret = fetch_log_text(&text, &text_len);
if (ret < 0) {
log_debug(" [MDBG] initial log snapshot failed for %s: 0x%08x",
g_mdbg.game.title_id, ret);
g_mdbg.game.log_monitoring_active = false;
reset_log_snapshot();
return;
}
update_log_snapshot(text, text_len);
reset_log_line_buffer();
}
static void poll_log_monitor(uint64_t now_us) {
if (!g_mdbg.game.active || !g_mdbg.game.log_monitoring_active) {
return;
}
if (!ensure_log_buffers()) {
g_mdbg.game.log_monitoring_active = false;
return;
}
const char *text = NULL;
size_t text_len = 0;
int ret = fetch_log_text(&text, &text_len);
if (ret < 0) {
log_debug(" [MDBG] log snapshot failed for %s: 0x%08x",
g_mdbg.game.title_id, ret);
g_mdbg.game.log_monitoring_active = false;
reset_log_snapshot();
return;
}
size_t skip = 0;
if (g_mdbg.log_snapshot_length != 0 && text_len >= g_mdbg.log_snapshot_length &&
!memcmp(g_mdbg.log_snapshot, text, g_mdbg.log_snapshot_length)) {
skip = g_mdbg.log_snapshot_length;
} else {
skip = find_log_overlap(text, text_len);
if (skip == 0 && g_mdbg.log_snapshot_length != 0) {
log_debug(" [MDBG] log stream reset or truncated for %s",
g_mdbg.game.title_id);
reset_log_line_buffer();
}
}
reset_klog_buffer();
}
static void poll_klog_monitor(uint64_t now_us) {
if (!g_mdbg.game.active || !g_mdbg.game.klog_monitoring_active) {
return;
for (size_t i = skip; i < text_len; ++i) {
append_log_char(text[i], now_us);
if (!g_mdbg.game.active)
return;
}
if (!open_klog_device())
return;
char chunk[KLOG_POLL_CHUNK_SIZE];
for (;;) {
ssize_t read_size = read(g_mdbg.klog_fd, chunk, sizeof(chunk));
if (read_size == 0)
return;
if (read_size < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
return;
log_debug(" [MDBG] /dev/klog read failed for %s: %s",
g_mdbg.game.title_id, strerror(errno));
g_mdbg.game.klog_monitoring_active = false;
reset_klog_buffer();
return;
}
for (ssize_t i = 0; i < read_size; ++i) {
append_klog_char(chunk[i], now_us);
if (!g_mdbg.game.active)
return;
}
}
update_log_snapshot(text, text_len);
}
static void start_klog_monitoring(void) {
static void start_log_monitoring(void) {
if (!g_mdbg.game.active)
return;
g_mdbg.game.klog_monitoring_active = true;
if (!open_klog_device())
if (!ensure_mdbg_privileges()) {
g_mdbg.game.log_monitoring_active = false;
return;
drain_klog_monitor();
}
g_mdbg.game.log_monitoring_active = true;
drain_log_monitor();
}
static void handle_crash_candidate(uint64_t flags, uint32_t state_flags,
@@ -511,14 +605,10 @@ static void handle_crash_candidate(uint64_t flags, uint32_t state_flags,
void sm_mdbg_init(void) {
memset(&g_mdbg, 0, sizeof(g_mdbg));
g_mdbg.klog_fd = -1;
reset_tracked_game(&g_mdbg.game);
reset_klog_buffer();
}
void sm_mdbg_shutdown(void) {
clear_tracked_game();
close_klog_device();
g_mdbg.privilege_probe_done = false;
g_mdbg.privilege_ready = false;
}
@@ -543,10 +633,18 @@ void sm_mdbg_game_on_exec(pid_t pid, const char *title_id, uint32_t app_id) {
g_mdbg.game.pid = pid;
g_mdbg.game.next_poll_us = now_us;
(void)strlcpy(g_mdbg.game.title_id, title_id, sizeof(g_mdbg.game.title_id));
int rtld_prefix_len =
snprintf(g_mdbg.game.rtld_error_prefix,
sizeof(g_mdbg.game.rtld_error_prefix),
"[rtld] <%ld> ERROR", (long)pid);
if (rtld_prefix_len <= 0 ||
(size_t)rtld_prefix_len >= sizeof(g_mdbg.game.rtld_error_prefix)) {
g_mdbg.game.rtld_error_prefix[0] = '\0';
}
struct kinfo_proc ki;
if (read_proc_info(pid, &ki))
capture_process_comm(&ki);
(void)strlcpy(g_mdbg.game.comm, ki.ki_comm, sizeof(g_mdbg.game.comm));
log_debug(" [MDBG] tracking crash-candidate state: %s pid=%ld app_id=0x%08X",
g_mdbg.game.title_id, (long)pid, app_id);
@@ -563,7 +661,7 @@ void sm_mdbg_game_on_kstuff_pause(pid_t pid, uint64_t pause_time_us,
g_mdbg.game.pause_time_us + MDBG_AUTOTUNE_WINDOW_US;
g_mdbg.game.pause_delay_seconds = pause_delay_seconds;
g_mdbg.game.next_poll_us = pause_time_us;
start_klog_monitoring();
start_log_monitoring();
}
void sm_mdbg_game_on_exit(pid_t pid) {
@@ -610,18 +708,18 @@ void sm_mdbg_poll(void) {
return;
}
poll_klog_monitor(now_us);
if (!ensure_mdbg_privileges()) {
if (!g_mdbg.game.log_monitoring_active)
g_mdbg.game.next_poll_us = 0;
return;
}
poll_log_monitor(now_us);
if (!g_mdbg.game.active)
return;
g_mdbg.game.next_poll_us = now_us + GAME_LIFECYCLE_POLL_INTERVAL_US;
if (!ensure_mdbg_privileges()) {
if (!g_mdbg.game.klog_monitoring_active)
g_mdbg.game.next_poll_us = 0;
return;
}
uint64_t flags = 0;
int ret = query_mdbg_flags(g_mdbg.game.pid, &flags);
if (is_mdbg_process_gone_error(ret)) {