Skip to content

Commit 8d8e6b3

Browse files
committed
Fix async-signal-safety in MMU cache stat handler
The signal handler for SIGINT/SIGTERM was calling fprintf(), which is not async-signal-safe and can lead to deadlocks or data corruption. - Use volatile sig_atomic_t flag instead of calling fprintf directly - Signal handler now only sets the flag (async-signal-safe) - Main loops check the flag and print statistics when safe - Applies to both SMP (coroutine) and single-hart execution paths
1 parent e9fa09a commit 8d8e6b3

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

main.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -911,15 +911,15 @@ static int semu_step(emu_state_t *emu)
911911

912912
#ifdef MMU_CACHE_STATS
913913
static vm_t *global_vm_for_signal = NULL;
914+
static volatile sig_atomic_t signal_received = 0;
914915

915916
/* Forward declaration */
916917
static void print_mmu_cache_stats(vm_t *vm);
917918

919+
/* Async-signal-safe handler: only set flag, defer printing */
918920
static void signal_handler_stats(int sig UNUSED)
919921
{
920-
if (global_vm_for_signal)
921-
print_mmu_cache_stats(global_vm_for_signal);
922-
exit(0);
922+
signal_received = 1;
923923
}
924924

925925
static void print_mmu_cache_stats(vm_t *vm)
@@ -1029,6 +1029,13 @@ static int semu_run(emu_state_t *emu)
10291029
#endif
10301030

10311031
while (!emu->stopped) {
1032+
#ifdef MMU_CACHE_STATS
1033+
/* Check if signal received (SIGINT/SIGTERM) */
1034+
if (signal_received) {
1035+
print_mmu_cache_stats(&emu->vm);
1036+
return 0;
1037+
}
1038+
#endif
10321039
/* Resume each hart's coroutine in round-robin fashion */
10331040
for (uint32_t i = 0; i < vm->n_hart; i++) {
10341041
coro_resume_hart(i);
@@ -1122,6 +1129,11 @@ static int semu_run(emu_state_t *emu)
11221129
if (ret)
11231130
return ret;
11241131
#ifdef MMU_CACHE_STATS
1132+
/* Check if signal received (SIGINT/SIGTERM) */
1133+
if (signal_received) {
1134+
print_mmu_cache_stats(&emu->vm);
1135+
return 0;
1136+
}
11251137
/* Exit after running for 15 seconds to collect statistics */
11261138
gettimeofday(&current_time, NULL);
11271139
long elapsed_sec = current_time.tv_sec - start_time.tv_sec;

0 commit comments

Comments
 (0)