Skip to content

Commit

Permalink
Introduce TraceResolver::load_addresses() for raw address array
Browse files Browse the repository at this point in the history
TraceResolver has a load_stacktrace() method accepting only an
object like StackTrace. That object is basically an array of
pointers.

This was not really convenient, because

1) it required carrying of this StackTrace object from the moment
  of its creation to the load_stacktrace() invocation. Sometimes
  this is a long path. And that may break encapsulation, if a
  project, using Backward, does not want to include Backward
  header anywhere except for 1 or 2 C++ files, responsible for
  collection and resolution of addresses. So basically,
  load_stacktrace() prevented split of stack load and stack
  resolution into separate submodules of a project;

2) that made impossible to use Backward to resolve a stack,
  collected not via Backward.

The patch introduces a new method load_addresses(), accepting an
array of addresses. That solves both problems.

Alongside, to avoid increase of code duplication by empty
load_addresses() methods in the classes where they are not needed,
now both load_stacktrace() and load_addresses() are in one base
class, used by all resolvers. load_addresses() is a virtual
method, which does nothing, except for a couple of classes, where
it is overridden as backtrace_symbols(). load_stacktrace() just
calls load_addresses() and doesn't need to be defined everywhere
again and again.
  • Loading branch information
Gerold103 committed Feb 25, 2020
1 parent c51737a commit 220eda3
Showing 1 changed file with 28 additions and 32 deletions.
60 changes: 28 additions & 32 deletions backward.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,19 +944,16 @@ class StackTrace : public StackTraceImpl<system_tag::current_tag> {};

/*************** TRACE RESOLVER ***************/

template <typename TAG> class TraceResolverImpl;

#ifdef BACKWARD_SYSTEM_UNKNOWN

template <> class TraceResolverImpl<system_tag::unknown_tag> {
class TraceResolverImplBase {
public:
template <class ST> void load_stacktrace(ST &) {}
ResolvedTrace resolve(ResolvedTrace t) { return t; }
};
virtual void load_addresses(void *const*addresses, int address_count) {}

#endif
template <class ST> void load_stacktrace(ST &st) {
load_addresses(st.begin(), (int)st.size());
}

virtual ResolvedTrace resolve(ResolvedTrace t) { return t; }

class TraceResolverImplBase {
protected:
std::string demangle(const char *funcname) {
return _demangler.demangle(funcname);
Expand All @@ -966,6 +963,15 @@ class TraceResolverImplBase {
details::demangler _demangler;
};

template <typename TAG> class TraceResolverImpl;

#ifdef BACKWARD_SYSTEM_UNKNOWN

template <> class TraceResolverImpl<system_tag::unknown_tag>
: public TraceResolverImplBase {};

#endif

#ifdef BACKWARD_SYSTEM_LINUX

class TraceResolverLinuxBase
Expand Down Expand Up @@ -1029,15 +1035,14 @@ template <>
class TraceResolverLinuxImpl<trace_resolver_tag::backtrace_symbol>
: public TraceResolverLinuxBase {
public:
template <class ST> void load_stacktrace(ST &st) {
using namespace details;
if (st.size() == 0) {
void load_addresses(void *const*addresses, int address_count) override {
if (address_count == 0) {
return;
}
_symbols.reset(backtrace_symbols(st.begin(), (int)st.size()));
_symbols.reset(backtrace_symbols(addresses, address_count));
}

ResolvedTrace resolve(ResolvedTrace trace) {
ResolvedTrace resolve(ResolvedTrace trace) override {
char *filename = _symbols[trace.idx];
char *funcname = filename;
while (*funcname && *funcname != '(') {
Expand Down Expand Up @@ -1074,9 +1079,7 @@ class TraceResolverLinuxImpl<trace_resolver_tag::libbfd>
public:
TraceResolverLinuxImpl() : _bfd_loaded(false) {}

template <class ST> void load_stacktrace(ST &) {}

ResolvedTrace resolve(ResolvedTrace trace) {
ResolvedTrace resolve(ResolvedTrace trace) override {
Dl_info symbol_info;

// trace.addr is a virtual address in memory pointing to some code.
Expand Down Expand Up @@ -1438,9 +1441,7 @@ class TraceResolverLinuxImpl<trace_resolver_tag::libdw>
public:
TraceResolverLinuxImpl() : _dwfl_handle_initialized(false) {}

template <class ST> void load_stacktrace(ST &) {}

ResolvedTrace resolve(ResolvedTrace trace) {
ResolvedTrace resolve(ResolvedTrace trace) override {
using namespace details;

Dwarf_Addr trace_addr = (Dwarf_Addr)trace.addr;
Expand Down Expand Up @@ -1767,9 +1768,7 @@ class TraceResolverLinuxImpl<trace_resolver_tag::libdwarf>
public:
TraceResolverLinuxImpl() : _dwarf_loaded(false) {}

template <class ST> void load_stacktrace(ST &) {}

ResolvedTrace resolve(ResolvedTrace trace) {
ResolvedTrace resolve(ResolvedTrace trace) override {
// trace.addr is a virtual address in memory pointing to some code.
// Let's try to find from which loaded object it comes from.
// The loaded object can be yourself btw.
Expand Down Expand Up @@ -3148,15 +3147,14 @@ template <>
class TraceResolverDarwinImpl<trace_resolver_tag::backtrace_symbol>
: public TraceResolverImplBase {
public:
template <class ST> void load_stacktrace(ST &st) {
using namespace details;
if (st.size() == 0) {
void load_addresses(void *const*addresses, int address_count) override {
if (address_count == 0) {
return;
}
_symbols.reset(backtrace_symbols(st.begin(), st.size()));
_symbols.reset(backtrace_symbols(addresses, address_count));
}

ResolvedTrace resolve(ResolvedTrace trace) {
ResolvedTrace resolve(ResolvedTrace trace) override {
// parse:
// <n> <file> <addr> <mangled-name> + <offset>
char *filename = _symbols[trace.idx];
Expand Down Expand Up @@ -3291,8 +3289,6 @@ template <> class TraceResolverImpl<system_tag::windows_tag> {
image_type = h->FileHeader.Machine;
}

template <class ST> void load_stacktrace(ST &) {}

static const int max_sym_len = 255;
struct symbol_t {
SYMBOL_INFO sym;
Expand All @@ -3301,7 +3297,7 @@ template <> class TraceResolverImpl<system_tag::windows_tag> {

DWORD64 displacement;

ResolvedTrace resolve(ResolvedTrace t) {
ResolvedTrace resolve(ResolvedTrace t) override {
HANDLE process = GetCurrentProcess();

char name[256];
Expand Down

0 comments on commit 220eda3

Please sign in to comment.