diff options
Diffstat (limited to 'src/dbghelp.cpp')
-rw-r--r-- | src/dbghelp.cpp | 243 |
1 files changed, 100 insertions, 143 deletions
diff --git a/src/dbghelp.cpp b/src/dbghelp.cpp index 38cb6f5..40c2ba5 100644 --- a/src/dbghelp.cpp +++ b/src/dbghelp.cpp @@ -5,180 +5,137 @@ #include "pdb/all.hpp" -#include <safeint.h> - #include <Windows.h> +#include <safeint.h> #pragma warning(push, 0) #include <DbgHelp.h> #pragma warning(pop, 0) #include <cstddef> #include <cstring> - #include <stdexcept> #include <string> -namespace pdb -{ - namespace - { - void set_dbghelp_options() - { - SymSetOptions(SymGetOptions() - | SYMOPT_DEBUG - | SYMOPT_LOAD_LINES - | SYMOPT_UNDNAME); - } - - void initialize(HANDLE id) - { - set_dbghelp_options(); - - if (!SymInitialize(id, NULL, FALSE)) - throw error::windows(GetLastError()); - } - - void clean_up(HANDLE id) - { - if (!SymCleanup(id)) - throw error::windows(GetLastError()); - } - - Address next_offline_base = 0x10000000; - - Address gen_next_offline_base(std::size_t pdb_size) - { - const auto base = next_offline_base; - using msl::utilities::SafeAdd; - if (!SafeAdd(next_offline_base, pdb_size, next_offline_base)) - throw std::runtime_error{"no more PDB files can be added, the internal address space is exhausted"}; - return base; - } - - BOOL CALLBACK enum_symbols_callback( - SYMBOL_INFO *info, - ULONG, - VOID *raw_callback_ptr) - { - const auto callback_ptr = reinterpret_cast<DbgHelp::OnSymbol*>(raw_callback_ptr); - const auto& callback = *callback_ptr; - callback(SymbolInfo{*info}); - return TRUE; - } - } +namespace pdb { +namespace { - DbgHelp::DbgHelp() - { - initialize(id); - } +void set_dbghelp_options() { + SymSetOptions(SymGetOptions() | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME); +} - DbgHelp::~DbgHelp() - { - try - { - close(); - } - catch (...) - { } - } +void initialize(HANDLE id) { + set_dbghelp_options(); - void DbgHelp::close() - { - if (!closed) - { - clean_up(id); - closed = true; - } - } + if (!SymInitialize(id, NULL, FALSE)) + throw error::windows(GetLastError()); +} - ModuleInfo DbgHelp::load_pdb(const std::string& path) const - { - DWORD size = 0; - if (!msl::utilities::SafeCast(file::get_size(path), size)) - throw std::range_error{"PDB file is too large"}; +void clean_up(HANDLE id) { + if (!SymCleanup(id)) + throw error::windows(GetLastError()); +} - const auto offline_base = SymLoadModule64( - id, - NULL, - path.c_str(), - NULL, - gen_next_offline_base(size), - size); +Address next_offline_base = 0x10000000; - if (!offline_base) - throw error::windows(GetLastError()); +Address gen_next_offline_base(std::size_t pdb_size) { + const auto base = next_offline_base; + using msl::utilities::SafeAdd; + if (!SafeAdd(next_offline_base, pdb_size, next_offline_base)) + throw std::runtime_error{ + "no more PDB files can be added, the internal address space is exhausted"}; + return base; +} - return get_module_info(offline_base); - } +BOOL CALLBACK enum_symbols_callback(SYMBOL_INFO* info, ULONG, VOID* raw_callback_ptr) { + const auto callback_ptr = reinterpret_cast<DbgHelp::OnSymbol*>(raw_callback_ptr); + const auto& callback = *callback_ptr; + callback(SymbolInfo{*info}); + return TRUE; +} - ModuleInfo DbgHelp::get_module_info(Address offline_base) const - { - ModuleInfo info; +} // namespace - if (!SymGetModuleInfo64( - id, - offline_base, - &static_cast<ModuleInfo::Raw&>(info))) - throw error::windows(GetLastError()); +DbgHelp::DbgHelp() { + initialize(id); +} - return info; +DbgHelp::~DbgHelp() { + try { + close(); + } catch (...) { } +} - void DbgHelp::enum_symbols(const ModuleInfo& module, const OnSymbol& callback) const - { - if (!SymEnumSymbols( - id, - module.get_offline_base(), - NULL, - &enum_symbols_callback, - const_cast<OnSymbol*>(&callback))) - throw error::windows(GetLastError()); +void DbgHelp::close() { + if (!closed) { + clean_up(id); + closed = true; } +} - SymbolInfo DbgHelp::resolve_symbol(Address offline) const - { - Address displacement = 0; - SymbolInfo symbol; +ModuleInfo DbgHelp::load_pdb(const std::string& path) const { + DWORD size = 0; + if (!msl::utilities::SafeCast(file::get_size(path), size)) + throw std::range_error{"PDB file is too large"}; - if (!SymFromAddr( - id, - offline, - &displacement, - &static_cast<SYMBOL_INFO&>(symbol))) - throw error::windows(GetLastError()); + const auto offline_base = + SymLoadModule64(id, NULL, path.c_str(), NULL, gen_next_offline_base(size), size); - symbol.set_displacement(displacement); - return symbol; - } + if (!offline_base) + throw error::windows(GetLastError()); - SymbolInfo DbgHelp::resolve_symbol(const std::string& name) const - { - SymbolInfo symbol; + return get_module_info(offline_base); +} - if (!SymFromName( - id, - name.c_str(), - &static_cast<SYMBOL_INFO&>(symbol))) - throw error::windows(GetLastError()); +ModuleInfo DbgHelp::get_module_info(Address offline_base) const { + ModuleInfo info; - return symbol; - } + if (!SymGetModuleInfo64(id, offline_base, &static_cast<ModuleInfo::Raw&>(info))) + throw error::windows(GetLastError()); - LineInfo DbgHelp::resolve_line(Address offline) const - { - IMAGEHLP_LINE64 raw; - std::memset(&raw, 0, sizeof(raw)); - raw.SizeOfStruct = sizeof(raw); + return info; +} - DWORD displacement = 0; +void DbgHelp::enum_symbols(const ModuleInfo& module, const OnSymbol& callback) const { + if (!SymEnumSymbols(id, + module.get_offline_base(), + NULL, + &enum_symbols_callback, + const_cast<OnSymbol*>(&callback))) + throw error::windows(GetLastError()); +} - if (!SymGetLineFromAddr64( - id, - offline, - &displacement, - &raw)) - throw error::windows(GetLastError()); +SymbolInfo DbgHelp::resolve_symbol(Address offline) const { + Address displacement = 0; + SymbolInfo symbol; - return LineInfo{raw}; - } + if (!SymFromAddr(id, offline, &displacement, &static_cast<SYMBOL_INFO&>(symbol))) + throw error::windows(GetLastError()); + + symbol.set_displacement(displacement); + return symbol; } + +SymbolInfo DbgHelp::resolve_symbol(const std::string& name) const { + SymbolInfo symbol; + + if (!SymFromName(id, name.c_str(), &static_cast<SYMBOL_INFO&>(symbol))) + throw error::windows(GetLastError()); + + return symbol; +} + +LineInfo DbgHelp::resolve_line(Address offline) const { + IMAGEHLP_LINE64 raw; + std::memset(&raw, 0, sizeof(raw)); + raw.SizeOfStruct = sizeof(raw); + + DWORD displacement = 0; + + if (!SymGetLineFromAddr64(id, offline, &displacement, &raw)) + throw error::windows(GetLastError()); + + return LineInfo{raw}; +} + +} // namespace pdb |