fix(runtime): --debug leak tracker crashed with "undefined symbol: atexit" on the native backend
The leak tracker registered its end-of-run report via glibc's bare `atexit`. That symbol lives only in the static libc_nonshared.a; it is NOT a dynamic export of libc.so.6. The QBE/cc path linked fine because gcc auto-pulls libc_nonshared.a, but the native backend's linkers (internal ELF linker and the native external-assembler cc invocation) do not, so a --debug build aborted at load time with `symbol lookup error: undefined symbol: atexit`. Register via __cxa_atexit instead — a genuine dynamic libc export that resolves on every link path. Its third argument is the DSO handle; nil registers the handler against the main program. The handler takes one (ignored) argument. Pre-existing bug (reproduces on v0.12.0); affects only --debug builds compiled with --backend native. Verified on all three link paths (QBE/cc, native internal linker, native external assembler) plus the full suite and all four fixpoints.
This commit is contained in:
parent
6fa4c62e80
commit
7d8a4c7ad9
|
|
@ -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;
|
||||
|
||||
{ ------------------------------------------------------------------ }
|
||||
|
|
|
|||
Loading…
Reference in a new issue