Skip to content

Commit

Permalink
Diagnostics: Fix demangling
Browse files Browse the repository at this point in the history
Rename to better names
More comments
Less branches
  • Loading branch information
EmosewaMC committed Oct 7, 2023
1 parent b33e993 commit 122d56c
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 57 deletions.
2 changes: 1 addition & 1 deletion dCommon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ set(DCOMMON_SOURCES
"NiPoint3.cpp"
"NiQuaternion.cpp"
"SHA512.cpp"
"Type.cpp"
"Demangler.cpp"
"ZCompression.cpp"
"BrickByBrickFix.cpp"
"BinaryPathFinder.cpp"
Expand Down
29 changes: 29 additions & 0 deletions dCommon/Demangler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "Demangler.h"
#ifdef __GNUG__
#include <cstdlib>
#include <cxxabi.h>
#include <memory>
#include <typeinfo>

std::string Demangler::Demangle(const char* name) {
// some arbitrary value to eliminate the compiler warning
// -4 is not a valid return value for __cxa_demangle so we'll use that.
int status = -4;

// __cxa_demangle requires that we free the returned char*
std::unique_ptr<char, void (*)(void*)> res{
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};

return (status == 0) ? res.get() : "";
}

#else // __GNUG__

// does nothing if not g++
std::string Demangler::Demangle(const char* name) {
return name;
}

#endif // __GNUG__
9 changes: 9 additions & 0 deletions dCommon/Demangler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <string>

namespace Demangler {
// Given a char* containing a mangled name, return a std::string containing the demangled name.
// If the function fails for any reason, it returns an empty string.
std::string Demangle(const char* name);
}
36 changes: 19 additions & 17 deletions dCommon/Diagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static void ErrorCallback(void* data, const char* msg, int errnum) {
}
#endif

#include "Type.h"
#include "Demangler.h"

void GenerateDump() {
std::string cmd = "sudo gcore " + std::to_string(getpid());
Expand All @@ -122,41 +122,43 @@ void CatchUnhandled(int sig) {
if (Diagnostics::GetProduceMemoryDump()) {
GenerateDump();
}

void* array[10];
constexpr uint8_t MaxStackTrace = 32;
void* array[MaxStackTrace];
size_t size;

// get void*'s for all entries on the stack
size = backtrace(array, 10);
size = backtrace(array, MaxStackTrace);

#if defined(__GNUG__) and defined(__dynamic)
# if defined(__GNUG__)

// Loop through the returned addresses, and get the symbols to be demangled
char** strings = backtrace_symbols(array, size);

// Print the stack trace
for (size_t i = 0; i < size; i++) {
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' and extract the function name
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]'
// and extract '_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress' from it to be demangled into a proper name
std::string functionName = strings[i];
std::string::size_type start = functionName.find('(');
std::string::size_type end = functionName.find('+');
if (start != std::string::npos && end != std::string::npos) {
std::string demangled = functionName.substr(start + 1, end - start - 1);

demangled = demangle(functionName.c_str());
demangled = Demangler::Demangle(demangled.c_str());

if (demangled.empty()) {
Game::logger->Log("Diagnostics", "[%02zu] %s", i, demangled.c_str());
} else {
Game::logger->Log("Diagnostics", "[%02zu] %s", i, functionName.c_str());
// If the demangled string is not empty, then we can replace the mangled string with the demangled one
if (!demangled.empty()) {
demangled.push_back('(');
demangled += functionName.substr(end);
functionName = demangled;
}
} else {
Game::logger->Log("Diagnostics", "[%02zu] %s", i, functionName.c_str());
}

Game::logger->Log("Diagnostics", "[%02zu] %s", i, functionName.c_str());
}
#else
# else // defined(__GNUG__)
backtrace_symbols_fd(array, size, STDOUT_FILENO);
#endif
# endif // defined(__GNUG__)

FILE* file = fopen(fileName.c_str(), "w+");
if (file != NULL) {
Expand All @@ -166,7 +168,7 @@ void CatchUnhandled(int sig) {
fclose(file);
}

#else
#else // __include_backtrace__

struct backtrace_state* state = backtrace_create_state(
Diagnostics::GetProcessFileName().c_str(),
Expand All @@ -177,7 +179,7 @@ void CatchUnhandled(int sig) {
struct bt_ctx ctx = { state, 0 };
Bt(state);

#endif
#endif // __include_backtrace__

exit(EXIT_FAILURE);
}
Expand Down
27 changes: 0 additions & 27 deletions dCommon/Type.cpp

This file was deleted.

12 changes: 0 additions & 12 deletions dCommon/Type.h

This file was deleted.

0 comments on commit 122d56c

Please sign in to comment.