std::basic_stacktrace(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

🌸 NAME 🌸

Bestie, this is the whole std::basic_stacktrace(3) situation from the C++ Standard Libary (their spelling, not mine 😭) β€” and the NAME entry is literally std::basic_stacktrace β€” std::basic_stacktrace. Yes, icon behavior. We're about to get into it. πŸ’…


πŸ“Έ Synopsis πŸ“Έ

Okay so, Defined in header <stacktrace> β€” here's the declaration vibe:

Defined in header <stacktrace>

template< class Allocator >
class basic_stacktrace;

(1) (since C++23)

using stacktrace =
    std::basic_stacktrace<std::allocator<std::stacktrace_entry>>;

(2) (since C++23)

namespace pmr {

using stacktrace =
    std::basic_stacktrace<std::pmr::polymorphic_allocator<std::stacktrace_entry>>;

}

(3) (since C++23)

  1. The basic_stacktrace class template represents a snapshot of the whole stacktrace or its given part. It satisfies the requirement of AllocatorAwareContainer, SequenceContainer, and ReversibleContainer, except that only move, assignment, swap, and operations for const-qualified sequence containers are supported, and the semantics of comparison functions are different from those required for a container.
  2. Convenience type alias for the basic_stacktrace using the default std::allocator.
  3. Convenience type alias for the basic_stacktrace using the polymorphic allocator.

The invocation sequence of the current evaluation x[0] (the original math writes {x}_{0}) in the current thread of execution is a sequence ({x}_{0}, ..., {x}_{n}) aka (x[0], ..., x[n]) of evaluations such that, for i β‰₯ 0, {x}_{i} aka x[i] is within the function invocation {x}_{i+1} aka x[i+1].

A stacktrace is an approximate representation of an invocation sequence and consists of stacktrace entries. ✨

A stacktrace entry represents an evaluation in a stacktrace. It is represented by std::stacktrace_entry in the C++ standard library.


🧩 Template parameters 🧩

  • Allocator β€” an allocator that is used to acquire/release memory and to construct/destroy the elements in that memory. The type must meet the requirements of Allocator. The program is ill-formed if Allocator::value_type is not std::stacktrace_entry. 🫢

πŸŽ€ Member types πŸŽ€

  • value_type β€” std::stacktrace_entry
  • const_reference β€” const value_type&
  • reference β€” value_type&
  • const_iterator β€” implementation-defined const LegacyRandomAccessIterator type that models random_access_iterator
  • iterator β€” const_iterator
  • reverse_iterator β€” std::reverse_iterator<iterator>
  • reverse_const_iterator β€” std::reverse_iterator<const_iterator>
  • difference_type β€” implementation-defined signed integer type
  • size_type β€” implementation-defined unsigned integer type
  • allocator_type β€” Allocator

πŸ› οΈ Member functions πŸ› οΈ

  • constructor β€” creates a new basic_stacktrace (public member function)
  • destructor β€” destroys the basic_stacktrace (public member function)
  • operator= β€” assigns to the basic_stacktrace (public member function)
  • current β€” obtains the current stacktrace or its given part (public static member function)
  • get_allocator β€” returns the associated allocator (public member function)

πŸ¦‹ Iterators πŸ¦‹

  • begin β€” returns an iterator to the beginning (public member function)
  • cbegin β€” public member function
  • end β€” returns an iterator to the end (public member function)
  • cend β€” public member function
  • rbegin β€” returns a reverse iterator to the beginning (public member function)
  • crbegin β€” public member function
  • rend β€” returns a reverse iterator to the end (public member function)
  • crend β€” public member function

πŸ“¦ Capacity πŸ“¦

  • empty β€” checks whether the basic_stacktrace is empty (public member function)
  • size β€” returns the number of stacktrace entries (public member function)
  • max_size β€” returns the maximum possible number of stacktrace entries (public member function)

πŸšͺ Element access πŸšͺ

  • operator[] β€” access specified stacktrace entry (public member function)
  • at β€” access specified stacktrace entry with bounds checking (public member function)

πŸ” Modifiers πŸ”

  • swap β€” swaps the contents (public member function)

🫢 Non-member functions 🫢

  • operator== β€” compares the sizes and the contents of two basic_stacktrace values (function template)
  • operator<=> (C++23) β€” compares the sizes and the contents of two basic_stacktrace values (function template)
  • std::swap(std::basic_stacktrace) (C++23) β€” specializes the std::swap algorithm (function template)
  • to_string (C++23) β€” returns a string with a description of the basic_stacktrace (function template)
  • operator<< (C++23) β€” performs stream output of basic_stracktrace (function template)
yes bestie, basic_stracktrace is exactly how it's written there β€” we are preserving the moment, not fixing it πŸ˜­πŸ’€

🧚 Helper classes 🧚

  • std::hash<std::basic_stacktrace> (C++23) β€” hash support for std::basic_stacktrace (class template specialization)
  • std::formatter<std::basic_stacktrace> (C++23) β€” formatting support for basic_stacktrace (class template specialization)

πŸ“ Notes πŸ“

Support for custom allocators is provided for using basic_stacktrace on a hot path or in embedded environments. Users can allocate stacktrace_entry objects on the stack or in some other place, where appropriate. ✨

The sequence of std::stacktrace_entry objects owned by a std::basic_stacktrace is immutable, and either is empty or represents a contiguous interval of the whole stacktrace. No cap.

boost::stacktrace::basic_stacktrace (available in Boost.Stacktrace) can be used instead when std::basic_stacktrace is not available. Backup plan behavior πŸ’…

πŸ”¬ Feature-test macros πŸ”¬

  • __cpp_lib_stacktrace β€” value 202011L β€” Std (C++23) β€” feature: Stacktrace library
  • __cpp_lib_formatters β€” value 202302L β€” Std (C++23) β€” feature: Formatting std::thread::id and std::stacktrace

πŸ§ͺ Example πŸ§ͺ

The output obtained using Compiler Explorer: msvc and gcc. πŸ‘‘

// Run this code

#include <iostream>
#include <stacktrace>

int nested_func(int c)
{
    std::cout << std::stacktrace::current() << '\n';
    return c + 1;
}

int func(int b)
{
    return nested_func(b + 1);
}

int main()
{
    std::cout << func(777);
}

✨ Possible output ✨

// msvc output (the lines ending with '•' arrows are split to fit the
width):
0> C:\Users\ContainerAdministrator\AppData\Local\Temp\compiler-
explorer-compiler20221122-•
31624-2ja1sf.8ytzw\example.cpp(6): output_s!nested_func+0x1F
1> C:\Users\ContainerAdministrator\AppData\Local\Temp\compiler-
explorer-compiler20221122-•
31624-2ja1sf.8ytzw\example.cpp(12): output_s!func+0x15
2> C:\Users\ContainerAdministrator\AppData\Local\Temp\compiler-
explorer-compiler20221122-•
31624-2ja1sf.8ytzw\example.cpp(15): output_s!main+0xE
3>
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288):
output_s!•
__scrt_common_main_seh+0x10C
4> KERNEL32!BaseThreadInitThunk+0x14
5> ntdll!RtlUserThreadStart+0x21
779

gcc output:
   0# nested_func(int) at /app/example.cpp:7
   1# func(int) at /app/example.cpp:13
   2#      at /app/example.cpp:18
   3#      at :0
   4#      at :0
   5#

779

πŸ‘€ See also πŸ‘€

  • stacktrace_entry (C++23) β€” representation of an evaluation in a stacktrace (class)

mwah πŸ’‹ β€” signed with love by http://cppreference.com, dated 2024.06.10, bestie 🫢✨ (that's the source/version and date, not me copying the footer πŸ˜­πŸ’–)

πŸ“¦ where this page comes from