mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-11-03 22:21:59 +00:00 
			
		
		
		
	Diagnostics: Fix demangling (#1215)
Rename to better names More comments Less branches
This commit is contained in:
		@@ -12,7 +12,7 @@ set(DCOMMON_SOURCES
 | 
			
		||||
		"NiPoint3.cpp"
 | 
			
		||||
		"NiQuaternion.cpp"
 | 
			
		||||
		"SHA512.cpp"
 | 
			
		||||
		"Type.cpp"
 | 
			
		||||
		"Demangler.cpp"
 | 
			
		||||
		"ZCompression.cpp"
 | 
			
		||||
		"BrickByBrickFix.cpp"
 | 
			
		||||
		"BinaryPathFinder.cpp"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								dCommon/Demangler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								dCommon/Demangler.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -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
									
								
								dCommon/Demangler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								dCommon/Demangler.h
									
									
									
									
									
										Normal file
									
								
							@@ -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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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());
 | 
			
		||||
@@ -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) {
 | 
			
		||||
@@ -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(),
 | 
			
		||||
@@ -177,7 +179,7 @@ void CatchUnhandled(int sig) {
 | 
			
		||||
	struct bt_ctx ctx = { state, 0 };
 | 
			
		||||
	Bt(state);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif // __include_backtrace__
 | 
			
		||||
 | 
			
		||||
	exit(EXIT_FAILURE);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
#include "Type.h"
 | 
			
		||||
#ifdef __GNUG__
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <cxxabi.h>
 | 
			
		||||
 | 
			
		||||
std::string demangle(const char* name) {
 | 
			
		||||
 | 
			
		||||
	int status = -4; // some arbitrary value to eliminate the compiler warning
 | 
			
		||||
 | 
			
		||||
	// enable c++11 by passing the flag -std=c++11 to g++
 | 
			
		||||
	std::unique_ptr<char, void(*)(void*)> res{
 | 
			
		||||
		abi::__cxa_demangle(name, NULL, NULL, &status),
 | 
			
		||||
		std::free
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return (status == 0) ? res.get() : name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// does nothing if not g++
 | 
			
		||||
std::string demangle(const char* name) {
 | 
			
		||||
	return name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
 | 
			
		||||
std::string demangle(const char* name);
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
std::string type(const T& t) {
 | 
			
		||||
 | 
			
		||||
	return demangle(typeid(t).name());
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user