1 #include <stdlib.h> 2 #include <stdint.h> 3 #include <stdbool.h> 4 #include <debug.h> 5 #include <signal.h> 6 #include <atomic.h> 7 #include <pthread.h> 8 #include "syscall.h" 9 #include "libc.h" 10 #include <bits/errno.h> 11 12 extern bool g_enable_check; 13 extern void mem_check_deinit(void); 14 extern void clean_recycle_list(bool clean_all); 15 pthread_mutex_t __exit_mutex = PTHREAD_MUTEX_INITIALIZER; 16 dummy()17static void dummy() 18 { 19 } 20 21 /* atexit.c and __stdio_exit.c override these. the latter is linked 22 * as a consequence of linking either __toread.c or __towrite.c. */ 23 weak_alias(dummy, __funcs_on_exit); 24 weak_alias(dummy, __stdio_exit); 25 weak_alias(dummy, _fini); 26 27 extern weak hidden void (*const __fini_array_start)(void), (*const __fini_array_end)(void); 28 libc_exit_fini(void)29static void libc_exit_fini(void) 30 { 31 uintptr_t a = (uintptr_t)&__fini_array_end; 32 for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)())) 33 (*(void (**)())(a-sizeof(void(*)())))(); 34 _fini(); 35 } 36 37 weak_alias(libc_exit_fini, __libc_exit_fini); 38 exit(int code)39_Noreturn void exit(int code) 40 { 41 sigset_t set; 42 43 __block_app_sigs(&set); 44 45 int ret = pthread_mutex_trylock(&__exit_mutex); 46 if (ret == EBUSY) { 47 pthread_exit(NULL); 48 } 49 50 if (g_enable_check) { 51 check_leak(); 52 check_heap_integrity(); 53 mem_check_deinit(); 54 clean_recycle_list(true); 55 } 56 __funcs_on_exit(); 57 __libc_exit_fini(); 58 __stdio_exit(); 59 _Exit(code); 60 } 61