From 4be77f11ea44f11a6ef094cce1d18271cd391626 Mon Sep 17 00:00:00 2001 From: baromas Date: Sat, 7 Nov 2026 22:57:22 +0300 Subject: [PATCH] fix: only flush OoT LightEvent diagnostics when enabled Gate the remaining diagnostic flushes and verify guest calls, 64-bit timeouts and return values with logging on and off. --- games/totk/runtime/services.c | 4 ++-- tests/test_light_event_observer.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/test_light_event_observer.py diff --git a/games/totk/runtime/services.c b/games/totk/runtime/services.c index 3e963c04c..78c975945 100644 --- a/games/totk/runtime/services.c +++ b/games/totk/runtime/services.c @@ -395,9 +395,9 @@ static void lv_log(const char *tag, void *ev){if(!oot_probe())return;unsigned ch pthread_threadid_np(NULL,&tid); fprintf(stderr,"[lv-probe] %s th=%llx ev=%llx [%02x %02x %02x %02x %02x %02x %02x %02x]\n",tag,(unsigned long long)tid,(unsigned long long)(uintptr_t)ev,p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);fflush(stderr);} static void observed_light_wait(void *ev){lv_log("W ",ev); - ((void(*)(void*))runtime_symbol("_ZN2nn2os14WaitLightEventEPNS0_14LightEventTypeE"))(ev);if(oot_probe())fprintf(stderr,"[lv-probe] W -> done\n");fflush(stderr);} + ((void(*)(void*))runtime_symbol("_ZN2nn2os14WaitLightEventEPNS0_14LightEventTypeE"))(ev);if(oot_probe()){fprintf(stderr,"[lv-probe] W -> done\n");fflush(stderr);}} static uint32_t observed_light_timedwait(void *ev,uint64_t ts){lv_log("TW",ev); - uint32_t r=((uint32_t(*)(void*,uint64_t))runtime_symbol("_ZN2nn2os19TimedWaitLightEventEPNS0_14LightEventTypeENS_8TimeSpanE"))(ev,ts);if(oot_probe())fprintf(stderr,"[lv-probe] TW -> %x\n",r);fflush(stderr);return r;} + uint32_t r=((uint32_t(*)(void*,uint64_t))runtime_symbol("_ZN2nn2os19TimedWaitLightEventEPNS0_14LightEventTypeENS_8TimeSpanE"))(ev,ts);if(oot_probe()){fprintf(stderr,"[lv-probe] TW -> %x\n",r);fflush(stderr);}return r;} static void observed_light_signal(void *ev){lv_log("S ",ev); ((void(*)(void*))runtime_symbol("_ZN2nn2os16SignalLightEventEPNS0_14LightEventTypeE"))(ev);} static void observed_light_clear(void *ev){lv_log("C ",ev); diff --git a/tests/test_light_event_observer.py b/tests/test_light_event_observer.py new file mode 100644 index 000000000..acf518106 --- /dev/null +++ b/tests/test_light_event_observer.py @@ -0,0 +1,29 @@ +"""Actual production wrappers forward calls/return values with diagnostics off or on.""" +import os,platform,subprocess,tempfile,unittest +from pathlib import Path +ROOT=Path(__file__).resolve().parents[1] +@unittest.skipUnless(platform.system()=='Darwin','Apple thread-id API') +class LightEventObserver(unittest.TestCase): + def test_logging_preserves_calls_timeout_and_result(self): + text=(ROOT/'games/totk/runtime/services.c').read_text();a=text.index('static void lv_log(');b=text.index('/* TEMP probe (OoT): the movie player',a) + prefix='''#include +#include +#include +#include +#include +static int count;static void *last;static uint64_t timeout; +static void call(void *p){count++;last=p;} +static uint32_t timed(void *p,uint64_t t){call(p);timeout=t;return 0xab123456;} +static void *runtime_symbol(const char *name){return strstr(name,"TimedWait")?(void*)timed:(void*)call;} +''' + main='''int main(void){uint64_t ev=0;observed_light_wait(&ev);uint32_t r=observed_light_timedwait(&ev,0x123456789abcdef0ull);observed_light_signal(&ev);observed_light_clear(&ev);return !(count==4&&last==&ev&&r==0xab123456&&timeout==0x123456789abcdef0ull);} +''' + with tempfile.TemporaryDirectory() as td: + probe=next(line for line in text.splitlines() if line.startswith('static int oot_probe(')) + p=Path(td);(p/'test.c').write_text(prefix+probe+'\n'+text[a:b]+main) + r=subprocess.run(['xcrun','clang','-Wall','-Wextra','-Werror',str(p/'test.c'),'-o',str(p/'probe')],capture_output=True,text=True);self.assertEqual(r.returncode,0,r.stderr) + env={k:v for k,v in os.environ.items() if k!='TOTK_WAIT_LOG'} + for on in (False,True): + with self.subTest(logging=on): + r=subprocess.run([str(p/'probe')],env=env|({'TOTK_WAIT_LOG':'1'} if on else {}),capture_output=True,text=True) + self.assertEqual(r.returncode,0,r.stderr);self.assertEqual('[lv-probe]' in r.stderr,on)