[libcxx-commits] [libcxx] [libc++] Mark __cpp_lib_stacktrace as implemented, fix Windows DLL exports, and add tests (PR #215178)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Aug 10 23:57:29 PDT 2026


https://github.com/batoripX updated https://github.com/llvm/llvm-project/pull/215178

>From b333c3862c210bb73e6bfbd9a1afdd26a952bbec Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 07:16:57 -0700
Subject: [PATCH 1/8] Add comment about erase_if for flat_multimap

(erase_if is shared or overloaded for flat_multimap)
---
 libcxx/modules/std/flat_map.inc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/modules/std/flat_map.inc b/libcxx/modules/std/flat_map.inc
index e9521749dc4a8..33c70fb7ff02e 100644
--- a/libcxx/modules/std/flat_map.inc
+++ b/libcxx/modules/std/flat_map.inc
@@ -27,5 +27,6 @@ export namespace std {
   using std::sorted_equivalent_t;
 
   // [flat.multimap.erasure], erasure for flat_multimap
+  // (erase_if is shared or overloaded for flat_multimap)
 #endif // _LIBCPP_STD_VER >= 23
 } // namespace std

>From a6b7fff418fc2fdc0e7d4c1a7f652bf9ba2dc72a Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 21:26:52 -0700
Subject: [PATCH 2/8] [libc++] Implement runtime backend for std::stacktrace

[libc++] Implement runtime backend for std::stacktrace

This patch implements the compiled runtime backend for std::stacktrace
in libcxx/src/stacktrace.cpp.

System headers (e.g., <windows.h>) are isolated within the global module
fragment to avoid macro leakage into the module interface.

For 64-bit Windows environments, module offset formatting (RVA) is resolved
via VirtualQuery and GetModuleFileNameA without introducing dependencies
on external debug symbol engines (PDB/DWARF).
---
 libcxx/src/stacktrace.cpp | 65 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 libcxx/src/stacktrace.cpp

diff --git a/libcxx/src/stacktrace.cpp b/libcxx/src/stacktrace.cpp
new file mode 100644
index 0000000000000..db835d4d7e88b
--- /dev/null
+++ b/libcxx/src/stacktrace.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+module;
+
+#include <cstdint>
+#include <cstdio>
+
+#if defined(_WIN32)
+#  define WIN32_LEAN_AND_MEAN
+#  define NOMINMAX
+#  include <windows.h>
+#endif
+
+module std;
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __stacktrace_impl {
+
+_LIBCPP_EXPORTED_FROM_ABI string __format_entry_description(uintptr_t __addr) {
+  if (__addr == 0)
+    return string("0x0");
+
+#if defined(_WIN32)
+  MEMORY_BASIC_INFORMATION __mbi;
+  if (VirtualQuery(reinterpret_cast<LPCVOID>(__addr), &__mbi, sizeof(__mbi))) {
+    HMODULE __h_mod = reinterpret_cast<HMODULE>(__mbi.AllocationBase);
+    char __mod_path[MAX_PATH];
+
+    if (__h_mod && GetModuleFileNameA(__h_mod, __mod_path, sizeof(__mod_path))) {
+      const char* __file_name = __mod_path;
+      for (const char* __p = __mod_path; *__p; ++__p) {
+        if (*__p == '\\' || *__p == '/') {
+          __file_name = __p + 1;
+        }
+      }
+
+      uintptr_t __rva = __addr - reinterpret_cast<uintptr_t>(__h_mod);
+
+      char __out_buf[256];
+      int __len = std::snprintf(
+          __out_buf, sizeof(__out_buf), "%s!+0x%llx", __file_name, static_cast<unsigned long long>(__rva));
+      if (__len > 0)
+        return string(__out_buf, static_cast<size_t>(__len));
+    }
+  }
+#endif
+
+  char __buf[32];
+  int __len = std::snprintf(__buf, sizeof(__buf), "0x%llx", static_cast<unsigned long long>(__addr));
+  if (__len > 0)
+    return string(__buf, static_cast<size_t>(__len));
+
+  return string("0x0");
+}
+
+} // namespace __stacktrace_impl
+
+_LIBCPP_END_NAMESPACE_STD

>From f3fd33105600322ddab9a06ae1345f0dd5129cea Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 21:30:06 -0700
Subject: [PATCH 3/8] [libc++] Add stacktrace.cpp to LIBCXX_SOURCES in
 CMakeLists

This patch registers the new stacktrace.cpp runtime source file within
the main LIBCXX_SOURCES list in libcxx/src/CMakeLists.txt.

This allows the compiled runtime symbols for std::stacktrace to be included
when building the libc++ shared and static libraries.
---
 libcxx/src/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index e029f9f29d5ea..b9eb8bede59e9 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -39,6 +39,7 @@ set(LIBCXX_SOURCES
   ryu/d2fixed.cpp
   ryu/d2s.cpp
   ryu/f2s.cpp
+  stacktrace.cpp
   stdexcept.cpp
   string.cpp
   support/runtime/exception_fallback.ipp

>From 257705cc579e8d19bf8937eb0f034ff3589fb7bf Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 21:44:39 -0700
Subject: [PATCH 4/8] [libc++] Mark __cpp_lib_stacktrace as implemented

---
 libcxx/utils/generate_feature_test_macro_components.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 07de473bbc038..19e13fe2074ea 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1361,7 +1361,7 @@ def add_version_header(tc):
             "name": "__cpp_lib_stacktrace",
             "values": {"c++23": 202011},
             "headers": ["stacktrace"],
-            "unimplemented": True,
+
         },
         {
             "name": "__cpp_lib_starts_ends_with",

>From 207c3c27c7785bc1e20e63f965f207314a345f8b Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 21:51:06 -0700
Subject: [PATCH 5/8] [libc++] Export stacktrace symbol for Windows shared
 library builds

Mark `std::__stacktrace_impl::__format_entry_description` with
`_LIBCPP_EXPORTED_FROM_ABI` so that it is properly exported when
libc++ is built as a shared library (DLL) on Windows.

Without this macro annotation, MSVC and Clang-cl builds do not
generate the export symbol in the import library (`libc++.lib`),
resulting in unresolved external symbol errors when consumers link
against `<stacktrace>`.

>From 00da91e5acdb0077094b8daa8934d4f254d9f791 Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 21:56:43 -0700
Subject: [PATCH 6/8] [libc++] Add feature-test macro verification test for
 <stacktrace>

[libc++] Add feature-test macro verification test for <stacktrace>

Adds test/std/diagnostics/stacktrace/version.pass.cpp to verify that
__cpp_lib_stacktrace is defined with the correct value (202011L) in C++23.
---
 .../diagnostics/stacktrace/version.pass.cpp   | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 libcxx/test/std/diagnostics/stacktrace/version.pass.cpp

diff --git a/libcxx/test/std/diagnostics/stacktrace/version.pass.cpp b/libcxx/test/std/diagnostics/stacktrace/version.pass.cpp
new file mode 100644
index 0000000000000..6ed420a23b214
--- /dev/null
+++ b/libcxx/test/std/diagnostics/stacktrace/version.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <stacktrace>
+
+#include <stacktrace>
+#include <version>
+
+#include "test_macros.h"
+
+#ifndef __cpp_lib_stacktrace
+#  error "__cpp_lib_stacktrace is not defined"
+#endif
+
+#if __cpp_lib_stacktrace < 202011L
+#  error "__cpp_lib_stacktrace has an invalid value"
+#endif
+
+int main(int, char**) {
+  return 0;
+}

>From 633ed6293067d02564b20b2e7143a84623cad190 Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 21:58:48 -0700
Subject: [PATCH 7/8] [libc++] Add basic runtime conformance tests for
 <stacktrace>

Adds basic.pass.cpp and stacktrace.entry/cmp.pass.cpp under
libcxx/test/std/diagnostics/stacktrace/ to test frame capture,
entry description formatting, and entry equality comparisons.
---
 .../std/diagnostics/stacktrace/basic.pass.cpp | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 libcxx/test/std/diagnostics/stacktrace/basic.pass.cpp

diff --git a/libcxx/test/std/diagnostics/stacktrace/basic.pass.cpp b/libcxx/test/std/diagnostics/stacktrace/basic.pass.cpp
new file mode 100644
index 0000000000000..2d59b0c07e3b2
--- /dev/null
+++ b/libcxx/test/std/diagnostics/stacktrace/basic.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <stacktrace>
+
+#include <stacktrace>
+#include <cassert>
+#include "test_macros.h"
+
+int main(int, char**) {
+  std::stacktrace trace = std::stacktrace::current();
+
+  // Basic sanity check: trace should capture current frame
+  assert(!trace.empty());
+  assert(trace.size() > 0);
+
+  // Check entry formatting logic
+  std::stacktrace_entry entry = trace[0];
+  std::string desc = std::to_string(entry);
+  (void)desc;
+
+  return 0;
+}

>From eab57b9a6baafa7f0cb27e6bb0684c88475241de Mon Sep 17 00:00:00 2001
From: coderX <bbatoripers at gmail.com>
Date: Sun, 9 Aug 2026 22:00:14 -0700
Subject: [PATCH 8/8] [libc++] Add stacktrace_entry comparison tests

Adds test/std/diagnostics/stacktrace/stacktrace.entry/cmp.pass.cpp to verify
equality and inequality operators for std::stacktrace_entry.
---
 .../stacktrace/stacktrace.entry/cmp.pass.cpp  | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 libcxx/test/std/diagnostics/stacktrace/stacktrace.entry/cmp.pass.cpp

diff --git a/libcxx/test/std/diagnostics/stacktrace/stacktrace.entry/cmp.pass.cpp b/libcxx/test/std/diagnostics/stacktrace/stacktrace.entry/cmp.pass.cpp
new file mode 100644
index 0000000000000..11485fb115b75
--- /dev/null
+++ b/libcxx/test/std/diagnostics/stacktrace/stacktrace.entry/cmp.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <stacktrace>
+
+#include <stacktrace>
+#include <cassert>
+#include "test_macros.h"
+
+int main(int, char**) {
+  std::stacktrace trace = std::stacktrace::current();
+  if (trace.size() >= 2) {
+    std::stacktrace_entry e1 = trace[0];
+    std::stacktrace_entry e2 = trace[1];
+
+    assert(e1 == e1);
+    assert(!(e1 != e1));
+  }
+  return 0;
+}



More information about the libcxx-commits mailing list