mirror of
https://github.com/QuasarApp/backward-cpp.git
synced 2025-04-30 20:24:30 +00:00
Handle executable being deleted or replaced by directly opening
`/proc/self/exe` rather than file it links to. Fixes issue #146.
This commit is contained in:
parent
79e7738e1f
commit
1ecbdc6491
50
backward.hpp
50
backward.hpp
@ -811,6 +811,31 @@ private:
|
|||||||
|
|
||||||
#ifdef BACKWARD_SYSTEM_LINUX
|
#ifdef BACKWARD_SYSTEM_LINUX
|
||||||
|
|
||||||
|
class TraceResolverLinuxBase
|
||||||
|
: public TraceResolverImplBase {
|
||||||
|
public:
|
||||||
|
TraceResolverLinuxBase()
|
||||||
|
: argv0_(get_argv0()), exec_path_(read_symlink("/proc/self/exe")) {
|
||||||
|
}
|
||||||
|
std::string resolve_exec_path(Dl_info &symbol_info) const {
|
||||||
|
// mutates symbol_info.dli_fname to be filename to open and returns filename to display
|
||||||
|
if(symbol_info.dli_fname == argv0_) {
|
||||||
|
// dladdr returns argv[0] in dli_fname for symbols contained in
|
||||||
|
// the main executable, which is not a valid path if the
|
||||||
|
// executable was found by a search of the PATH environment
|
||||||
|
// variable; In that case, we actually open /proc/self/exe, which
|
||||||
|
// is always the actual executable (even if it was deleted/replaced!)
|
||||||
|
// but display the path that /proc/self/exe links to.
|
||||||
|
symbol_info.dli_fname = "/proc/self/exe";
|
||||||
|
return exec_path_;
|
||||||
|
} else {
|
||||||
|
return symbol_info.dli_fname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string argv0_;
|
||||||
|
std::string exec_path_;
|
||||||
|
|
||||||
static std::string get_argv0() {
|
static std::string get_argv0() {
|
||||||
std::string argv0;
|
std::string argv0;
|
||||||
std::getline(std::ifstream("/proc/self/cmdline"), argv0, '\0');
|
std::getline(std::ifstream("/proc/self/cmdline"), argv0, '\0');
|
||||||
@ -837,6 +862,7 @@ static std::string read_symlink(std::string const &symlink_path) {
|
|||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename STACKTRACE_TAG> class TraceResolverLinuxImpl;
|
template <typename STACKTRACE_TAG> class TraceResolverLinuxImpl;
|
||||||
|
|
||||||
@ -844,7 +870,7 @@ template <typename STACKTRACE_TAG> class TraceResolverLinuxImpl;
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
class TraceResolverLinuxImpl<trace_resolver_tag::backtrace_symbol>
|
class TraceResolverLinuxImpl<trace_resolver_tag::backtrace_symbol>
|
||||||
: public TraceResolverImplBase {
|
: public TraceResolverLinuxBase {
|
||||||
public:
|
public:
|
||||||
template <class ST> void load_stacktrace(ST &st) {
|
template <class ST> void load_stacktrace(ST &st) {
|
||||||
using namespace details;
|
using namespace details;
|
||||||
@ -887,7 +913,7 @@ private:
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
class TraceResolverLinuxImpl<trace_resolver_tag::libbfd>
|
class TraceResolverLinuxImpl<trace_resolver_tag::libbfd>
|
||||||
: public TraceResolverImplBase {
|
: public TraceResolverLinuxBase {
|
||||||
public:
|
public:
|
||||||
TraceResolverLinuxImpl() : _bfd_loaded(false) {}
|
TraceResolverLinuxImpl() : _bfd_loaded(false) {}
|
||||||
|
|
||||||
@ -903,12 +929,6 @@ public:
|
|||||||
return trace; // dat broken trace...
|
return trace; // dat broken trace...
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tmp;
|
|
||||||
if (symbol_info.dli_fname == get_argv0()) {
|
|
||||||
tmp = read_symlink("/proc/self/exe");
|
|
||||||
symbol_info.dli_fname = tmp.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we get in symbol_info:
|
// Now we get in symbol_info:
|
||||||
// .dli_fname:
|
// .dli_fname:
|
||||||
// pathname of the shared object that contains the address.
|
// pathname of the shared object that contains the address.
|
||||||
@ -928,7 +948,7 @@ public:
|
|||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace.object_filename = symbol_info.dli_fname;
|
trace.object_filename = resolve_exec_path(symbol_info);
|
||||||
bfd_fileobject &fobj = load_object_with_bfd(symbol_info.dli_fname);
|
bfd_fileobject &fobj = load_object_with_bfd(symbol_info.dli_fname);
|
||||||
if (!fobj.handle) {
|
if (!fobj.handle) {
|
||||||
return trace; // sad, we couldn't load the object :(
|
return trace; // sad, we couldn't load the object :(
|
||||||
@ -1257,7 +1277,7 @@ private:
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
class TraceResolverLinuxImpl<trace_resolver_tag::libdw>
|
class TraceResolverLinuxImpl<trace_resolver_tag::libdw>
|
||||||
: public TraceResolverImplBase {
|
: public TraceResolverLinuxBase {
|
||||||
public:
|
public:
|
||||||
TraceResolverLinuxImpl() : _dwfl_handle_initialized(false) {}
|
TraceResolverLinuxImpl() : _dwfl_handle_initialized(false) {}
|
||||||
|
|
||||||
@ -1586,7 +1606,7 @@ private:
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
class TraceResolverLinuxImpl<trace_resolver_tag::libdwarf>
|
class TraceResolverLinuxImpl<trace_resolver_tag::libdwarf>
|
||||||
: public TraceResolverImplBase {
|
: public TraceResolverLinuxBase {
|
||||||
public:
|
public:
|
||||||
TraceResolverLinuxImpl() : _dwarf_loaded(false) {}
|
TraceResolverLinuxImpl() : _dwarf_loaded(false) {}
|
||||||
|
|
||||||
@ -1613,12 +1633,6 @@ public:
|
|||||||
return trace; // dat broken trace...
|
return trace; // dat broken trace...
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tmp;
|
|
||||||
if (symbol_info.dli_fname == get_argv0()) {
|
|
||||||
tmp = read_symlink("/proc/self/exe");
|
|
||||||
symbol_info.dli_fname = tmp.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we get in symbol_info:
|
// Now we get in symbol_info:
|
||||||
// .dli_fname:
|
// .dli_fname:
|
||||||
// pathname of the shared object that contains the address.
|
// pathname of the shared object that contains the address.
|
||||||
@ -1645,7 +1659,7 @@ public:
|
|||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace.object_filename = symbol_info.dli_fname;
|
trace.object_filename = resolve_exec_path(symbol_info);
|
||||||
dwarf_fileobject &fobj = load_object_with_dwarf(symbol_info.dli_fname);
|
dwarf_fileobject &fobj = load_object_with_dwarf(symbol_info.dli_fname);
|
||||||
if (!fobj.dwarf_handle) {
|
if (!fobj.dwarf_handle) {
|
||||||
return trace; // sad, we couldn't load the object :(
|
return trace; // sad, we couldn't load the object :(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user