diff options
Diffstat (limited to 'cxx/include/aesnixx')
-rw-r--r-- | cxx/include/aesnixx/debug.hpp | 161 | ||||
-rw-r--r-- | cxx/include/aesnixx/error.hpp | 2 |
2 files changed, 107 insertions, 56 deletions
diff --git a/cxx/include/aesnixx/debug.hpp b/cxx/include/aesnixx/debug.hpp index 6c92a95..f3e35f4 100644 --- a/cxx/include/aesnixx/debug.hpp +++ b/cxx/include/aesnixx/debug.hpp @@ -10,11 +10,8 @@ #ifdef WIN32 #include <Windows.h> -#pragma warning(push) -#pragma warning(disable: 4091) #include <DbgHelp.h> -#pragma warning(pop) -#pragma comment(lib, "dbghelp.lib") +#pragma comment(lib, "DbgHelp.Lib") #endif #include <cstddef> @@ -29,52 +26,14 @@ namespace aesni class CallStackFormatter { public: - CallStackFormatter() - { - #ifdef WIN32 - valid_flag = SymInitialize(GetCurrentProcess(), NULL, TRUE) ? true : false; - #endif - } + CallStackFormatter() = default; - std::string format(void* addr) const + std::string format_address(const void* addr) const { #ifdef WIN32 - if (!valid_flag) - return format_fallback(addr); - - DWORD64 symbol_info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; - PSYMBOL_INFO symbol_info = (PSYMBOL_INFO) symbol_info_buf; - symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol_info->MaxNameLen = MAX_SYM_NAME; - - IMAGEHLP_MODULE64 module_info; - module_info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); - - DWORD64 displacement_within_symbol; - - if (!SymFromAddr(GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &displacement_within_symbol, symbol_info)) - { - if (!SymGetModuleInfo64(GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &module_info)) - return format_fallback(addr); - - void* const displacement_within_module = reinterpret_cast<char*>(addr) - module_info.BaseOfImage; - return format_with_module(module_info.ModuleName, displacement_within_module); - } - - if (!SymGetModuleInfo64(GetCurrentProcess(), symbol_info->ModBase, &module_info)) - return format_with_symbol(symbol_info->Name, addr); - - return format_with_symbol_and_module(symbol_info->Name, module_info.ModuleName, reinterpret_cast<void*>(displacement_within_symbol)); + return format_address_win32(addr); #else - return format_fallback(addr); - #endif - } - - ~CallStackFormatter() - { - #ifdef WIN32 - if (valid_flag) - SymCleanup(GetCurrentProcess()); + return format_address_fallback(addr); #endif } @@ -95,31 +54,123 @@ namespace aesni return oss.str(); } - std::string format_fallback(void* addr) const + static std::string format_address_fallback(const void* addr) { return put_between_brackets(addr); } - std::string format_with_module(const std::string& module_name, void* displacement) const + static std::string format_module( + const std::string& module_name, + const void* offset = nullptr) { - if (displacement == NULL) + if (offset == nullptr) return put_between_brackets(module_name); else - return put_between_brackets(module_name + "+" + stringify(displacement)); + return put_between_brackets(module_name + "+" + stringify(offset)); } - std::string format_with_symbol(const std::string& symbol_name, void* displacement) const + static std::string format_symbol( + const std::string& symbol_name, + const void* offset = nullptr) { - return format_with_module(symbol_name, displacement); + return format_module(symbol_name, offset); } - std::string format_with_symbol_and_module(const std::string& symbol_name, const std::string& module_name, void* displacement) const + static std::string format_symbol( + const std::string& module_name, + const std::string& symbol_name, + const void* offset = nullptr) { - return format_with_symbol(module_name + "!" + symbol_name, displacement); + return format_symbol(module_name + "!" + symbol_name, offset); } #ifdef WIN32 - bool valid_flag = false; + class DbgHelp + { + public: + DbgHelp() + { + initialized_flag = SymInitialize(GetCurrentProcess(), NULL, TRUE) != FALSE; + } + + bool initialized() const + { + return initialized_flag; + } + + ~DbgHelp() + { + if (initialized_flag) + SymCleanup(GetCurrentProcess()); + } + + private: + bool initialized_flag = false; + + DbgHelp(const DbgHelp&) = delete; + DbgHelp& operator=(const DbgHelp&) = delete; + }; + + DbgHelp dbghelp; + + std::string format_address_win32(const void* addr) const + { + if (!dbghelp.initialized()) + return format_address_fallback(addr); + + DWORD64 symbol_info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; + const auto symbol_info = reinterpret_cast<SYMBOL_INFO*>(symbol_info_buf); + symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol_info->MaxNameLen = MAX_SYM_NAME; + + IMAGEHLP_MODULE64 module_info; + module_info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); + + DWORD64 symbol_offset; + + const auto symbol_resolved = SymFromAddr( + GetCurrentProcess(), + reinterpret_cast<DWORD64>(addr), + &symbol_offset, + symbol_info); + + if (symbol_resolved) + { + const auto module_resolved = SymGetModuleInfo64( + GetCurrentProcess(), + symbol_info->ModBase, + &module_info); + + if (module_resolved) + { + return format_symbol( + module_info.ModuleName, + symbol_info->Name, + reinterpret_cast<const void*>(symbol_offset)); + } + else + { + return format_symbol(symbol_info->Name, addr); + } + } + else + { + const auto module_resolved = SymGetModuleInfo64( + GetCurrentProcess(), + reinterpret_cast<DWORD64>(addr), + &module_info); + + if (module_resolved) + { + const auto module_offset = reinterpret_cast<const char*>(addr) - module_info.BaseOfImage; + return format_module(module_info.ModuleName, module_offset); + } + else + { + return format_address_fallback(addr); + } + } + } #endif }; } diff --git a/cxx/include/aesnixx/error.hpp b/cxx/include/aesnixx/error.hpp index 9118e97..067d563 100644 --- a/cxx/include/aesnixx/error.hpp +++ b/cxx/include/aesnixx/error.hpp @@ -40,7 +40,7 @@ namespace aesni aux::CallStackFormatter formatter; std::for_each(call_stack, call_stack + call_stack_size, [&formatter, &callback] (void* addr) { - callback(addr, formatter.format(addr)); + callback(addr, formatter.format_address(addr)); }); } |