Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed tcmalloc crashes #794

Merged
merged 2 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core/include/utils/demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@

#include <string>

std::string demangle(const char* name);
std::string demangle(const char* name) noexcept;

#endif // __DEMANGLE_H__
5 changes: 3 additions & 2 deletions src/core/include/utils/get-call-stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@
#include <vector>

/**
* @brief get_call_stack() is a function to get the call stack
* @brief get_call_stack() is a function to get the call stack.
* @attention it must not throw an exception as it is called from OpenFHEException
* @return a vector with call stack (demangled function names)
*/
std::vector<std::string> get_call_stack();
std::vector<std::string> get_call_stack() noexcept;

#endif // __GET_CALL_STACK_H__
27 changes: 22 additions & 5 deletions src/core/lib/utils/demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,31 @@
#if defined(__clang__) || defined(__GNUC__)
#include <cxxabi.h>

std::string demangle(const char* const name) {
int status = -1;
std::unique_ptr<char> result{abi::__cxa_demangle(name, NULL, NULL, &status)};
std::string demangle(const char* const name) noexcept {
// output_buffer must be malloc'ed
size_t output_buffer_size = 512;
auto output_buffer = reinterpret_cast<char*>(std::malloc(output_buffer_size));
int status = -1;

return (status == 0) ? result.get() : (std::string("Can not demangle symbol: ") + name);
char* ptr = abi::__cxa_demangle(name, output_buffer, &output_buffer_size, &status);
std::string result;
if (status == 0 && ptr != nullptr) {
result = ptr;
// If ptr is different from output_buffer, free ptr as it points to the newly allocated (realloc) buffer
if (ptr != output_buffer)
std::free(ptr);
else
std::free(output_buffer);
}
else {
result = "Cannot demangle symbol: " + std::string(name);
std::free(output_buffer);
}

return result;
}
#else
std::string demangle(const char* const name) {
std::string demangle(const char* const name) noexcept {
return name;
}
#endif
20 changes: 12 additions & 8 deletions src/core/lib/utils/get-call-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "utils/get-call-stack.h"

#if defined(__linux__) && defined(__GNUC__)
// clang-format off
// clang-format off
#include "utils/demangle.h"

#include <execinfo.h>
Expand All @@ -43,7 +43,7 @@ namespace {
enum { MAX_BACKTRACE_ADDRESSES = 512 };
}

static bool stringEmpty(const std::string& str) {
static bool stringEmpty(const std::string& str) noexcept {
if (!str.length())
return true;

Expand All @@ -56,18 +56,21 @@ static bool stringEmpty(const std::string& str) {
return true;
}

std::vector<std::string> get_call_stack() {
std::vector<std::string> get_call_stack() noexcept {
void* bt_buffer[MAX_BACKTRACE_ADDRESSES] = {NULL};
const int n = backtrace(bt_buffer, MAX_BACKTRACE_ADDRESSES);
if (n < 1) {
return std::vector<std::string>();
}
const std::unique_ptr<char*> symbols(backtrace_symbols(bt_buffer, n));
char** symbols = reinterpret_cast<char**>(backtrace_symbols(bt_buffer, n));
if (symbols == NULL) {
return std::vector<std::string>();
}

const size_t numSymbols = static_cast<size_t>(n);
std::vector<std::string> ret(numSymbols);
std::vector<std::string> retVec(numSymbols);
for (size_t i = 0; i < numSymbols; ++i) {
std::string symbol(symbols.get()[i]);
std::string symbol(symbols[i]);
// we need to get rid of anything that doesn't belong to the name
// Mangled symbol examples:
// ./lib/libOPENFHEcore.so.1(_Z14get_call_stackB5cxx11v+0x35) [0x7f1b5cdb91d5]
Expand All @@ -81,10 +84,11 @@ std::vector<std::string> get_call_stack() {
size_t newLen = symbol.length() - pos;
std::string mangledName(symbol.substr(pos + 1, newLen));

ret[i] = (stringEmpty(mangledName)) ? symbols.get()[i] : demangle(mangledName.c_str());
retVec[i] = (stringEmpty(mangledName)) ? symbols[i] : demangle(mangledName.c_str());
}

return ret;
free(symbols);
return retVec;
}
#else
std::vector<std::string> get_call_stack() {
Expand Down