Skip to content

[libc][stdlib] initial support for __cxa_finalize #85865

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 22, 2024

Conversation

nickdesaulniers
Copy link
Member

I'm trying to break up the pieces of supporting __cxa_finalize into smaller
commits. Provide this symbol first, and make use of it from exit.

Next will be to store __dso_handle, then finally to only run callbacks that
were registered from a specific dso.

Link: #85651
Link: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor

I'm trying to break up the pieces of supporting __cxa_finalize into smaller
commits. Provide this symbol first, and make use of it from exit.

Next will be to store __dso_handle, then finally to only run callbacks that
were registered from a specific dso.

Link: llvm#85651
Link: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor
@llvmbot
Copy link
Member

llvmbot commented Mar 19, 2024

@llvm/pr-subscribers-libc

Author: Nick Desaulniers (nickdesaulniers)

Changes

I'm trying to break up the pieces of supporting __cxa_finalize into smaller
commits. Provide this symbol first, and make use of it from exit.

Next will be to store __dso_handle, then finally to only run callbacks that
were registered from a specific dso.

Link: #85651
Link: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor


Full diff: https://github.com/llvm/llvm-project/pull/85865.diff

2 Files Affected:

  • (modified) libc/src/stdlib/atexit.cpp (+19-12)
  • (modified) libc/src/stdlib/exit.cpp (+3-5)
diff --git a/libc/src/stdlib/atexit.cpp b/libc/src/stdlib/atexit.cpp
index 741ea4f25103ac..fa072b2fdf8d09 100644
--- a/libc/src/stdlib/atexit.cpp
+++ b/libc/src/stdlib/atexit.cpp
@@ -55,14 +55,10 @@ void stdc_at_exit_func(void *payload) {
   reinterpret_cast<StdCAtExitCallback *>(payload)();
 }
 
-} // namespace
-
-namespace internal {
-
 void call_exit_callbacks() {
   handler_list_mtx.lock();
   while (!exit_callbacks.empty()) {
-    auto unit = exit_callbacks.back();
+    AtExitUnit &unit = exit_callbacks.back();
     exit_callbacks.pop_back();
     handler_list_mtx.unlock();
     unit.callback(unit.payload);
@@ -71,20 +67,31 @@ void call_exit_callbacks() {
   ExitCallbackList::destroy(&exit_callbacks);
 }
 
-} // namespace internal
-
-static int add_atexit_unit(const AtExitUnit &unit) {
+int add_atexit_unit(const AtExitUnit &unit) {
   MutexLock lock(&handler_list_mtx);
-  if (!exit_callbacks.push_back(unit))
-    return -1;
-  return 0;
+  if (exit_callbacks.push_back(unit))
+    return 0;
+  return -1;
 }
 
+} // namespace
+
+extern "C" {
+
 // TODO: Handle the last dso handle argument.
-extern "C" int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
+int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
   return add_atexit_unit({callback, payload});
 }
 
+// TODO: Handle the dso handle argument. call_exit_callbacks should only invoke
+// the callbacks from this DSO. Requires adding support for __dso_handle.
+void __cxa_finalize(void *dso) {
+  if (!dso)
+    call_exit_callbacks();
+}
+
+} // extern "C"
+
 LLVM_LIBC_FUNCTION(int, atexit, (StdCAtExitCallback * callback)) {
   return add_atexit_unit(
       {&stdc_at_exit_func, reinterpret_cast<void *>(callback)});
diff --git a/libc/src/stdlib/exit.cpp b/libc/src/stdlib/exit.cpp
index cc5ae6648d11f2..e754b34e46985a 100644
--- a/libc/src/stdlib/exit.cpp
+++ b/libc/src/stdlib/exit.cpp
@@ -10,14 +10,12 @@
 #include "src/__support/OSUtil/quick_exit.h"
 #include "src/__support/common.h"
 
-namespace LIBC_NAMESPACE {
+extern "C" void __cxa_finalize(void *);
 
-namespace internal {
-void call_exit_callbacks();
-}
+namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(void, exit, (int status)) {
-  internal::call_exit_callbacks();
+  __cxa_finalize(nullptr);
   quick_exit(status);
   __builtin_unreachable();
 }

MutexLock lock(&handler_list_mtx);
if (!exit_callbacks.push_back(unit))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I slightly prefer the original version where we only execute the if body in the case of an error and continue otherwise.

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nickdesaulniers nickdesaulniers merged commit 4318f7e into llvm:main Mar 22, 2024
@nickdesaulniers nickdesaulniers deleted the __cxa_finalize4 branch March 22, 2024 15:28
chencha3 pushed a commit to chencha3/llvm-project that referenced this pull request Mar 23, 2024
I'm trying to break up the pieces of supporting __cxa_finalize into smaller
commits. Provide this symbol first, and make use of it from exit.

Next will be to store __dso_handle, then finally to only run callbacks that
were registered from a specific dso.

Link: llvm#85651
Link: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants