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):
11963
11963
@also_with_wasm_bigint
11964
11964
def test_parseTools (self ):
11965
11965
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):
714
714
715
715
class libnoexit (Library ):
716
716
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
717
720
src_dir = 'system/lib/libc'
718
721
src_files = ['atexit_dummy.c' ]
719
722
@@ -780,6 +783,10 @@ def get_libcall_files(self):
780
783
]
781
784
math_files = files_in_path (path = 'system/lib/libc/musl/src/math' , filenames = math_files )
782
785
786
+ exit_files = files_in_path (
787
+ path = 'system/lib/libc/musl/src/exit' ,
788
+ filenames = ['atexit.c' ])
789
+
783
790
other_files = files_in_path (
784
791
path = 'system/lib/libc' ,
785
792
filenames = ['emscripten_memcpy.c' , 'emscripten_memset.c' ,
@@ -802,7 +809,7 @@ def get_libcall_files(self):
802
809
iprintf_files += files_in_path (
803
810
path = 'system/lib/libc/musl/src/string' ,
804
811
filenames = ['strlen.c' ])
805
- return math_files + other_files + iprintf_files
812
+ return math_files + exit_files + other_files + iprintf_files
806
813
807
814
def get_files (self ):
808
815
libc_files = []
You can’t perform that action at this time.
0 commit comments