Skip to content

Commit

Permalink
Avoid program_invocation_name which is available only on Linux
Browse files Browse the repository at this point in the history
`program_invocation_name` is defined by the system headers only on
Linux, or at least it is not available on FreeBSD.

Introduce own global variable that contains the program name. If
it is unset then use `getprogname()` or `program_invocation_name`.

Co-authored-by: Ken Sedgwick <ken@bonsai.com>
  • Loading branch information
vasild and ksedgwic committed Oct 25, 2024
1 parent d595541 commit f545cbf
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Boss/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
# include "config.h"
#endif

std::string g_argv0;

namespace Boss {

class Main::Impl {
Expand Down Expand Up @@ -62,6 +64,7 @@ class Main::Impl {
{
assert(argv.size() >= 1);
argv0 = argv[0];
g_argv0 = argv[0];
if (argv.size() >= 2) {
auto argv1 = argv[1];
if (argv1 == "--version" || argv1 == "-V")
Expand Down
27 changes: 25 additions & 2 deletions Util/BacktraceException.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@
#include <iomanip>
#include <memory>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <string.h>
#include <string>

#ifdef HAVE_CONFIG_H
# include"config.h"
#endif

extern std::string g_argv0;

namespace Util {

Expand Down Expand Up @@ -74,13 +81,29 @@ class BacktraceException : public T {
return oss.str();
}

std::string progname() const {
// This variable is set by the CLBOSS mainline.
if (!g_argv0.empty()) {
return g_argv0;
}

// When libclboss is linked with the unit tests the
// g_argv0 variable is not set and we need to use
// built-in versions
#ifdef HAVE_GETPROGNAME
return getprogname();
#else
return program_invocation_name;
#endif
}

// Unfortunately there is no simple way to get a high quality
// backtrace using in-process libraries. Instead for now we
// popen an addr2line process and use it's output.
std::string addr2line(void* addr) const {
char cmd[512];
snprintf(cmd, sizeof(cmd),
"addr2line -C -f -p -e %s %p", program_invocation_name, addr);
"addr2line -C -f -p -e %s %p", progname().c_str(), addr);

std::array<char, 128> buffer;
std::string result;
Expand Down
15 changes: 15 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,21 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
AC_MSG_RESULT([no])
])

# Check for getprogname()
AC_MSG_CHECKING([for getprogname])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include<stdlib.h>
]], [[
const char* p = getprogname();
(void)p; // avoid warning about set but unused variable
]])], [ #then
AC_DEFINE([HAVE_GETPROGNAME], [1],
[Define to 1 if you have a getprogname function.])
AC_MSG_RESULT([yes])
], [ #else
AC_MSG_RESULT([no])
])

AC_CONFIG_FILES([Makefile
external/bitcoin-ripemd160/Makefile
external/bitcoin-sha256/Makefile
Expand Down

0 comments on commit f545cbf

Please sign in to comment.