Skip to content

Commit fb633f9

Browse files
Add C++23 stacktrace
1 parent a35b290 commit fb633f9

File tree

94 files changed

+5537
-44
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+5537
-44
lines changed

libcxx/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS
131131
the shared library they shipped should turn this on and see `include/__configuration/availability.h`
132132
for more details." OFF)
133133

134+
option(LIBCXX_STACKTRACE_ALLOW_TOOLS_AT_RUNTIME
135+
"For C++23 <stacktrace>: whether to allow invocation of `addr2line`, `llvm-addr2line`, or `atos`
136+
at runtime (if it's available in `PATH`) to resolve call-chain addresses in the stacktrace
137+
into source locations, if other methods are not available." ON)
138+
134139
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
135140
set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in")
136141
elseif(MINGW)
@@ -750,6 +755,7 @@ config_define(${LIBCXX_ENABLE_UNICODE} _LIBCPP_HAS_UNICODE)
750755
config_define(${LIBCXX_ENABLE_WIDE_CHARACTERS} _LIBCPP_HAS_WIDE_CHARACTERS)
751756
config_define(${LIBCXX_ENABLE_TIME_ZONE_DATABASE} _LIBCPP_HAS_TIME_ZONE_DATABASE)
752757
config_define(${LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS} _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS)
758+
config_define(${LIBCXX_STACKTRACE_ALLOW_TOOLS_AT_RUNTIME} _LIBCPP_STACKTRACE_ALLOW_TOOLS_AT_RUNTIME)
753759

754760
# TODO: Remove in LLVM 21. We're leaving an error to make this fail explicitly.
755761
if (LIBCXX_ENABLE_ASSERTIONS)

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ Status
396396
---------------------------------------------------------- -----------------
397397
``__cpp_lib_spanstream`` *unimplemented*
398398
---------------------------------------------------------- -----------------
399-
``__cpp_lib_stacktrace`` *unimplemented*
399+
``__cpp_lib_stacktrace`` ``202011L``
400400
---------------------------------------------------------- -----------------
401401
``__cpp_lib_stdatomic_h`` ``202011L``
402402
---------------------------------------------------------- -----------------

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Implemented Papers
5353
- P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github <https://github.com/llvm/llvm-project/issues/105252>`__)
5454
- P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github <https://github.com/llvm/llvm-project/issues/105250>`__)
5555
- P2655R3: ``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type (`Github <https://github.com/llvm/llvm-project/issues/105260>`__)
56+
- P0881R7: A Proposal to add stacktrace library (`Github <https://github.com/llvm/llvm-project/issues/105131>`__)
57+
- P2301R1: Add a `pmr` alias for `std::stacktrace` (`Github <https://github.com/llvm/llvm-project/issues/105167>`__)
5658

5759
Improvements and New Features
5860
-----------------------------

libcxx/docs/Status/Cxx23Issues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@
189189
"`LWG3028 <https://wg21.link/LWG3028>`__","Container requirements tables should distinguish ``const`` and non-``const`` variables","2022-11 (Kona)","","",""
190190
"`LWG3118 <https://wg21.link/LWG3118>`__","``fpos`` equality comparison unspecified","2022-11 (Kona)","","",""
191191
"`LWG3177 <https://wg21.link/LWG3177>`__","Limit permission to specialize variable templates to program-defined types","2022-11 (Kona)","|Nothing To Do|","",""
192-
"`LWG3515 <https://wg21.link/LWG3515>`__","§[stacktrace.basic.nonmem]: ``operator<<`` should be less templatized","2022-11 (Kona)","","",""
192+
"`LWG3515 <https://wg21.link/LWG3515>`__","§[stacktrace.basic.nonmem]: ``operator<<`` should be less templatized","2022-11 (Kona)","|Nothing To Do|","",""
193193
"`LWG3545 <https://wg21.link/LWG3545>`__","``std::pointer_traits`` should be SFINAE-friendly","2022-11 (Kona)","|Complete|","18",""
194194
"`LWG3569 <https://wg21.link/LWG3569>`__","``join_view`` fails to support ranges of ranges with non-default_initializable iterators","2022-11 (Kona)","","",""
195195
"`LWG3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor","2022-11 (Kona)","|Complete|","19",""

libcxx/docs/Status/Cxx23Papers.csv

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"Paper #","Paper Name","Meeting","Status","First released version","Notes"
2-
"`P0881R7 <https://wg21.link/P0881R7>`__","A Proposal to add stacktrace library","2020-11 (Virtual)","","",""
2+
"`P0881R7 <https://wg21.link/P0881R7>`__","A Proposal to add stacktrace library","2020-11 (Virtual)","|Complete|","21",""
33
"`P0943R6 <https://wg21.link/P0943R6>`__","Support C atomics in C++","2020-11 (Virtual)","|Complete|","15",""
44
"`P1048R1 <https://wg21.link/P1048R1>`__","A proposal for a type trait to detect scoped enumerations","2020-11 (Virtual)","|Complete|","12",""
55
"`P1679R3 <https://wg21.link/P1679R3>`__","string contains function","2020-11 (Virtual)","|Complete|","12",""
@@ -32,7 +32,7 @@
3232
"`P1675R2 <https://wg21.link/P1675R2>`__","``rethrow_exception`` must be allowed to copy","2021-10 (Virtual)","|Nothing To Do|","",""
3333
"`P2077R3 <https://wg21.link/P2077R3>`__","Heterogeneous erasure overloads for associative containers","2021-10 (Virtual)","","",""
3434
"`P2251R1 <https://wg21.link/P2251R1>`__","Require ``span`` & ``basic_string_view`` to be Trivially Copyable","2021-10 (Virtual)","|Complete|","14",""
35-
"`P2301R1 <https://wg21.link/P2301R1>`__","Add a ``pmr`` alias for ``std::stacktrace``","2021-10 (Virtual)","","",""
35+
"`P2301R1 <https://wg21.link/P2301R1>`__","Add a ``pmr`` alias for ``std::stacktrace``","2021-10 (Virtual)","|Complete|","21",""
3636
"`P2321R2 <https://wg21.link/P2321R2>`__","``zip``","2021-10 (Virtual)","|In Progress|","",""
3737
"`P2340R1 <https://wg21.link/P2340R1>`__","Clarifying the status of the 'C headers'","2021-10 (Virtual)","|Nothing To Do|","",""
3838
"`P2393R1 <https://wg21.link/P2393R1>`__","Cleaning up ``integer``-class types","2021-10 (Virtual)","","",""
@@ -110,7 +110,7 @@
110110
"`P2713R1 <https://wg21.link/P2713R1>`__","Escaping improvements in ``std::format``","2023-02 (Issaquah)","|Complete|","19",""
111111
"`P2675R1 <https://wg21.link/P2675R1>`__","``format``'s width estimation is too approximate and not forward compatible","2023-02 (Issaquah)","|Complete|","17",""
112112
"`P2572R1 <https://wg21.link/P2572R1>`__","``std::format`` fill character allowances","2023-02 (Issaquah)","|Complete|","17",""
113-
"`P2693R1 <https://wg21.link/P2693R1>`__","Formatting ``thread::id`` and ``stacktrace``","2023-02 (Issaquah)","|Partial|","","The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is not implemented yet"
113+
"`P2693R1 <https://wg21.link/P2693R1>`__","Formatting ``thread::id`` and ``stacktrace``","2023-02 (Issaquah)","|Partial|","","The formatter for ``stacktrace`` is not implemented yet"
114114
"`P2679R2 <https://wg21.link/P2679R2>`__","Fixing ``std::start_lifetime_as`` for arrays","2023-02 (Issaquah)","","",""
115115
"`P2674R1 <https://wg21.link/P2674R1>`__","A trait for implicit lifetime types","2023-02 (Issaquah)","|Complete|","20",""
116116
"`P2655R3 <https://wg21.link/P2655R3>`__","``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","2023-02 (Issaquah)","|Complete|","21","The paper is implemented as a DR to C++20"

libcxx/docs/VendorDocumentation.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ General purpose options
185185
ship the IANA time zone database. When time zones are not supported,
186186
time zone support in <chrono> will be disabled.
187187

188+
.. option:: LIBCXX_STACKTRACE_ALLOW_TOOLS_AT_RUNTIME:BOOL
189+
190+
**Default**: ``ON``
191+
192+
For C++23 <stacktrace>: whether to allow invocation of ``addr2line``, ``llvm-addr2line``, or ``atos``
193+
at runtime (if it's available in ``PATH``) to resolve call-chain addresses in the stacktrace
194+
into source locations, if other methods are not available.
195+
188196
.. option:: LIBCXX_INSTALL_LIBRARY_DIR:PATH
189197

190198
**Default**: ``lib${LIBCXX_LIBDIR_SUFFIX}``

libcxx/include/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,12 @@ set(files
739739
__ranges/views.h
740740
__ranges/zip_view.h
741741
__split_buffer
742+
__stacktrace/base.h
743+
__stacktrace/basic.h
744+
__stacktrace/entry.h
745+
__stacktrace/hash.h
746+
__stacktrace/nonmem.h
747+
__stacktrace/to_string.h
742748
__std_mbstate_t.h
743749
__stop_token/atomic_unique_lock.h
744750
__stop_token/intrusive_list_view.h
@@ -1058,6 +1064,7 @@ set(files
10581064
span
10591065
sstream
10601066
stack
1067+
stacktrace
10611068
stdatomic.h
10621069
stdbool.h
10631070
stddef.h

libcxx/include/__config

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,33 @@ typedef __char32_t char32_t;
924924
# define _LIBCPP_NOINLINE
925925
# endif
926926

927+
// Some functions, e.g. std::stacktrace::current, need to avoid being
928+
// tail-called by (and tail-calling other) functions, for proper enumeration of
929+
// call-stack frames.
930+
// clang-format off
931+
932+
// Disables tail-call optimization for "outbound" calls
933+
// performed in the function annotated with this attribute.
934+
# if __has_cpp_attribute(_Clang::__disable_tail_calls__)
935+
# define _LIBCPP_NO_TAIL_CALLS_OUT [[_Clang::__disable_tail_calls__]]
936+
# elif __has_cpp_attribute(__gnu__::__optimize__)
937+
# define _LIBCPP_NO_TAIL_CALLS_OUT [[__gnu__::__optimize__("no-optimize-sibling-calls")]]
938+
# else
939+
# define _LIBCPP_NO_TAIL_CALLS_OUT
940+
# endif
941+
942+
// Disables tail-call optimization for "inbound" calls -- that is,
943+
// calls from some other function calling the one having this attribute.
944+
# if __has_cpp_attribute(_Clang::__not_tail_called__)
945+
# define _LIBCPP_NO_TAIL_CALLS_IN [[_Clang::__not_tail_called__]]
946+
# else
947+
# define _LIBCPP_NO_TAIL_CALLS_IN
948+
# endif
949+
950+
// Disable TCO for calls into, and out from, the annotated function.
951+
# define _LIBCPP_NO_TAIL_CALLS _LIBCPP_NO_TAIL_CALLS_IN _LIBCPP_NO_TAIL_CALLS_OUT
952+
// clang-format on
953+
927954
// We often repeat things just for handling wide characters in the library.
928955
// When wide characters are disabled, it can be useful to have a quick way of
929956
// disabling it without having to resort to #if-#endif, which has a larger

libcxx/include/__config_site.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#cmakedefine _LIBCPP_HAS_NO_STD_MODULES
3434
#cmakedefine01 _LIBCPP_HAS_TIME_ZONE_DATABASE
3535
#cmakedefine01 _LIBCPP_INSTRUMENTED_WITH_ASAN
36+
#cmakedefine01 _LIBCPP_STACKTRACE_ALLOW_TOOLS_AT_RUNTIME
3637

3738
// PSTL backends
3839
#cmakedefine _LIBCPP_PSTL_BACKEND_SERIAL

libcxx/include/__stacktrace/base.h

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP_STACKTRACE_BUILDER
11+
#define _LIBCPP_STACKTRACE_BUILDER
12+
13+
#include <__config>
14+
#include <__cstddef/byte.h>
15+
#include <__cstddef/size_t.h>
16+
#include <__functional/function.h>
17+
#include <__fwd/format.h>
18+
#include <__fwd/ostream.h>
19+
#include <__memory/allocator.h>
20+
#include <__memory/allocator_traits.h>
21+
#include <__new/allocate.h>
22+
#include <__vector/vector.h>
23+
#include <cstddef>
24+
#include <cstdint>
25+
#include <list>
26+
#include <optional>
27+
#include <string>
28+
29+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30+
# pragma GCC system_header
31+
#endif
32+
33+
_LIBCPP_PUSH_MACROS
34+
#include <__undef_macros>
35+
36+
_LIBCPP_BEGIN_NAMESPACE_STD
37+
38+
class _LIBCPP_EXPORTED_FROM_ABI stacktrace_entry;
39+
40+
namespace __stacktrace {
41+
42+
struct _LIBCPP_HIDE_FROM_ABI alloc final {
43+
function<byte*(size_t)> __alloc_bytes_;
44+
function<void(byte*, size_t)> __dealloc_bytes_;
45+
46+
template <class _Allocator>
47+
_LIBCPP_HIDE_FROM_ABI alloc(_Allocator __alloc) {
48+
using _AT = allocator_traits<_Allocator>;
49+
using _BA = typename _AT::template rebind_alloc<byte>;
50+
auto __ba = _BA(__alloc);
51+
__alloc_bytes_ = [__ba](size_t __sz) mutable { return __ba.allocate(__sz); };
52+
__dealloc_bytes_ = [__ba](void* __ptr, size_t __sz) mutable { __ba.deallocate((byte*)__ptr, __sz); };
53+
}
54+
55+
template <typename _Tp>
56+
struct _LIBCPP_HIDE_FROM_ABI Alloc {
57+
function<byte*(size_t)> __alloc_bytes_;
58+
function<void(byte*, size_t)> __dealloc_bytes_;
59+
60+
Alloc(function<byte*(size_t)> __alloc_bytes, function<void(byte*, size_t)> __dealloc_bytes)
61+
: __alloc_bytes_(__alloc_bytes), __dealloc_bytes_(__dealloc_bytes) {}
62+
63+
template <typename _T2 = _Tp>
64+
Alloc(Alloc<_T2> const& __rhs) : Alloc(__rhs.__alloc_bytes_, __rhs.__dealloc_bytes_) {}
65+
66+
using value_type = _Tp;
67+
[[nodiscard]] _Tp* allocate(size_t __sz) { return (_Tp*)__alloc_bytes_(__sz * sizeof(_Tp)); }
68+
void deallocate(_Tp* __ptr, size_t __sz) { __dealloc_bytes_((byte*)__ptr, __sz * sizeof(_Tp)); }
69+
70+
template <typename _A2>
71+
bool operator==(_A2 const& __rhs) const {
72+
return &__rhs == this;
73+
}
74+
};
75+
76+
template <typename _Tp>
77+
Alloc<_Tp> _LIBCPP_HIDE_FROM_ABI make_alloc() {
78+
return {__alloc_bytes_, __dealloc_bytes_};
79+
}
80+
81+
using str = basic_string<char, char_traits<char>, Alloc<char>>;
82+
83+
template <typename... _Args>
84+
str _LIBCPP_HIDE_FROM_ABI make_str(_Args... __args) {
85+
return str(std::forward<_Args>(__args)..., make_alloc<char>());
86+
}
87+
88+
template <typename _Tp>
89+
using vec = vector<_Tp, Alloc<_Tp>>;
90+
91+
template <typename _Tp, typename... _Args>
92+
_LIBCPP_HIDE_FROM_ABI vec<_Tp> make_vec(_Args... __args) {
93+
return vec(std::forward<_Args>(__args)..., make_alloc<_Tp>());
94+
}
95+
96+
template <typename _Tp>
97+
using list = ::std::list<_Tp, Alloc<_Tp>>;
98+
99+
template <typename _Tp, typename... _Args>
100+
_LIBCPP_HIDE_FROM_ABI list<_Tp> make_list(_Args... __args) {
101+
return list(std::forward<_Args>(__args)..., make_alloc<_Tp>());
102+
}
103+
};
104+
105+
struct _LIBCPP_HIDE_FROM_ABI entry_base {
106+
uintptr_t __addr_actual_{}; // this address, as observed in this current process
107+
uintptr_t __addr_unslid_{}; // address adjusted for ASLR
108+
optional<__stacktrace::alloc::str> __desc_{}; // uses wrapped _Allocator from caller
109+
optional<__stacktrace::alloc::str> __file_{}; // uses wrapped _Allocator from caller
110+
uint_least32_t __line_{};
111+
112+
_LIBCPP_HIDE_FROM_ABI stacktrace_entry to_stacktrace_entry() const;
113+
};
114+
115+
struct _LIBCPP_EXPORTED_FROM_ABI builder final {
116+
alloc __alloc_; // wraps the caller-provided allocator
117+
alloc::vec<entry_base> __entries_;
118+
alloc::str __main_prog_path_;
119+
120+
template <class _Allocator>
121+
explicit _LIBCPP_EXPORTED_FROM_ABI builder(_Allocator __alloc)
122+
: __alloc_(__alloc), __entries_(__alloc_.make_vec<entry_base>()), __main_prog_path_(__alloc_.make_str()) {}
123+
124+
_LIBCPP_NO_TAIL_CALLS _LIBCPP_NOINLINE _LIBCPP_EXPORTED_FROM_ABI void
125+
build_stacktrace(size_t __skip, size_t __max_depth);
126+
};
127+
128+
} // namespace __stacktrace
129+
_LIBCPP_END_NAMESPACE_STD
130+
131+
_LIBCPP_POP_MACROS
132+
133+
#endif // _LIBCPP_STACKTRACE_BUILDER

0 commit comments

Comments
 (0)