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

View File

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