From 6890ce0d34f72763a533bc6cfe3069494f21329f Mon Sep 17 00:00:00 2001 From: Miren Radia <32646026+mirenradia@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:39:35 +0100 Subject: [PATCH] BLBackTrace: Check for `addr2line` in path first (#4079) ## Summary This fixes #4077 by first checking if `addr2line` or `eu-addr2line` is in the `PATH` first and then falls back to `/usr/bin/addr2line` or `/usr/bin/eu-addr2line` if not. ## Additional background See #4077 for why using the hardcoded path is a problem. --- Src/Base/AMReX_BLBackTrace.cpp | 44 +++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/Src/Base/AMReX_BLBackTrace.cpp b/Src/Base/AMReX_BLBackTrace.cpp index d511a192728..d065bd71c05 100644 --- a/Src/Base/AMReX_BLBackTrace.cpp +++ b/Src/Base/AMReX_BLBackTrace.cpp @@ -13,12 +13,13 @@ #include #endif +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include #if !(defined(_MSC_VER) && defined(__CUDACC__)) //MSVC can't pre-processor cfenv with `Zc:preprocessor` @@ -177,6 +178,18 @@ namespace { } return r; } + +#ifdef __linux__ + bool command_exists(std::string const &cmd) + { + // command -v is part of POSIX so should be available + std::string check_command = "command -v " + cmd + " > /dev/null 2>&1"; + int r = std::system(check_command.c_str()); + // return value of std::system is implementation defined and can be + // decoded using WEXITSTATUS but it should be 0 on success + return r == 0; + } +#endif } #endif @@ -209,19 +222,32 @@ BLBackTrace::print_backtrace_info (FILE* f) int have_addr2line = 0; std::string eu_cmd; { - have_eu_addr2line = file_exists("/usr/bin/eu-addr2line"); + if (command_exists("eu-addr2line")) { + have_eu_addr2line = 1; + eu_cmd = "eu-addr2line"; + } else { + std::string eu_fallback_path = "/usr/bin/eu-addr2line"; + have_eu_addr2line = file_exists(eu_fallback_path.c_str()); + eu_cmd = std::move(eu_fallback_path); + } if (have_eu_addr2line) { const pid_t pid = getpid(); // cmd = "/usr/bin/eu-addr2line -C -f -i --pretty-print -p " - eu_cmd = "/usr/bin/eu-addr2line -C -f -i -p " - + std::to_string(pid); + eu_cmd += " -C -f -i -p " + std::to_string(pid); } } std::string cmd; { - have_addr2line = file_exists("/usr/bin/addr2line"); + if (command_exists("addr2line")) { + have_addr2line = 1; + cmd = "addr2line"; + } else { + std::string fallback_path = "/usr/bin/addr2line"; + have_addr2line = file_exists(fallback_path.c_str()); + cmd = std::move(fallback_path); + } if (have_addr2line) { - cmd = "/usr/bin/addr2line -Cpfie " + amrex::system::exename; + cmd += " -Cpfie " + amrex::system::exename; } }