Skip to content

Commit 6476059

Browse files
JoeMattclaude
andcommitted
fix: free table68k + branch_condition_table on shutdown (#125)
The sanitizers CI job (added in PR #121) surfaced two ASAN leaks totaling ~1.5 MB on every test run after the m68000 UBSAN noise was filtered out: 1. table68k (src/m68000/readcpu.c:928) -- 65536 * sizeof(struct instr) ~= 1.5 MB. Allocated lazily on first m68k_pulse_reset, never freed. 2. branch_condition_table (src/tom/gpu.c:257) -- 256 bytes (32 * 8 conditional-flag LUT). Allocated by GPUInit -> build_branch_condition_table, never freed. Both are process-lifetime one-time inits. In a libretro core that gets dlopen'd / dlclose'd repeatedly (e.g., the iOS Provenance host), these leaked on every load cycle. Fix: - Add GPUDone() -- frees branch_condition_table, NULLs the pointer so a subsequent GPUInit re-allocates cleanly. Wired into TOMDone alongside OPDone() / BlitterDone(). - Add m68k_done() -- frees table68k, NULLs the pointer, resets the file-scope `emulation_initialized` flag (was function-static in m68k_pulse_reset; hoisted to file scope so the new done can reset it). Wired into JaguarDone after the existing subsystem Done() calls. Both done functions are idempotent and safe to call without a prior init (free(NULL) is a no-op). Closes #125. Co-Authored-By: Claude Opus 4.7 <[email protected]>
1 parent 709ffca commit 6476059

6 files changed

Lines changed: 34 additions & 2 deletions

File tree

src/core/jaguar.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ void JaguarDone(void)
919919
DSPDone();
920920
TOMDone();
921921
JERRYDone();
922+
m68k_done();
922923
}
923924

924925
uint8_t * GetRamPtr(void)

src/m68000/m68kinterface.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,25 @@ void M68KDebugResume(void)
7878
}
7979

8080

81+
// File-scope so m68k_done() below can reset it after freeing table68k.
82+
static uint32_t emulation_initialized = 0;
83+
84+
// Free process-lifetime allocations made by read_table68k(). Called
85+
// from JaguarDone() so ASAN runs see a clean shutdown.
86+
extern struct instr * table68k;
87+
void m68k_done(void)
88+
{
89+
if (table68k)
90+
{
91+
free(table68k);
92+
table68k = NULL;
93+
}
94+
emulation_initialized = 0;
95+
}
96+
8197
// Pulse the RESET line on the CPU
8298
void m68k_pulse_reset(void)
8399
{
84-
static uint32_t emulation_initialized = 0;
85-
86100
// The first call to this function initializes the opcode handler jump table
87101
if (!emulation_initialized)
88102
{

src/m68000/m68kinterface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ typedef enum
7070
#define M68K_INT_ACK_SPURIOUS 0xFFFFFFFE
7171

7272
void m68k_pulse_reset(void);
73+
void m68k_done(void);
7374
int m68k_execute(int num_cycles);
7475
void m68k_set_irq(unsigned int int_level);
7576

src/tom/gpu.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,20 @@ void GPUInit(void)
642642
GPUReset();
643643
}
644644

645+
void GPUDone(void)
646+
{
647+
/* Release the branch-condition LUT so process-lifetime ASAN runs
648+
* don't report it as a leak. Safe to call without a matching
649+
* GPUInit (free(NULL) is a no-op) and safe to re-call after a
650+
* subsequent GPUInit (build_branch_condition_table early-outs on
651+
* non-NULL pointer). */
652+
if (branch_condition_table)
653+
{
654+
free(branch_condition_table);
655+
branch_condition_table = NULL;
656+
}
657+
}
658+
645659
void GPUReset(void)
646660
{
647661
unsigned i;

src/tom/gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extern "C" {
1515
#define GPU_WORK_RAM_BASE 0x00F03000
1616

1717
void GPUInit(void);
18+
void GPUDone(void);
1819
void GPUReset(void);
1920
void GPUExec(int32_t);
2021
void GPUUpdateRegisterBanks(void);

src/tom/tom.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,7 @@ void TOMDone(void)
846846
{
847847
OPDone();
848848
BlitterDone();
849+
GPUDone();
849850
}
850851

851852

0 commit comments

Comments
 (0)