20 General utilities library [utilities]

20.21 Stacktrace [stacktrace]

20.21.1 General [stacktrace.general]

Subclause [stacktrace] describes components that C++ programs may use to store the stacktrace of the current thread of execution and query information about the stored stacktrace at runtime.
The invocation sequence of the current evaluation in the current thread of execution is a sequence of evaluations such that, for , is within the function invocation ([intro.execution]).
A stacktrace is an approximate representation of an invocation sequence and consists of stacktrace entries.
A stacktrace entry represents an evaluation in a stacktrace.

20.21.2 Header <stacktrace> synopsis [stacktrace.syn]

namespace std { // [stacktrace.entry], class stacktrace_­entry class stacktrace_entry; // [stacktrace.basic], class template basic_­stacktrace template<class Allocator> class basic_stacktrace; // basic_­stacktrace typedef names using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>; // [stacktrace.basic.nonmem], non-member functions template<class Allocator> void swap(basic_stacktrace<Allocator>& a, basic_stacktrace<Allocator>& b) noexcept(noexcept(a.swap(b))); string to_string(const stacktrace_entry& f); template<class Allocator> string to_string(const basic_stacktrace<Allocator>& st); template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const stacktrace_entry& f); template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_stacktrace<Allocator>& st); // [stacktrace.basic.hash], hash support template<class T> struct hash; template<> struct hash<stacktrace_entry>; template<class Allocator> struct hash<basic_stacktrace<Allocator>>; }

20.21.3 Class stacktrace_­entry [stacktrace.entry]

20.21.3.1 Overview [stacktrace.entry.overview]

namespace std { class stacktrace_entry { public: using native_handle_type = implementation-defined; // [stacktrace.entry.ctor], constructors constexpr stacktrace_entry() noexcept; constexpr stacktrace_entry(const stacktrace_entry& other) noexcept; constexpr stacktrace_entry& operator=(const stacktrace_entry& other) noexcept; ~stacktrace_entry(); // [stacktrace.entry.obs], observers constexpr native_handle_type native_handle() const noexcept; constexpr explicit operator bool() const noexcept; // [stacktrace.entry.query], query string description() const; string source_file() const; uint_least32_t source_line() const; // [stacktrace.entry.cmp], comparison friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept; friend constexpr strong_ordering operator<=>(const stacktrace_entry& x, const stacktrace_entry& y) noexcept; }; }
An object of type stacktrace_­entry is either empty, or represents a stacktrace entry and provides operations for querying information about it.
The class stacktrace_­entry models regular ([concepts.object]) and three_­way_­comparable<strong_­ordering> ([cmp.concept]).

20.21.3.2 Constructors [stacktrace.entry.ctor]

constexpr stacktrace_entry() noexcept;
Postconditions: *this is empty.

20.21.3.3 Observers [stacktrace.entry.obs]

constexpr native_handle_type native_handle() const noexcept;
The semantics of this function are implementation-defined.
Remarks: Successive invocations of the native_­handle function for an unchanged stacktrace_­entry object return identical values.
constexpr explicit operator bool() const noexcept;
Returns: false if and only if *this is empty.

20.21.3.4 Query [stacktrace.entry.query]

[Note 1:
All the stacktrace_­entry query functions treat errors other than memory allocation errors as β€œno information available” and do not throw in that case.
β€” end note]
string description() const;
Returns: A description of the evaluation represented by *this, or an empty string.
Throws: bad_­alloc if memory for the internal data structures or the resulting string cannot be allocated.
string source_file() const;
Returns: The presumed or actual name of the source file ([cpp.predefined]) that lexically contains the expression or statement whose evaluation is represented by *this, or an empty string.
Throws: bad_­alloc if memory for the internal data structures or the resulting string cannot be allocated.
uint_least32_t source_line() const;
Returns: 0, or a 1-based line number that lexically relates to the evaluation represented by *this.
If source_­file returns the presumed name of the source file, returns the presumed line number; if source_­file returns the actual name of the source file, returns the actual line number.
Throws: bad_­alloc if memory for the internal data structures cannot be allocated.

20.21.3.5 Comparison [stacktrace.entry.cmp]

friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept;
Returns: true if and only if x and y represent the same stacktrace entry or both x and y are empty.

20.21.4 Class template basic_­stacktrace [stacktrace.basic]

20.21.4.1 Overview [stacktrace.basic.overview]

namespace std { template<class Allocator> class basic_stacktrace { public: using value_type = stacktrace_entry; using const_reference = const value_type&; using reference = value_type&; using const_iterator = implementation-defined; // see [stacktrace.basic.obs] using iterator = const_iterator; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using difference_type = implementation-defined; using size_type = implementation-defined; using allocator_type = Allocator; // [stacktrace.basic.ctor], creation and assignment static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept; static basic_stacktrace current(size_type skip, const allocator_type& alloc = allocator_type()) noexcept; static basic_stacktrace current(size_type skip, size_type max_depth, const allocator_type& alloc = allocator_type()) noexcept; basic_stacktrace() noexcept(is_nothrow_default_constructible_v<allocator_type>); explicit basic_stacktrace(const allocator_type& alloc) noexcept; basic_stacktrace(const basic_stacktrace& other); basic_stacktrace(basic_stacktrace&& other) noexcept; basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc); basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc); basic_stacktrace& operator=(const basic_stacktrace& other); basic_stacktrace& operator=(basic_stacktrace&& other) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); ~basic_stacktrace(); // [stacktrace.basic.obs], observers allocator_type get_allocator() const noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator rend() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; const_reference operator[](size_type) const; const_reference at(size_type) const; // [stacktrace.basic.cmp], comparisons template<class Allocator2> friend bool operator==(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept; template<class Allocator2> friend strong_ordering operator<=>(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept; // [stacktrace.basic.mod], modifiers void swap(basic_stacktrace& other) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value); private: vector<value_type, allocator_type> frames_; // exposition only }; }
The class template basic_­stacktrace satisfies the requirements of an allocator-aware container (Table 76), a sequence container ([sequence.reqmts]), and a reversible container ([container.requirements.general]) except that
  • only move, assignment, swap, and operations defined for const-qualified sequence containers are supported and,
  • the semantics of comparison functions are different from those required for a container.

20.21.4.2 Creation and assignment [stacktrace.basic.ctor]

static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept;
Returns: A basic_­stacktrace object with frames_­ storing the stacktrace of the current evaluation in the current thread of execution, or an empty basic_­stacktrace object if the initialization of frames_­ failed.
alloc is passed to the constructor of the frames_­ object.
[Note 1:
If the stacktrace was successfully obtained, then frames_­.front() is the stacktrace_­entry representing approximately the current evaluation, and frames_­.back() is the stacktrace_­entry representing approximately the initial function of the current thread of execution.
β€” end note]
static basic_stacktrace current(size_type skip, const allocator_type& alloc = allocator_type()) noexcept;
Let t be a stacktrace as-if obtained via basic_­stacktrace​::​current(alloc).
Let n be t.size().
Returns: A basic_­stacktrace object where frames_­ is direct-non-list-initialized from arguments t.begin() + min(n, skip), t.end(), and alloc, or an empty basic_­stacktrace object if the initialization of frames_­ failed.
static basic_stacktrace current(size_type skip, size_type max_depth, const allocator_type& alloc = allocator_type()) noexcept;
Let t be a stacktrace as-if obtained via basic_­stacktrace​::​current(alloc).
Let n be t.size().
Preconditions: skip <= skip + max_­depth is true.
Returns: A basic_­stacktrace object where frames_­ is direct-non-list-initialized from arguments t.begin() + min(n, skip), t.begin() + min(n, skip + max_­depth), and alloc, or an empty basic_­stacktrace object if the initialization of frames_­ failed.
basic_stacktrace() noexcept(is_nothrow_default_constructible_v<allocator_type>);
Postconditions: empty() is true.
explicit basic_stacktrace(const allocator_type& alloc) noexcept;
Effects: alloc is passed to the frames_­ constructor.
Postconditions: empty() is true.
basic_stacktrace(const basic_stacktrace& other); basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc); basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc); basic_stacktrace& operator=(const basic_stacktrace& other); basic_stacktrace& operator=(basic_stacktrace&& other) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Remarks: Implementations may strengthen the exception specification for these functions ([res.on.exception.handling]) by ensuring that empty() is true on failed allocation.

20.21.4.3 Observers [stacktrace.basic.obs]

using const_iterator = implementation-defined;
The type models random_­access_­iterator ([iterator.concept.random.access]) and meets the Cpp17RandomAccessIterator requirements ([random.access.iterators]).
allocator_type get_allocator() const noexcept;
Returns: frames_­.get_­allocator().
const_iterator begin() const noexcept; const_iterator cbegin() const noexcept;
Returns: An iterator referring to the first element in frames_­.
If empty() is true, then it returns the same value as end().
const_iterator end() const noexcept; const_iterator cend() const noexcept;
Returns: The end iterator.
const_reverse_iterator rbegin() const noexcept; const_reverse_iterator crbegin() const noexcept;
Returns: reverse_­iterator(cend()).
const_reverse_iterator rend() const noexcept; const_reverse_iterator crend() const noexcept;
Returns: reverse_­iterator(cbegin()).
[[nodiscard]] bool empty() const noexcept;
Returns: frames_­.empty().
size_type size() const noexcept;
Returns: frames_­.size().
size_type max_size() const noexcept;
Returns: frames_­.max_­size().
const_reference operator[](size_type frame_no) const;
Preconditions: frame_­no < size() is true.
Returns: frames_­[frame_­no].
Throws: Nothing.
const_reference at(size_type frame_no) const;
Returns: frames_­[frame_­no].
Throws: out_­of_­range if frame_­no >= size().

20.21.4.4 Comparisons [stacktrace.basic.cmp]

template<class Allocator2> friend bool operator==(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept;
Returns: equal(x.begin(), x.end(), y.begin(), y.end()).
template<class Allocator2> friend strong_ordering operator<=>(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept;
Returns: x.size() <=> y.size() if x.size() != y.size(); lexicographical_­compare_­three_­way(x.begin(), x.end(), y.begin(), y.end()) otherwise.

20.21.4.5 Modifiers [stacktrace.basic.mod]

void swap(basic_stacktrace& other) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Exchanges the contents of *this and other.

20.21.4.6 Non-member functions [stacktrace.basic.nonmem]

template<class Allocator> void swap(basic_stacktrace<Allocator>& a, basic_stacktrace<Allocator>& b) noexcept(noexcept(a.swap(b)));
Effects: Equivalent to a.swap(b).
string to_string(const stacktrace_entry& f);
Returns: A string with a description of f.
Recommended practice: The description should provide information about the contained evaluation, including information from f.source_­file() and f.source_­line().
template<class Allocator> string to_string(const basic_stacktrace<Allocator>& st);
Returns: A string with a description of st.
[Note 1:
The number of lines is not guaranteed to be equal to st.size().
β€” end note]
template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const stacktrace_entry& f);
Effects: Equivalent to: return os << to_­string(f);
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_stacktrace<Allocator>& st);
Effects: Equivalent to: return os << to_­string(st);

20.21.4.7 Hash support [stacktrace.basic.hash]

template<> struct hash<stacktrace_entry>; template<class Allocator> struct hash<basic_stacktrace<Allocator>>;
The specializations are enabled ([unord.hash]).