diff --git a/compiler/src/main/pascal/runtime.arc.pas b/compiler/src/main/pascal/runtime.arc.pas index 141cb67..ec07ae9 100644 --- a/compiler/src/main/pascal/runtime.arc.pas +++ b/compiler/src/main/pascal/runtime.arc.pas @@ -60,7 +60,15 @@ procedure _AbstractMethodError; procedure _LeakTrackerEnable; procedure _LeakTrackerRegister(UserPtr: Pointer; ClassName: Pointer; UnitName: Pointer; Line: Int64); -procedure _libc_atexit(Fn: Pointer); external name 'atexit'; +{ Register an at-exit handler. Uses __cxa_atexit, NOT atexit: glibc's bare + `atexit` lives only in the static libc_nonshared.a (it is not a dynamic export + of libc.so.6), so a link that does not pull that archive — as the native + backend's internal and external linkers do not — leaves `atexit` unresolved at + load time. __cxa_atexit is a genuine dynamic libc export and resolves on + every link path. Its third argument is the DSO handle; nil registers the + handler against the main program. The handler is passed one (ignored) arg. } +function _libc_cxa_atexit(Fn, Arg, DsoHandle: Pointer): Integer; + external name '__cxa_atexit'; implementation @@ -366,7 +374,7 @@ begin GLTTable := PChar(_BlaiseGetMem(TableSize)); if GLTTable = nil then begin GLTEnabled := False; Exit end; _libc_memset(GLTTable, 0, Int64(TableSize)); - _libc_atexit(Pointer(@_LeakTrackerReport)); + _libc_cxa_atexit(Pointer(@_LeakTrackerReport), nil, nil); end; { ------------------------------------------------------------------ }