The simple create/release code: #include <JavaScriptCore/JSContextRef.h> int main() { auto *global = JSGlobalContextCreate(nullptr); JSGlobalContextRelease(global); } built with clang: clang++ -std=c++14 -g test.cc -framework JavaScriptCore and run with the leaks instrumentation: leaks -atExit -- ./a.out reports a lot of leaks: Process 19039 is not debuggable. Due to security restrictions, leaks can only show or save contents of readonly memory of restricted processes. Process: a.out [19039] Path: /Users/USER/*/a.out Load Address: 0x1001b4000 Identifier: a.out Version: 0 Code Type: ARM64 Platform: macOS Parent Process: leaks [19037] Date/Time: 2022-11-09 14:29:12.962 -0700 Launch Time: 2022-11-09 14:29:12.435 -0700 OS Version: macOS 12.6 (21G115) Report Version: 7 Analysis Tool: /Applications/Xcode.app/Contents/Developer/usr/bin/leaks Analysis Tool Version: Xcode 14.0.1 (14A400) ---- leaks Report Version: 4.0 Process 19039: 1012 nodes malloced for 68 KB Process 19039: 110 leaks for 4400 total leaked bytes. 110 (4.30K) << TOTAL >> 1 (1.25K) ROOT LEAK: 0x11d820000 [1280] 1 (64 bytes) ROOT LEAK: 0x11d804960 [64] 1 (64 bytes) ROOT LEAK: 0x11d8049a0 [64] 1 (64 bytes) ROOT LEAK: 0x11d8049e0 [64] 1 (64 bytes) ROOT LEAK: 0x11d804a20 [64] 1 (32 bytes) ROOT LEAK: 0x11d804020 [32] 1 (32 bytes) ROOT LEAK: 0x11d804040 [32] 1 (32 bytes) ROOT LEAK: 0x11d804060 [32] 1 (32 bytes) ROOT LEAK: 0x11d804080 [32] 1 (32 bytes) ROOT LEAK: 0x11d8040a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8040c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8040e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804100 [32] 1 (32 bytes) ROOT LEAK: 0x11d804120 [32] 1 (32 bytes) ROOT LEAK: 0x11d804140 [32] 1 (32 bytes) ROOT LEAK: 0x11d804160 [32] 1 (32 bytes) ROOT LEAK: 0x11d804180 [32] 1 (32 bytes) ROOT LEAK: 0x11d8041a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8041c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8041e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804200 [32] 1 (32 bytes) ROOT LEAK: 0x11d804220 [32] 1 (32 bytes) ROOT LEAK: 0x11d804240 [32] 1 (32 bytes) ROOT LEAK: 0x11d804260 [32] 1 (32 bytes) ROOT LEAK: 0x11d804280 [32] 1 (32 bytes) ROOT LEAK: 0x11d8042a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8042c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8042e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804300 [32] 1 (32 bytes) ROOT LEAK: 0x11d804320 [32] 1 (32 bytes) ROOT LEAK: 0x11d804340 [32] 1 (32 bytes) ROOT LEAK: 0x11d804360 [32] 1 (32 bytes) ROOT LEAK: 0x11d804380 [32] 1 (32 bytes) ROOT LEAK: 0x11d8043a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8043c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8043e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804400 [32] 1 (32 bytes) ROOT LEAK: 0x11d804420 [32] 1 (32 bytes) ROOT LEAK: 0x11d804440 [32] 1 (32 bytes) ROOT LEAK: 0x11d804460 [32] 1 (32 bytes) ROOT LEAK: 0x11d804480 [32] 1 (32 bytes) ROOT LEAK: 0x11d8044a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8044c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8044e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804500 [32] 1 (32 bytes) ROOT LEAK: 0x11d804520 [32] 1 (32 bytes) ROOT LEAK: 0x11d804540 [32] 1 (32 bytes) ROOT LEAK: 0x11d804560 [32] 1 (32 bytes) ROOT LEAK: 0x11d804580 [32] 1 (32 bytes) ROOT LEAK: 0x11d8045a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8045c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8045e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804600 [32] 1 (32 bytes) ROOT LEAK: 0x11d804620 [32] 1 (32 bytes) ROOT LEAK: 0x11d804640 [32] 1 (32 bytes) ROOT LEAK: 0x11d804660 [32] 1 (32 bytes) ROOT LEAK: 0x11d804680 [32] 1 (32 bytes) ROOT LEAK: 0x11d8046a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8046c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8046e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804700 [32] 1 (32 bytes) ROOT LEAK: 0x11d804720 [32] 1 (32 bytes) ROOT LEAK: 0x11d804740 [32] 1 (32 bytes) ROOT LEAK: 0x11d804760 [32] 1 (32 bytes) ROOT LEAK: 0x11d804780 [32] 1 (32 bytes) ROOT LEAK: 0x11d8047a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8047c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8047e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804800 [32] 1 (32 bytes) ROOT LEAK: 0x11d804820 [32] 1 (32 bytes) ROOT LEAK: 0x11d804840 [32] 1 (32 bytes) ROOT LEAK: 0x11d804860 [32] 1 (32 bytes) ROOT LEAK: 0x11d804880 [32] 1 (32 bytes) ROOT LEAK: 0x11d8048a0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8048c0 [32] 1 (32 bytes) ROOT LEAK: 0x11d8048e0 [32] 1 (32 bytes) ROOT LEAK: 0x11d804900 [32] 1 (32 bytes) ROOT LEAK: 0x11d804920 [32] 1 (32 bytes) ROOT LEAK: 0x11d804940 [32] 1 (16 bytes) ROOT LEAK: 0x1090040c0 [16] 1 (16 bytes) ROOT LEAK: 0x109004110 [16] 1 (16 bytes) ROOT LEAK: 0x109004140 [16] 1 (16 bytes) ROOT LEAK: 0x109004170 [16] 1 (16 bytes) ROOT LEAK: 0x1090041a0 [16] 1 (16 bytes) ROOT LEAK: 0x1090041d0 [16] 1 (16 bytes) ROOT LEAK: 0x109004200 [16] 1 (16 bytes) ROOT LEAK: 0x109004230 [16] 1 (16 bytes) ROOT LEAK: 0x109004260 [16] 1 (16 bytes) ROOT LEAK: 0x109004290 [16] 1 (16 bytes) ROOT LEAK: 0x1090042c0 [16] 1 (16 bytes) ROOT LEAK: 0x1090042f0 [16] 1 (16 bytes) ROOT LEAK: 0x109004320 [16] 1 (16 bytes) ROOT LEAK: 0x109004350 [16] 1 (16 bytes) ROOT LEAK: 0x109004380 [16] 1 (16 bytes) ROOT LEAK: 0x1090043b0 [16] 1 (16 bytes) ROOT LEAK: 0x1090043e0 [16] 1 (16 bytes) ROOT LEAK: 0x109004410 [16] 1 (16 bytes) ROOT LEAK: 0x109004440 [16] 1 (16 bytes) ROOT LEAK: 0x109004470 [16] 1 (16 bytes) ROOT LEAK: 0x1090044a0 [16] 1 (16 bytes) ROOT LEAK: 0x1090044d0 [16] 1 (16 bytes) ROOT LEAK: 0x109004500 [16] 1 (16 bytes) ROOT LEAK: 0x109004510 [16] 1 (16 bytes) ROOT LEAK: 0x109004520 [16] 1 (16 bytes) ROOT LEAK: 0x109004530 [16] 1 (16 bytes) ROOT LEAK: 0x109004540 [16] 1 (16 bytes) ROOT LEAK: 0x1090045b0 [16] 1 (16 bytes) ROOT LEAK: 0x1090045d0 [16] 1 (16 bytes) ROOT LEAK: <WTF::Detail::CallableWrapper<JSC::VMTraps::SignalSender::initializeSignals()::'lambda'()::operator()() const::'lambda'(WTF::Signal, WTF::SigInfo&, __darwin_arm_thread_state64&), WTF::SignalAction, WTF::Signal, WTF::SigInfo&, __darwin_arm_thread_state64&> 0x1090045f0> [16] 1 (16 bytes) ROOT LEAK: <WTF::Detail::CallableWrapper<JSC::Wasm::prepareFastMemory()::$_1::operator()() const::'lambda'(WTF::Signal, WTF::SigInfo&, __darwin_arm_thread_state64&), WTF::SignalAction, WTF::Signal, WTF::SigInfo&, __darwin_arm_thread_state64&> 0x109004600> [16] Is it a bug? If it is not, how to properly finalize JavaScriptCore global context?
This is likely not an actual issue. CC'ing some experts for an authoritative answer though. - This app doesn't give garbage collection any time to run. - JSC uses decorated pointers which leaks doesn't understand.
If I call JSGarbageCollect(), it does not change output: #include <JavaScriptCore/JSContextRef.h> int main() { auto *global = JSGlobalContextCreate(nullptr); JSGarbageCollect(global); JSGlobalContextRelease(global); } I would like to know a proper JavaScriptCore shutdown.
Thanks for reporting. This is not a real issue, the problem is that leaks tool cannot trace compact pointers. So they are false positive.