@@ -13,39 +13,16 @@ use std::path::PathBuf;
1313use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
1414use tracing_subscriber:: { layer:: SubscriberExt , util:: SubscriberInitExt } ;
1515
16- // glibc 2.31 compat: __libc_single_threaded was added in glibc 2.32 but ONNX
17- // Runtime references it, so a build for SLES 15 SP4 and similar needs a
18- // definition to link against.
19- //
20- // The storage must be WRITABLE. This was previously `pub static ... : u8 = 0`,
21- // which lands in .rodata, and the comment claimed "on newer glibc the real
22- // symbol shadows this at runtime" - the opposite of how ELF resolves it. A
23- // definition in the executable takes precedence over the one in libc, and on
24- // aarch64 this symbol is also emitted into .dynsym, so glibc bound its own
25- // startup write of the flag to our read-only byte and took SIGSEGV before
26- // main(): every invocation died, including `--version` and `--help`
27- // (issue #15). x86_64 escaped only because the symbol is not dynamically
28- // exported there, so glibc kept using its own copy.
29- //
30- // glibc owns the value: it sets the flag at startup and clears it when a
31- // thread is created. We only supply the storage, and never read it. On a glibc
32- // too old to maintain it, the byte stays 0, which is the conservative
33- // "not single threaded" answer.
16+ // glibc 2.31 compat: ONNX Runtime references `__libc_single_threaded`, which
17+ // glibc only defines from 2.32 on, so a build for SLES 15 SP4 and similar
18+ // needs a definition to link against. The storage has to be writable - glibc
19+ // writes the flag at startup - which is what `SingleThreaded` provides; see
20+ // `codegraph_server::glibc_compat` for the full story (issue #15).
3421#[ cfg( target_os = "linux" ) ]
35- mod glibc_compat {
36- use std:: cell:: UnsafeCell ;
37-
38- #[ repr( transparent) ]
39- pub struct SingleThreaded ( UnsafeCell < u8 > ) ;
40-
41- // SAFETY: glibc is the only writer, from its own startup and
42- // thread-creation paths, and this process never reads the byte. The
43- // UnsafeCell is what places it in writable memory rather than .rodata.
44- unsafe impl Sync for SingleThreaded { }
45-
46- #[ no_mangle]
47- pub static __libc_single_threaded: SingleThreaded = SingleThreaded ( UnsafeCell :: new ( 0 ) ) ;
48- }
22+ #[ no_mangle]
23+ #[ allow( non_upper_case_globals) ]
24+ pub static __libc_single_threaded: codegraph_server:: glibc_compat:: SingleThreaded =
25+ codegraph_server:: glibc_compat:: SingleThreaded :: ZERO ;
4926
5027#[ derive( Parser ) ]
5128#[ command( name = "codegraph-server" ) ]
0 commit comments