exit.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* Copyright (C) 1991-2019 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <unistd.h>
  17. #include <sysdep.h>
  18. #include <libc-lock.h>
  19. #include "exit.h"
  20. #include "set-hooks.h"
  21. DEFINE_HOOK (__libc_atexit, (void))
  22. /* Initialize the flag that indicates exit function processing
  23. is complete. See concurrency notes in stdlib/exit.h where
  24. __exit_funcs_lock is declared. */
  25. bool __exit_funcs_done = false;
  26. /* Call all functions registered with `atexit' and `on_exit',
  27. in the reverse of the order in which they were registered
  28. perform stdio cleanup, and terminate program execution with STATUS. */
  29. void
  30. attribute_hidden
  31. __run_exit_handlers (int status, struct exit_function_list **listp,
  32. bool run_list_atexit, bool run_dtors)
  33. {
  34. /* First, call the TLS destructors. */
  35. #ifndef SHARED
  36. if (&__call_tls_dtors != NULL)
  37. #endif
  38. if (run_dtors)
  39. __call_tls_dtors ();
  40. /* We do it this way to handle recursive calls to exit () made by
  41. the functions registered with `atexit' and `on_exit'. We call
  42. everyone on the list and use the status value in the last
  43. exit (). */
  44. while (true)
  45. {
  46. struct exit_function_list *cur;
  47. __libc_lock_lock (__exit_funcs_lock);
  48. restart:
  49. cur = *listp;
  50. if (cur == NULL)
  51. {
  52. /* Exit processing complete. We will not allow any more
  53. atexit/on_exit registrations. */
  54. __exit_funcs_done = true;
  55. __libc_lock_unlock (__exit_funcs_lock);
  56. break;
  57. }
  58. while (cur->idx > 0)
  59. {
  60. struct exit_function *const f = &cur->fns[--cur->idx];
  61. const uint64_t new_exitfn_called = __new_exitfn_called;
  62. /* Unlock the list while we call a foreign function. */
  63. __libc_lock_unlock (__exit_funcs_lock);
  64. switch (f->flavor)
  65. {
  66. void (*atfct) (void);
  67. void (*onfct) (int status, void *arg);
  68. void (*cxafct) (void *arg, int status);
  69. case ef_free:
  70. case ef_us:
  71. break;
  72. case ef_on:
  73. onfct = f->func.on.fn;
  74. #ifdef PTR_DEMANGLE
  75. PTR_DEMANGLE (onfct);
  76. #endif
  77. onfct (status, f->func.on.arg);
  78. break;
  79. case ef_at:
  80. atfct = f->func.at;
  81. #ifdef PTR_DEMANGLE
  82. PTR_DEMANGLE (atfct);
  83. #endif
  84. atfct ();
  85. break;
  86. case ef_cxa:
  87. /* To avoid dlclose/exit race calling cxafct twice (BZ 22180),
  88. we must mark this function as ef_free. */
  89. f->flavor = ef_free;
  90. cxafct = f->func.cxa.fn;
  91. #ifdef PTR_DEMANGLE
  92. PTR_DEMANGLE (cxafct);
  93. #endif
  94. cxafct (f->func.cxa.arg, status);
  95. break;
  96. }
  97. /* Re-lock again before looking at global state. */
  98. __libc_lock_lock (__exit_funcs_lock);
  99. if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
  100. /* The last exit function, or another thread, has registered
  101. more exit functions. Start the loop over. */
  102. goto restart;
  103. }
  104. *listp = cur->next;
  105. if (*listp != NULL)
  106. /* Don't free the last element in the chain, this is the statically
  107. allocate element. */
  108. free (cur);
  109. __libc_lock_unlock (__exit_funcs_lock);
  110. }
  111. if (run_list_atexit)
  112. RUN_HOOK (__libc_atexit, ());
  113. _exit (status);
  114. }
  115. void
  116. exit (int status)
  117. {
  118. __run_exit_handlers (status, &__exit_funcs, true, true);
  119. }
  120. libc_hidden_def (exit)