backtrace: use fmtlib formatters for output

This commit is contained in:
Danny Robson 2024-02-21 14:52:50 +10:00
parent 9804306f13
commit db4d75bb1c
2 changed files with 39 additions and 15 deletions

View File

@ -17,7 +17,7 @@
#include "win32/windows.hpp" #include "win32/windows.hpp"
#include <dbghelp.h> #include <dbghelp.h>
#include <ostream> #include <fmt/ostream.h>
using cruft::backtrace; using cruft::backtrace;
@ -80,6 +80,17 @@ backtrace::backtrace ()
std::ostream& std::ostream&
cruft::operator<< (std::ostream &os, backtrace const &obj) cruft::operator<< (std::ostream &os, backtrace const &obj)
{ {
fmt::print (os, "{}", obj);
return os;
}
///////////////////////////////////////////////////////////////////////////////
fmt::format_context::iterator
fmt::formatter<cruft::backtrace>::format (
cruft::backtrace const &obj,
fmt::format_context &ctx
) {
const auto process = GetCurrentProcess (); const auto process = GetCurrentProcess ();
struct { struct {
@ -91,21 +102,20 @@ cruft::operator<< (std::ostream &os, backtrace const &obj)
sym.info.SizeOfStruct = sizeof (sym.info); sym.info.SizeOfStruct = sizeof (sym.info);
sym.info.MaxNameLen = std::size (sym.name); sym.info.MaxNameLen = std::size (sym.name);
os << "[ "; fmt::format_to (ctx.out (), "[ ");
for (auto const frame: obj.frames ()) { for (auto const frame: obj.frames ()) {
os << "{ addr: " << frame << ", name: "; fmt::format_to (ctx.out (), "{{ addr: {}, name: ", frame);
// Find the symbol name // Find the symbol name
sym.info.Name[0] = '\0'; sym.info.Name[0] = '\0';
memset (sym.name, 0, sizeof (sym.name)); memset (sym.name, 0, sizeof (sym.name));
if (FALSE == SymFromAddr (process, reinterpret_cast<uintptr_t> (frame), nullptr, &sym.info)) { if (FALSE == SymFromAddr (process, reinterpret_cast<uintptr_t> (frame), nullptr, &sym.info)) {
os << "null }, "; fmt::format_to (ctx.out (), "null }}, ");
} else { } else {
os << '\'' << sym.info.Name << "' }, "; fmt::format_to (ctx.out (), "'{}' }}, ", sym.info.Name);
} }
} }
os << " ]"; return fmt::format_to (ctx.out (), " ]");
return os;
} }

View File

@ -45,9 +45,11 @@ backtrace::backtrace (void)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::ostream& fmt::format_context::iterator
debug::operator <<(std::ostream &os, ::cruft::backtrace const &rhs) fmt::formatter<cruft::backtrace>::format (
{ cruft::backtrace const &obj,
fmt::format_context &ctx
) {
static auto process = GetCurrentProcess (); static auto process = GetCurrentProcess ();
CHECK (ready); CHECK (ready);
@ -60,17 +62,29 @@ debug::operator <<(std::ostream &os, ::cruft::backtrace const &rhs)
symbol.info.MaxNameLen = MAX_LENGTH; symbol.info.MaxNameLen = MAX_LENGTH;
symbol.info.SizeOfStruct = sizeof (SYMBOL_INFO); symbol.info.SizeOfStruct = sizeof (SYMBOL_INFO);
os << "[ "; fmt::format_to (ctx.out (), "[ ");
for (void *frame: rhs.frames ()) { for (void *frame: rhs.frames ()) {
symbol.name[0] = '\0'; symbol.name[0] = '\0';
SymFromAddr (process, (DWORD64)frame, 0, &symbol.info); SymFromAddr (process, (DWORD64)frame, 0, &symbol.info);
symbol.name[MAX_LENGTH] = '\0'; symbol.name[MAX_LENGTH] = '\0';
os << "{ addr: " << frame fmt::format_to (
<< ", name: '" << symbol.name '\'' ctx.out (),
<< " }, "; "{{ addr: {}, name: '{}' }}, ",
frame,
symbol.name
);
} }
os << " ]"; return fmt::format_to (ctx.out (), " ]");
}
///////////////////////////////////////////////////////////////////////////////
std::ostream&
debug::operator <<(std::ostream &os, ::cruft::backtrace const &rhs)
{
fmt::print (os, "{}", rhs);
return os; return os;
} }