File tree Expand file tree Collapse file tree 3 files changed +39
-1
lines changed Expand file tree Collapse file tree 3 files changed +39
-1
lines changed Original file line number Diff line number Diff line change 1+ #include <stdio.h>
2+
3+ // In Wasm destructors get lowered to constructors that call `__cxa_atexit`.
4+ //
5+ // Because this lowering happens during compilation this symbol cannot itself be
6+ // compiled as LTO (since generated new references to LTO symbols at LTO time
7+ // results int link failure). We had a bug where this symbol was itself LTO
8+ // which can cause link failures.
9+ //
10+ // See: https://github.com/emscripten-core/emscripten/issues/16836
11+ void my_dtor () __attribute__((destructor ));
12+
13+ void my_dtor () {
14+ printf ("my_dtor\n" );
15+ }
16+
17+ int main () {
18+ printf ("main done\n" );
19+ return 0 ;
20+ }
Original file line number Diff line number Diff line change @@ -11963,3 +11963,14 @@ def test_no_cfi(self):
1196311963 @also_with_wasm_bigint
1196411964 def test_parseTools (self ):
1196511965 self .do_other_test ('test_parseTools.c' , emcc_args = ['--js-library' , test_file ('other/test_parseTools.js' )])
11966+
11967+ def test_lto_atexit (self ):
11968+ self .emcc_args .append ('-flto' )
11969+
11970+ # Without EXIT_RUNTIME we don't expect the dtor to run at all
11971+ output = self .do_runf (test_file ('other/test_lto_atexit.c' ), 'main done' )
11972+ self .assertNotContained ('my_dtor' , output )
11973+
11974+ # With EXIT_RUNTIME we expect to see the dtor running.
11975+ self .set_setting ('EXIT_RUNTIME' )
11976+ self .do_runf (test_file ('other/test_lto_atexit.c' ), 'main done\n my_dtor\n ' )
Original file line number Diff line number Diff line change @@ -714,6 +714,9 @@ class libcompiler_rt(MTLibrary, SjLjLibrary):
714714
715715class libnoexit (Library ):
716716 name = 'libnoexit'
717+ # __cxa_atexit calls can be generated during LTO the implemenation cannot
718+ # itself be LTO. See `get_libcall_files` below for more details.
719+ force_object_files = True
717720 src_dir = 'system/lib/libc'
718721 src_files = ['atexit_dummy.c' ]
719722
@@ -780,6 +783,10 @@ def get_libcall_files(self):
780783 ]
781784 math_files = files_in_path (path = 'system/lib/libc/musl/src/math' , filenames = math_files )
782785
786+ exit_files = files_in_path (
787+ path = 'system/lib/libc/musl/src/exit' ,
788+ filenames = ['atexit.c' ])
789+
783790 other_files = files_in_path (
784791 path = 'system/lib/libc' ,
785792 filenames = ['emscripten_memcpy.c' , 'emscripten_memset.c' ,
@@ -802,7 +809,7 @@ def get_libcall_files(self):
802809 iprintf_files += files_in_path (
803810 path = 'system/lib/libc/musl/src/string' ,
804811 filenames = ['strlen.c' ])
805- return math_files + other_files + iprintf_files
812+ return math_files + exit_files + other_files + iprintf_files
806813
807814 def get_files (self ):
808815 libc_files = []
You can’t perform that action at this time.
0 commit comments