Skip to content

Commit

Permalink
s
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimitri Rusin committed Jan 19, 2024
1 parent e156ada commit 454623b
Showing 1 changed file with 77 additions and 4 deletions.
81 changes: 77 additions & 4 deletions include/ioh/common/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <execinfo.h>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <signal.h>
#include <string>
#include <type_traits>
#include <unistd.h>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -58,6 +61,79 @@ namespace ioh::problem
};
} // namespace ioh::problem




void print_backtrace() {
const int max_frames = 64;
void* addrlist[max_frames + 1];

// retrieve current stack addresses
int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));

if (addrlen == 0) {
std::cerr << " <empty, possibly corrupt>\n";
return;
}

// resolve addresses into strings containing "filename(function+address)",
// this array must be free()-ed
char** symbollist = backtrace_symbols(addrlist, addrlen);

// allocate string which will be filled with the demangled function name
size_t funcnamesize = 256;
char* funcname = (char*)malloc(funcnamesize);

// iterate over the returned symbol lines. skip the first, it is the
// address of this function.
for (int i = 1; i < addrlen; i++) {
char *begin_name = nullptr, *begin_offset = nullptr, *end_offset = nullptr;

// find parentheses and +address offset surrounding the mangled name
for (char *p = symbollist[i]; *p; ++p) {
if (*p == '(')
begin_name = p;
else if (*p == '+')
begin_offset = p;
else if (*p == ')' && begin_offset) {
end_offset = p;
break;
}
}

if (begin_name && begin_offset && end_offset && begin_name < begin_offset) {
*begin_name++ = '\0';
*begin_offset++ = '\0';
*end_offset = '\0';

// mangle the function name
int status;
char* ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status);
if (status == 0) {
funcname = ret; // use possibly realloc()-ed string
std::cerr << " " << symbollist[i] << " : " << funcname << "+" << begin_offset << "\n";
} else {
// demangling failed, output function name as a C function with no arguments
std::cerr << " " << symbollist[i] << " : " << begin_name << "()+" << begin_offset << "\n";
}
} else {
// couldn't parse the line, print the whole line
std::cerr << " " << symbollist[i] << "\n";
}
}

free(funcname);
free(symbollist);
}









namespace ioh::common
{

Expand Down Expand Up @@ -142,11 +218,8 @@ namespace ioh::common

if (already_defined) {
std::string error_message = "Error: The name '" + name + "' has already been defined in the factory.";

// Output the error message to both std::cerr and std::cout
std::cerr << error_message << std::endl;
std::cout << error_message << std::endl;

print_backtrace(); // Print the backtrace here
assert(!already_defined && name.c_str());
}

Expand Down

0 comments on commit 454623b

Please sign in to comment.