• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()17 static 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)29 static 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