From 89023f7c05a33ded51d041450dd86c7a6b3e9fea Mon Sep 17 00:00:00 2001 From: prbegd <1225095986@qq.com> Date: Sat, 24 Jan 2026 23:11:47 +0800 Subject: [PATCH 1/4] Fix for issue 212 --- .../stacktrace/detail/libbacktrace_impls.hpp | 185 +++++++++++++++++- 1 file changed, 183 insertions(+), 2 deletions(-) diff --git a/include/boost/stacktrace/detail/libbacktrace_impls.hpp b/include/boost/stacktrace/detail/libbacktrace_impls.hpp index bde53f22..f9b3c989 100644 --- a/include/boost/stacktrace/detail/libbacktrace_impls.hpp +++ b/include/boost/stacktrace/detail/libbacktrace_impls.hpp @@ -23,6 +23,13 @@ # include #endif +#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# include +# include +# include "boost/winapi/access_rights.hpp" +# include "boost/winapi/handles.hpp" +#endif + namespace boost { namespace stacktrace { namespace detail { @@ -114,6 +121,180 @@ BOOST_SYMBOL_VISIBLE inline ::backtrace_state* construct_state(const program_loc return state; } +#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +[[nodiscard]] inline uintptr_t read_static_image_base(const char* file_path) noexcept +{ + boost::winapi::HANDLE_ hfile = boost::winapi::CreateFileA( + file_path, + boost::winapi::GENERIC_READ_, + boost::winapi::FILE_SHARE_READ_, + nullptr, + boost::winapi::OPEN_EXISTING_, + boost::winapi::FILE_ATTRIBUTE_NORMAL_, + nullptr); + + if (hfile == boost::winapi::INVALID_HANDLE_VALUE_) { + return 0; + } + + // Use anonymous struct because boost::winapi doesn't have IMAGE_DOS_HEADER + // yet. Same for all other anonymous structs in this function. + struct /* _IMAGE_DOS_HEADER */ { + boost::winapi::WORD_ e_magic; + boost::winapi::WORD_ e_cblp; + boost::winapi::WORD_ e_cp; + boost::winapi::WORD_ e_crlc; + boost::winapi::WORD_ e_cparhdr; + boost::winapi::WORD_ e_minalloc; + boost::winapi::WORD_ e_maxalloc; + boost::winapi::WORD_ e_ss; + boost::winapi::WORD_ e_sp; + boost::winapi::WORD_ e_csum; + boost::winapi::WORD_ e_ip; + boost::winapi::WORD_ e_cs; + boost::winapi::WORD_ e_lfarlc; + boost::winapi::WORD_ e_ovno; + boost::winapi::WORD_ e_res[4]; + boost::winapi::WORD_ e_oemid; + boost::winapi::WORD_ e_oeminfo; + boost::winapi::WORD_ e_res2[10]; + boost::winapi::LONG_ e_lfanew; + } dos_header {}; + boost::winapi::DWORD_ bytes_read = 0; + + if (!boost::winapi::ReadFile(hfile, &dos_header, sizeof(dos_header), + &bytes_read, nullptr) || dos_header.e_magic != 0x5A4D /* IMAGE_DOS_SIGNATURE */) { + boost::winapi::CloseHandle(hfile); + return 0; + } + + boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew, nullptr, boost::winapi::FILE_BEGIN_); + + boost::winapi::DWORD_ nt_signature = 0; + boost::winapi::ReadFile(hfile, &nt_signature, sizeof(nt_signature), &bytes_read, nullptr); + + if (nt_signature != 0x00004550 /* IMAGE_NT_SIGNATURE */) { + boost::winapi::CloseHandle(hfile); + return 0; + } + + struct /* _IMAGE_FILE_HEADER */ { + boost::winapi::WORD_ Machine; + boost::winapi::WORD_ NumberOfSections; + boost::winapi::DWORD_ TimeDateStamp; + boost::winapi::DWORD_ PointerToSymbolTable; + boost::winapi::DWORD_ NumberOfSymbols; + boost::winapi::WORD_ SizeOfOptionalHeader; + boost::winapi::WORD_ Characteristics; + } file_header {}; + boost::winapi::ReadFile(hfile, &file_header, sizeof(file_header), &bytes_read, nullptr); + + uintptr_t image_base = 0; + if (file_header.SizeOfOptionalHeader > 0) { + boost::winapi::WORD_ magic = 0; + boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew + 4 + sizeof(file_header), nullptr, boost::winapi::FILE_BEGIN_); + boost::winapi::ReadFile(hfile, &magic, sizeof(magic), &bytes_read, nullptr); + + typedef struct _IMAGE_DATA_DIRECTORY { + boost::winapi::DWORD_ VirtualAddress; + boost::winapi::DWORD_ Size; + } IMAGE_DATA_DIRECTORY; + + if (magic == 0x10b /* IMAGE_NT_OPTIONAL_HDR32_MAGIC */) { + struct /* _IMAGE_OPTIONAL_HEADER */ { + boost::winapi::WORD_ Magic; + boost::winapi::BYTE_ MajorLinkerVersion; + boost::winapi::BYTE_ MinorLinkerVersion; + boost::winapi::DWORD_ SizeOfCode; + boost::winapi::DWORD_ SizeOfInitializedData; + boost::winapi::DWORD_ SizeOfUninitializedData; + boost::winapi::DWORD_ AddressOfEntryPoint; + boost::winapi::DWORD_ BaseOfCode; + boost::winapi::DWORD_ BaseOfData; + boost::winapi::DWORD_ ImageBase; + boost::winapi::DWORD_ SectionAlignment; + boost::winapi::DWORD_ FileAlignment; + boost::winapi::WORD_ MajorOperatingSystemVersion; + boost::winapi::WORD_ MinorOperatingSystemVersion; + boost::winapi::WORD_ MajorImageVersion; + boost::winapi::WORD_ MinorImageVersion; + boost::winapi::WORD_ MajorSubsystemVersion; + boost::winapi::WORD_ MinorSubsystemVersion; + boost::winapi::DWORD_ Win32VersionValue; + boost::winapi::DWORD_ SizeOfImage; + boost::winapi::DWORD_ SizeOfHeaders; + boost::winapi::DWORD_ CheckSum; + boost::winapi::WORD_ Subsystem; + boost::winapi::WORD_ DllCharacteristics; + boost::winapi::DWORD_ SizeOfStackReserve; + boost::winapi::DWORD_ SizeOfStackCommit; + boost::winapi::DWORD_ SizeOfHeapReserve; + boost::winapi::DWORD_ SizeOfHeapCommit; + boost::winapi::DWORD_ LoaderFlags; + boost::winapi::DWORD_ NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[16 /* IMAGE_NUMBEROF_DIRECTORY_ENTRIES */]; + } optional_header {}; + boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew + 4 + sizeof(file_header), nullptr, boost::winapi::FILE_BEGIN_); + boost::winapi::ReadFile(hfile, &optional_header, sizeof(optional_header), &bytes_read, nullptr); + image_base = optional_header.ImageBase; + } else if (magic == 0x20b /* IMAGE_NT_OPTIONAL_HDR64_MAGIC */) { + struct /* _IMAGE_OPTIONAL_HEADER64 */ { + boost::winapi::WORD_ Magic; + boost::winapi::BYTE_ MajorLinkerVersion; + boost::winapi::BYTE_ MinorLinkerVersion; + boost::winapi::DWORD_ SizeOfCode; + boost::winapi::DWORD_ SizeOfInitializedData; + boost::winapi::DWORD_ SizeOfUninitializedData; + boost::winapi::DWORD_ AddressOfEntryPoint; + boost::winapi::DWORD_ BaseOfCode; + boost::winapi::ULONGLONG_ ImageBase; + boost::winapi::DWORD_ SectionAlignment; + boost::winapi::DWORD_ FileAlignment; + boost::winapi::WORD_ MajorOperatingSystemVersion; + boost::winapi::WORD_ MinorOperatingSystemVersion; + boost::winapi::WORD_ MajorImageVersion; + boost::winapi::WORD_ MinorImageVersion; + boost::winapi::WORD_ MajorSubsystemVersion; + boost::winapi::WORD_ MinorSubsystemVersion; + boost::winapi::DWORD_ Win32VersionValue; + boost::winapi::DWORD_ SizeOfImage; + boost::winapi::DWORD_ SizeOfHeaders; + boost::winapi::DWORD_ CheckSum; + boost::winapi::WORD_ Subsystem; + boost::winapi::WORD_ DllCharacteristics; + boost::winapi::ULONGLONG_ SizeOfStackReserve; + boost::winapi::ULONGLONG_ SizeOfStackCommit; + boost::winapi::ULONGLONG_ SizeOfHeapReserve; + boost::winapi::ULONGLONG_ SizeOfHeapCommit; + boost::winapi::DWORD_ LoaderFlags; + boost::winapi::DWORD_ NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[16 /* IMAGE_NUMBEROF_DIRECTORY_ENTRIES */]; + } optional_header {}; + boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew + 4 + sizeof(file_header), nullptr, boost::winapi::FILE_BEGIN_); + boost::winapi::ReadFile(hfile, &optional_header, sizeof(optional_header), &bytes_read, nullptr); + image_base = optional_header.ImageBase; + } + } + + boost::winapi::CloseHandle(hfile); + return image_base; +} +[[nodiscard]] inline uintptr_t rebase_address_for_syminfo(const void* addr_ptr) noexcept +{ + auto addr = reinterpret_cast(addr_ptr); + + boost::stacktrace::detail::location_from_symbol loc(addr_ptr); + const char* symbol_file = loc.empty() ? nullptr : loc.name(); + const auto static_base = read_static_image_base(symbol_file); + const auto dynamic_base = reinterpret_cast(boost::winapi::GetModuleHandleA(symbol_file)); + + return addr - dynamic_base + static_base; +} +#else +[[nodiscard]] inline uintptr_t rebase_address_for_syminfo(const void* addr_ptr) noexcept +{ return reinterpret_cast(addr_ptr); } +#endif + struct to_string_using_backtrace { std::string res; boost::stacktrace::detail::program_location prog_location; @@ -134,7 +315,7 @@ struct to_string_using_backtrace { || ::backtrace_syminfo( state, - reinterpret_cast(addr), + rebase_address_for_syminfo(addr), boost::stacktrace::detail::libbacktrace_syminfo_callback, boost::stacktrace::detail::libbacktrace_error_callback, &data @@ -181,7 +362,7 @@ inline std::string name_impl(const void* addr) { || ::backtrace_syminfo( state, - reinterpret_cast(addr), + rebase_address_for_syminfo(addr), boost::stacktrace::detail::libbacktrace_syminfo_callback, boost::stacktrace::detail::libbacktrace_error_callback, &data From f39e222138b7a63822a4624365d3e171f7e358b8 Mon Sep 17 00:00:00 2001 From: prbegd <1225095986@qq.com> Date: Sun, 25 Jan 2026 11:18:48 +0800 Subject: [PATCH 2/4] Fix libbacktrace_full_callback return value --- include/boost/stacktrace/detail/libbacktrace_impls.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/stacktrace/detail/libbacktrace_impls.hpp b/include/boost/stacktrace/detail/libbacktrace_impls.hpp index f9b3c989..2c3c831b 100644 --- a/include/boost/stacktrace/detail/libbacktrace_impls.hpp +++ b/include/boost/stacktrace/detail/libbacktrace_impls.hpp @@ -60,7 +60,7 @@ inline int libbacktrace_full_callback(void *data, uintptr_t /*pc*/, const char * *d.function = function; } d.line = static_cast(lineno); - return 0; + return 1; } inline void libbacktrace_error_callback(void* /*data*/, const char* /*msg*/, int /*errnum*/) noexcept { From 73347cb7fb1e183af0227e1ce7a0c006280b962f Mon Sep 17 00:00:00 2001 From: prbegd <1225095986@qq.com> Date: Sun, 25 Jan 2026 14:40:07 +0800 Subject: [PATCH 3/4] Fix: libbacktrace_full_callback will return 0 if there is no data --- include/boost/stacktrace/detail/libbacktrace_impls.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/boost/stacktrace/detail/libbacktrace_impls.hpp b/include/boost/stacktrace/detail/libbacktrace_impls.hpp index 2c3c831b..4c8c4613 100644 --- a/include/boost/stacktrace/detail/libbacktrace_impls.hpp +++ b/include/boost/stacktrace/detail/libbacktrace_impls.hpp @@ -53,14 +53,20 @@ inline void libbacktrace_syminfo_callback(void *data, uintptr_t pc, const char * inline int libbacktrace_full_callback(void *data, uintptr_t /*pc*/, const char *filename, int lineno, const char *function) { pc_data& d = *static_cast(data); + int return_value = 0; if (d.filename && filename) { *d.filename = filename; + return_value = 1; } if (d.function && function) { *d.function = function; + return_value = 1; } d.line = static_cast(lineno); - return 1; + if (d.line) { + return_value = 1; + } + return return_value; } inline void libbacktrace_error_callback(void* /*data*/, const char* /*msg*/, int /*errnum*/) noexcept { From 32b23c01f6b43d7de2d1bce9783f11030948805a Mon Sep 17 00:00:00 2001 From: prbegd <90972353+prbegd@users.noreply.github.com> Date: Sat, 11 Jul 2026 12:39:38 +0800 Subject: [PATCH 4/4] Revert "Fix for issue 212" This reverts commit 89023f7c05a33ded51d041450dd86c7a6b3e9fea. --- .../stacktrace/detail/libbacktrace_impls.hpp | 185 +----------------- 1 file changed, 2 insertions(+), 183 deletions(-) diff --git a/include/boost/stacktrace/detail/libbacktrace_impls.hpp b/include/boost/stacktrace/detail/libbacktrace_impls.hpp index 6e040ebd..28930aef 100644 --- a/include/boost/stacktrace/detail/libbacktrace_impls.hpp +++ b/include/boost/stacktrace/detail/libbacktrace_impls.hpp @@ -26,13 +26,6 @@ #include #include -#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -# include -# include -# include "boost/winapi/access_rights.hpp" -# include "boost/winapi/handles.hpp" -#endif - namespace boost { namespace stacktrace { namespace detail { @@ -130,180 +123,6 @@ BOOST_SYMBOL_VISIBLE inline ::backtrace_state* construct_state(const program_loc return state; } -#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -[[nodiscard]] inline uintptr_t read_static_image_base(const char* file_path) noexcept -{ - boost::winapi::HANDLE_ hfile = boost::winapi::CreateFileA( - file_path, - boost::winapi::GENERIC_READ_, - boost::winapi::FILE_SHARE_READ_, - nullptr, - boost::winapi::OPEN_EXISTING_, - boost::winapi::FILE_ATTRIBUTE_NORMAL_, - nullptr); - - if (hfile == boost::winapi::INVALID_HANDLE_VALUE_) { - return 0; - } - - // Use anonymous struct because boost::winapi doesn't have IMAGE_DOS_HEADER - // yet. Same for all other anonymous structs in this function. - struct /* _IMAGE_DOS_HEADER */ { - boost::winapi::WORD_ e_magic; - boost::winapi::WORD_ e_cblp; - boost::winapi::WORD_ e_cp; - boost::winapi::WORD_ e_crlc; - boost::winapi::WORD_ e_cparhdr; - boost::winapi::WORD_ e_minalloc; - boost::winapi::WORD_ e_maxalloc; - boost::winapi::WORD_ e_ss; - boost::winapi::WORD_ e_sp; - boost::winapi::WORD_ e_csum; - boost::winapi::WORD_ e_ip; - boost::winapi::WORD_ e_cs; - boost::winapi::WORD_ e_lfarlc; - boost::winapi::WORD_ e_ovno; - boost::winapi::WORD_ e_res[4]; - boost::winapi::WORD_ e_oemid; - boost::winapi::WORD_ e_oeminfo; - boost::winapi::WORD_ e_res2[10]; - boost::winapi::LONG_ e_lfanew; - } dos_header {}; - boost::winapi::DWORD_ bytes_read = 0; - - if (!boost::winapi::ReadFile(hfile, &dos_header, sizeof(dos_header), - &bytes_read, nullptr) || dos_header.e_magic != 0x5A4D /* IMAGE_DOS_SIGNATURE */) { - boost::winapi::CloseHandle(hfile); - return 0; - } - - boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew, nullptr, boost::winapi::FILE_BEGIN_); - - boost::winapi::DWORD_ nt_signature = 0; - boost::winapi::ReadFile(hfile, &nt_signature, sizeof(nt_signature), &bytes_read, nullptr); - - if (nt_signature != 0x00004550 /* IMAGE_NT_SIGNATURE */) { - boost::winapi::CloseHandle(hfile); - return 0; - } - - struct /* _IMAGE_FILE_HEADER */ { - boost::winapi::WORD_ Machine; - boost::winapi::WORD_ NumberOfSections; - boost::winapi::DWORD_ TimeDateStamp; - boost::winapi::DWORD_ PointerToSymbolTable; - boost::winapi::DWORD_ NumberOfSymbols; - boost::winapi::WORD_ SizeOfOptionalHeader; - boost::winapi::WORD_ Characteristics; - } file_header {}; - boost::winapi::ReadFile(hfile, &file_header, sizeof(file_header), &bytes_read, nullptr); - - uintptr_t image_base = 0; - if (file_header.SizeOfOptionalHeader > 0) { - boost::winapi::WORD_ magic = 0; - boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew + 4 + sizeof(file_header), nullptr, boost::winapi::FILE_BEGIN_); - boost::winapi::ReadFile(hfile, &magic, sizeof(magic), &bytes_read, nullptr); - - typedef struct _IMAGE_DATA_DIRECTORY { - boost::winapi::DWORD_ VirtualAddress; - boost::winapi::DWORD_ Size; - } IMAGE_DATA_DIRECTORY; - - if (magic == 0x10b /* IMAGE_NT_OPTIONAL_HDR32_MAGIC */) { - struct /* _IMAGE_OPTIONAL_HEADER */ { - boost::winapi::WORD_ Magic; - boost::winapi::BYTE_ MajorLinkerVersion; - boost::winapi::BYTE_ MinorLinkerVersion; - boost::winapi::DWORD_ SizeOfCode; - boost::winapi::DWORD_ SizeOfInitializedData; - boost::winapi::DWORD_ SizeOfUninitializedData; - boost::winapi::DWORD_ AddressOfEntryPoint; - boost::winapi::DWORD_ BaseOfCode; - boost::winapi::DWORD_ BaseOfData; - boost::winapi::DWORD_ ImageBase; - boost::winapi::DWORD_ SectionAlignment; - boost::winapi::DWORD_ FileAlignment; - boost::winapi::WORD_ MajorOperatingSystemVersion; - boost::winapi::WORD_ MinorOperatingSystemVersion; - boost::winapi::WORD_ MajorImageVersion; - boost::winapi::WORD_ MinorImageVersion; - boost::winapi::WORD_ MajorSubsystemVersion; - boost::winapi::WORD_ MinorSubsystemVersion; - boost::winapi::DWORD_ Win32VersionValue; - boost::winapi::DWORD_ SizeOfImage; - boost::winapi::DWORD_ SizeOfHeaders; - boost::winapi::DWORD_ CheckSum; - boost::winapi::WORD_ Subsystem; - boost::winapi::WORD_ DllCharacteristics; - boost::winapi::DWORD_ SizeOfStackReserve; - boost::winapi::DWORD_ SizeOfStackCommit; - boost::winapi::DWORD_ SizeOfHeapReserve; - boost::winapi::DWORD_ SizeOfHeapCommit; - boost::winapi::DWORD_ LoaderFlags; - boost::winapi::DWORD_ NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[16 /* IMAGE_NUMBEROF_DIRECTORY_ENTRIES */]; - } optional_header {}; - boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew + 4 + sizeof(file_header), nullptr, boost::winapi::FILE_BEGIN_); - boost::winapi::ReadFile(hfile, &optional_header, sizeof(optional_header), &bytes_read, nullptr); - image_base = optional_header.ImageBase; - } else if (magic == 0x20b /* IMAGE_NT_OPTIONAL_HDR64_MAGIC */) { - struct /* _IMAGE_OPTIONAL_HEADER64 */ { - boost::winapi::WORD_ Magic; - boost::winapi::BYTE_ MajorLinkerVersion; - boost::winapi::BYTE_ MinorLinkerVersion; - boost::winapi::DWORD_ SizeOfCode; - boost::winapi::DWORD_ SizeOfInitializedData; - boost::winapi::DWORD_ SizeOfUninitializedData; - boost::winapi::DWORD_ AddressOfEntryPoint; - boost::winapi::DWORD_ BaseOfCode; - boost::winapi::ULONGLONG_ ImageBase; - boost::winapi::DWORD_ SectionAlignment; - boost::winapi::DWORD_ FileAlignment; - boost::winapi::WORD_ MajorOperatingSystemVersion; - boost::winapi::WORD_ MinorOperatingSystemVersion; - boost::winapi::WORD_ MajorImageVersion; - boost::winapi::WORD_ MinorImageVersion; - boost::winapi::WORD_ MajorSubsystemVersion; - boost::winapi::WORD_ MinorSubsystemVersion; - boost::winapi::DWORD_ Win32VersionValue; - boost::winapi::DWORD_ SizeOfImage; - boost::winapi::DWORD_ SizeOfHeaders; - boost::winapi::DWORD_ CheckSum; - boost::winapi::WORD_ Subsystem; - boost::winapi::WORD_ DllCharacteristics; - boost::winapi::ULONGLONG_ SizeOfStackReserve; - boost::winapi::ULONGLONG_ SizeOfStackCommit; - boost::winapi::ULONGLONG_ SizeOfHeapReserve; - boost::winapi::ULONGLONG_ SizeOfHeapCommit; - boost::winapi::DWORD_ LoaderFlags; - boost::winapi::DWORD_ NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[16 /* IMAGE_NUMBEROF_DIRECTORY_ENTRIES */]; - } optional_header {}; - boost::winapi::SetFilePointer(hfile, dos_header.e_lfanew + 4 + sizeof(file_header), nullptr, boost::winapi::FILE_BEGIN_); - boost::winapi::ReadFile(hfile, &optional_header, sizeof(optional_header), &bytes_read, nullptr); - image_base = optional_header.ImageBase; - } - } - - boost::winapi::CloseHandle(hfile); - return image_base; -} -[[nodiscard]] inline uintptr_t rebase_address_for_syminfo(const void* addr_ptr) noexcept -{ - auto addr = reinterpret_cast(addr_ptr); - - boost::stacktrace::detail::location_from_symbol loc(addr_ptr); - const char* symbol_file = loc.empty() ? nullptr : loc.name(); - const auto static_base = read_static_image_base(symbol_file); - const auto dynamic_base = reinterpret_cast(boost::winapi::GetModuleHandleA(symbol_file)); - - return addr - dynamic_base + static_base; -} -#else -[[nodiscard]] inline uintptr_t rebase_address_for_syminfo(const void* addr_ptr) noexcept -{ return reinterpret_cast(addr_ptr); } -#endif - struct to_string_using_backtrace { std::string res; boost::stacktrace::detail::program_location prog_location; @@ -324,7 +143,7 @@ struct to_string_using_backtrace { || ::backtrace_syminfo( state, - rebase_address_for_syminfo(addr), + reinterpret_cast(addr), boost::stacktrace::detail::libbacktrace_syminfo_callback, boost::stacktrace::detail::libbacktrace_error_callback, &data @@ -371,7 +190,7 @@ inline std::string name_impl(const void* addr) { || ::backtrace_syminfo( state, - rebase_address_for_syminfo(addr), + reinterpret_cast(addr), boost::stacktrace::detail::libbacktrace_syminfo_callback, boost::stacktrace::detail::libbacktrace_error_callback, &data