From a38dacc6489ff3c7a0748a01ed7cc2bd0cdaaa7c Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Sat, 29 May 2021 01:03:28 +0300 Subject: include/pdb/ -> include/winapi/debug/ --- include/pdb/address.hpp | 34 ------------- include/pdb/all.hpp | 13 ----- include/pdb/call_stack.hpp | 53 -------------------- include/pdb/dbghelp.hpp | 72 --------------------------- include/pdb/module.hpp | 54 --------------------- include/pdb/repo.hpp | 58 ---------------------- include/pdb/symbol.hpp | 97 ------------------------------------- include/winapi/debug.hpp | 13 +++++ include/winapi/debug/address.hpp | 34 +++++++++++++ include/winapi/debug/call_stack.hpp | 53 ++++++++++++++++++++ include/winapi/debug/dbghelp.hpp | 72 +++++++++++++++++++++++++++ include/winapi/debug/module.hpp | 54 +++++++++++++++++++++ include/winapi/debug/repo.hpp | 58 ++++++++++++++++++++++ include/winapi/debug/symbol.hpp | 97 +++++++++++++++++++++++++++++++++++++ 14 files changed, 381 insertions(+), 381 deletions(-) delete mode 100644 include/pdb/address.hpp delete mode 100644 include/pdb/all.hpp delete mode 100644 include/pdb/call_stack.hpp delete mode 100644 include/pdb/dbghelp.hpp delete mode 100644 include/pdb/module.hpp delete mode 100644 include/pdb/repo.hpp delete mode 100644 include/pdb/symbol.hpp create mode 100644 include/winapi/debug.hpp create mode 100644 include/winapi/debug/address.hpp create mode 100644 include/winapi/debug/call_stack.hpp create mode 100644 include/winapi/debug/dbghelp.hpp create mode 100644 include/winapi/debug/module.hpp create mode 100644 include/winapi/debug/repo.hpp create mode 100644 include/winapi/debug/symbol.hpp (limited to 'include') diff --git a/include/pdb/address.hpp b/include/pdb/address.hpp deleted file mode 100644 index 3d7acd6..0000000 --- a/include/pdb/address.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2017 Egor Tensin -// This file is part of the "winapi-debug" project. -// For details, see https://github.com/egor-tensin/winapi-debug. -// Distributed under the MIT License. - -#pragma once - -#include - -#include -#include - -namespace pdb { - -typedef DWORD64 Address; - -inline std::string format_address(Address address) { - std::ostringstream oss; - oss << std::hex << std::showbase << address; - return oss.str(); -} - -inline std::string format_address(void* address) { - return format_address(reinterpret_cast
(address)); -} - -inline bool parse_address(Address& dest, const std::string& src) { - std::istringstream iss{src}; - iss >> std::hex; - char c; - return iss >> dest && !iss.get(c); -} - -} // namespace pdb diff --git a/include/pdb/all.hpp b/include/pdb/all.hpp deleted file mode 100644 index 968e85d..0000000 --- a/include/pdb/all.hpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2017 Egor Tensin -// This file is part of the "winapi-debug" project. -// For details, see https://github.com/egor-tensin/winapi-debug. -// Distributed under the MIT License. - -#pragma once - -#include "address.hpp" -#include "call_stack.hpp" -#include "dbghelp.hpp" -#include "module.hpp" -#include "repo.hpp" -#include "symbol.hpp" diff --git a/include/pdb/call_stack.hpp b/include/pdb/call_stack.hpp deleted file mode 100644 index 30f642c..0000000 --- a/include/pdb/call_stack.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2020 Egor Tensin -// This file is part of the "winapi-debug" project. -// For details, see https://github.com/egor-tensin/winapi-debug. -// Distributed under the MIT License. - -#pragma once - -#include "address.hpp" -#include "dbghelp.hpp" - -#include - -#include -#include -#include -#include -#include - -namespace pdb { - -class CallStack { -public: - static constexpr std::size_t frames_to_skip = 0; - static constexpr std::size_t frames_to_capture = 62; - - // Imposed by CaptureStackBackTrace: - static constexpr std::size_t max_length = 62; - - static_assert(frames_to_skip + frames_to_capture <= max_length, - "Call stack length is too large"); - - static CallStack capture(); - - using AddressCallback = std::function; - bool for_each_address(const AddressCallback& callback) const; - - static std::string pretty_print_address(const DbgHelp& dbghelp, Address addr); - - void dump(std::ostream& os, const DbgHelp&) const; - - const std::array frames; - const std::size_t length; - - const Address* begin() const { return frames.data(); } - const Address* cbegin() const { return begin(); } - const Address* end() const { return begin() + length; } - const Address* cend() const { return end(); } - -private: - CallStack() = default; -}; - -} // namespace pdb diff --git a/include/pdb/dbghelp.hpp b/include/pdb/dbghelp.hpp deleted file mode 100644 index 6965823..0000000 --- a/include/pdb/dbghelp.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2017 Egor Tensin -// This file is part of the "winapi-debug" project. -// For details, see https://github.com/egor-tensin/winapi-debug. -// Distributed under the MIT License. - -#pragma once - -#include "address.hpp" -#include "module.hpp" -#include "symbol.hpp" - -#include - -#include -#include - -namespace pdb { - -class DbgHelp { -public: - static DbgHelp current_process() { return DbgHelp{true}; } - static DbgHelp post_mortem() { return DbgHelp{false}; } - - void swap(DbgHelp& other) noexcept; - - DbgHelp(DbgHelp&& other) noexcept; - DbgHelp& operator=(DbgHelp) noexcept; - ~DbgHelp(); - - ModuleInfo load_pdb(const std::string& path) const; - - typedef std::function OnModule; - void enum_modules(const OnModule&) const; - - ModuleInfo resolve_module(Address) const; - - typedef std::function OnSymbol; - static constexpr auto all_symbols = "*!*"; - void enum_symbols(const ModuleInfo&, const std::string& mask, const OnSymbol&) const; - void enum_symbols(const ModuleInfo&, const OnSymbol&) const; - void enum_symbols(const std::string& mask, const OnSymbol&) const; - void enum_symbols(const OnSymbol&) const; - - SymbolInfo resolve_symbol(Address) const; - SymbolInfo resolve_symbol(const std::string&) const; - - LineInfo resolve_line(Address) const; - -private: - explicit DbgHelp(bool invade_current_process); - - void close(); - - HANDLE id = NULL; - - DbgHelp(const DbgHelp&) = delete; -}; - -inline void swap(DbgHelp& a, DbgHelp& b) noexcept { - a.swap(b); -} - -} // namespace pdb - -namespace std { - -template <> -inline void swap(pdb::DbgHelp& a, pdb::DbgHelp& b) noexcept { - a.swap(b); -} - -} // namespace std diff --git a/include/pdb/module.hpp b/include/pdb/module.hpp deleted file mode 100644 index 5cfa69d..0000000 --- a/include/pdb/module.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2017 Egor Tensin -// This file is part of the "winapi-debug" project. -// For details, see https://github.com/egor-tensin/winapi-debug. -// Distributed under the MIT License. - -#pragma once - -#include "address.hpp" - -#include -#include - -#include - -namespace pdb { - -class ModuleInfo { -public: - typedef IMAGEHLP_MODULEW64 Impl; - - ModuleInfo(); - explicit ModuleInfo(const Impl& impl); - - explicit operator Impl&() { return impl; } - explicit operator const Impl&() const { return impl; } - - Address get_offline_base() const { return impl.BaseOfImage; } - - std::string get_name() const; - -private: - static Impl create_impl(); - - Impl impl; -}; - -class Module : public ModuleInfo { -public: - Module(Address online_base, const ModuleInfo& info) - : ModuleInfo{info}, online_base{online_base} {} - - Address get_online_base() const { return online_base; } - - Address translate_offline_address(Address offline) const; - Address translate_online_address(Address online) const; - -private: - std::string invalid_offline_address(Address offline) const; - std::string invalid_online_address(Address online) const; - - const Address online_base; -}; - -} // namespace pdb diff --git a/include/pdb/repo.hpp b/include/pdb/repo.hpp deleted file mode 100644 index 3b194ff..0000000 --- a/include/pdb/repo.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2017 Egor Tensin -// This file is part of the "winapi-debug" project. -// For details, see https://github.com/egor-tensin/winapi-debug. -// Distributed under the MIT License. - -#pragma once - -#include "address.hpp" -#include "dbghelp.hpp" -#include "module.hpp" -#include "symbol.hpp" - -#include - -#include -#include -#include -#include - -namespace pdb { - -class Repo { -public: - Repo() = default; - - Address add_pdb(Address online_base, const std::string& path); - - typedef std::function OnSymbol; - void enum_symbols(const OnSymbol&) const; - void enum_symbols(Address offline_base, const OnSymbol&) const; - void enum_symbols(const Module&, const OnSymbol&) const; - - Symbol resolve_symbol(Address) const; - Symbol resolve_symbol(const std::string&) const; - - LineInfo resolve_line(Address) const; - - const Module& module_with_online_base(Address) const; - const Module& module_with_offline_base(Address) const; - -private: - Symbol symbol_from_buffer(const SymbolInfo&) const; - static Symbol symbol_from_buffer(const Module&, const SymbolInfo&); - - const Module& module_from_online_address(Address) const; - const Module& module_from_offline_address(Address) const; - - Address address_offline_to_online(Address) const; - Address address_online_to_offline(Address) const; - - const DbgHelp dbghelp{DbgHelp::post_mortem()}; - - std::unordered_set file_ids; - std::map online_bases; - std::map offline_bases; -}; - -} // namespace pdb diff --git a/include/pdb/symbol.hpp b/include/pdb/symbol.hpp deleted file mode 100644 index 47e4fb1..0000000 --- a/include/pdb/symbol.hpp +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2017 Egor Tensin -// This file is part of the "winapi-debug" project. -// For details, see https://github.com/egor-tensin/winapi-debug. -// Distributed under the MIT License. - -#pragma once - -#include "address.hpp" -#include "module.hpp" - -#include -#include - -#include -#include -#include -#include -#include - -namespace pdb { -namespace symbol { - -// MinGW-w64 (as of version 7.0) doesn't have SymTagEnum -typedef ULONG Tag; - -constexpr Tag SYM_TAG_FUNCTION = 5; - -#ifdef _MSC_VER -static_assert(static_cast(SymTagFunction) == SYM_TAG_FUNCTION, - "unexpected SymTagFunction value"); -#endif - -} // namespace symbol - -class SymbolInfo { -public: - typedef SYMBOL_INFOW Impl; - - SymbolInfo(); - explicit SymbolInfo(const Impl& impl); - - explicit operator Impl&() { return get_impl(); } - explicit operator const Impl&() const { return get_impl(); } - - Address get_displacement() const { return displacement; } - void set_displacement(Address new_value) { displacement = new_value; } - - std::string get_name() const; - - Address get_offline_base() const { return get_impl().ModBase; } - Address get_offline_address() const { return get_impl().Address; } - - symbol::Tag get_tag() const { return get_impl().Tag; } - - enum class Type : symbol::Tag { - Function = symbol::SYM_TAG_FUNCTION, - RESERVED = ULONG_MAX, - }; - - Type get_type() const { return static_cast(get_tag()); } - - bool is_function() const { return get_type() == Type::Function; } - -private: - static constexpr std::size_t char_size = sizeof(std::remove_extent::type); - static_assert(char_size == sizeof(wchar_t), "Aren't we using the wide WinAPI?"); - static constexpr std::size_t max_buffer_size = sizeof(Impl) + (MAX_SYM_NAME - 1) * char_size; - - std::array buffer; - Address displacement = 0; - - const Impl& get_impl() const { return *reinterpret_cast(buffer.data()); } - Impl& get_impl() { return *reinterpret_cast(buffer.data()); } -}; - -class Symbol : public SymbolInfo { -public: - Symbol(Address online_address, const SymbolInfo& info) - : SymbolInfo{info}, online_address{online_address} {} - - Address get_online_address() const { return online_address; } - -private: - const Address online_address; -}; - -class LineInfo { -public: - typedef IMAGEHLP_LINEW64 Impl; - - explicit LineInfo(const Impl& impl); - - const std::string file_path; - const unsigned long line_number; -}; - -} // namespace pdb diff --git a/include/winapi/debug.hpp b/include/winapi/debug.hpp new file mode 100644 index 0000000..dc42557 --- /dev/null +++ b/include/winapi/debug.hpp @@ -0,0 +1,13 @@ +// Copyright (c) 2017 Egor Tensin +// This file is part of the "winapi-debug" project. +// For details, see https://github.com/egor-tensin/winapi-debug. +// Distributed under the MIT License. + +#pragma once + +#include "debug/address.hpp" +#include "debug/call_stack.hpp" +#include "debug/dbghelp.hpp" +#include "debug/module.hpp" +#include "debug/repo.hpp" +#include "debug/symbol.hpp" diff --git a/include/winapi/debug/address.hpp b/include/winapi/debug/address.hpp new file mode 100644 index 0000000..3d7acd6 --- /dev/null +++ b/include/winapi/debug/address.hpp @@ -0,0 +1,34 @@ +// Copyright (c) 2017 Egor Tensin +// This file is part of the "winapi-debug" project. +// For details, see https://github.com/egor-tensin/winapi-debug. +// Distributed under the MIT License. + +#pragma once + +#include + +#include +#include + +namespace pdb { + +typedef DWORD64 Address; + +inline std::string format_address(Address address) { + std::ostringstream oss; + oss << std::hex << std::showbase << address; + return oss.str(); +} + +inline std::string format_address(void* address) { + return format_address(reinterpret_cast
(address)); +} + +inline bool parse_address(Address& dest, const std::string& src) { + std::istringstream iss{src}; + iss >> std::hex; + char c; + return iss >> dest && !iss.get(c); +} + +} // namespace pdb diff --git a/include/winapi/debug/call_stack.hpp b/include/winapi/debug/call_stack.hpp new file mode 100644 index 0000000..30f642c --- /dev/null +++ b/include/winapi/debug/call_stack.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2020 Egor Tensin +// This file is part of the "winapi-debug" project. +// For details, see https://github.com/egor-tensin/winapi-debug. +// Distributed under the MIT License. + +#pragma once + +#include "address.hpp" +#include "dbghelp.hpp" + +#include + +#include +#include +#include +#include +#include + +namespace pdb { + +class CallStack { +public: + static constexpr std::size_t frames_to_skip = 0; + static constexpr std::size_t frames_to_capture = 62; + + // Imposed by CaptureStackBackTrace: + static constexpr std::size_t max_length = 62; + + static_assert(frames_to_skip + frames_to_capture <= max_length, + "Call stack length is too large"); + + static CallStack capture(); + + using AddressCallback = std::function; + bool for_each_address(const AddressCallback& callback) const; + + static std::string pretty_print_address(const DbgHelp& dbghelp, Address addr); + + void dump(std::ostream& os, const DbgHelp&) const; + + const std::array frames; + const std::size_t length; + + const Address* begin() const { return frames.data(); } + const Address* cbegin() const { return begin(); } + const Address* end() const { return begin() + length; } + const Address* cend() const { return end(); } + +private: + CallStack() = default; +}; + +} // namespace pdb diff --git a/include/winapi/debug/dbghelp.hpp b/include/winapi/debug/dbghelp.hpp new file mode 100644 index 0000000..6965823 --- /dev/null +++ b/include/winapi/debug/dbghelp.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2017 Egor Tensin +// This file is part of the "winapi-debug" project. +// For details, see https://github.com/egor-tensin/winapi-debug. +// Distributed under the MIT License. + +#pragma once + +#include "address.hpp" +#include "module.hpp" +#include "symbol.hpp" + +#include + +#include +#include + +namespace pdb { + +class DbgHelp { +public: + static DbgHelp current_process() { return DbgHelp{true}; } + static DbgHelp post_mortem() { return DbgHelp{false}; } + + void swap(DbgHelp& other) noexcept; + + DbgHelp(DbgHelp&& other) noexcept; + DbgHelp& operator=(DbgHelp) noexcept; + ~DbgHelp(); + + ModuleInfo load_pdb(const std::string& path) const; + + typedef std::function OnModule; + void enum_modules(const OnModule&) const; + + ModuleInfo resolve_module(Address) const; + + typedef std::function OnSymbol; + static constexpr auto all_symbols = "*!*"; + void enum_symbols(const ModuleInfo&, const std::string& mask, const OnSymbol&) const; + void enum_symbols(const ModuleInfo&, const OnSymbol&) const; + void enum_symbols(const std::string& mask, const OnSymbol&) const; + void enum_symbols(const OnSymbol&) const; + + SymbolInfo resolve_symbol(Address) const; + SymbolInfo resolve_symbol(const std::string&) const; + + LineInfo resolve_line(Address) const; + +private: + explicit DbgHelp(bool invade_current_process); + + void close(); + + HANDLE id = NULL; + + DbgHelp(const DbgHelp&) = delete; +}; + +inline void swap(DbgHelp& a, DbgHelp& b) noexcept { + a.swap(b); +} + +} // namespace pdb + +namespace std { + +template <> +inline void swap(pdb::DbgHelp& a, pdb::DbgHelp& b) noexcept { + a.swap(b); +} + +} // namespace std diff --git a/include/winapi/debug/module.hpp b/include/winapi/debug/module.hpp new file mode 100644 index 0000000..5cfa69d --- /dev/null +++ b/include/winapi/debug/module.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2017 Egor Tensin +// This file is part of the "winapi-debug" project. +// For details, see https://github.com/egor-tensin/winapi-debug. +// Distributed under the MIT License. + +#pragma once + +#include "address.hpp" + +#include +#include + +#include + +namespace pdb { + +class ModuleInfo { +public: + typedef IMAGEHLP_MODULEW64 Impl; + + ModuleInfo(); + explicit ModuleInfo(const Impl& impl); + + explicit operator Impl&() { return impl; } + explicit operator const Impl&() const { return impl; } + + Address get_offline_base() const { return impl.BaseOfImage; } + + std::string get_name() const; + +private: + static Impl create_impl(); + + Impl impl; +}; + +class Module : public ModuleInfo { +public: + Module(Address online_base, const ModuleInfo& info) + : ModuleInfo{info}, online_base{online_base} {} + + Address get_online_base() const { return online_base; } + + Address translate_offline_address(Address offline) const; + Address translate_online_address(Address online) const; + +private: + std::string invalid_offline_address(Address offline) const; + std::string invalid_online_address(Address online) const; + + const Address online_base; +}; + +} // namespace pdb diff --git a/include/winapi/debug/repo.hpp b/include/winapi/debug/repo.hpp new file mode 100644 index 0000000..3b194ff --- /dev/null +++ b/include/winapi/debug/repo.hpp @@ -0,0 +1,58 @@ +// Copyright (c) 2017 Egor Tensin +// This file is part of the "winapi-debug" project. +// For details, see https://github.com/egor-tensin/winapi-debug. +// Distributed under the MIT License. + +#pragma once + +#include "address.hpp" +#include "dbghelp.hpp" +#include "module.hpp" +#include "symbol.hpp" + +#include + +#include +#include +#include +#include + +namespace pdb { + +class Repo { +public: + Repo() = default; + + Address add_pdb(Address online_base, const std::string& path); + + typedef std::function OnSymbol; + void enum_symbols(const OnSymbol&) const; + void enum_symbols(Address offline_base, const OnSymbol&) const; + void enum_symbols(const Module&, const OnSymbol&) const; + + Symbol resolve_symbol(Address) const; + Symbol resolve_symbol(const std::string&) const; + + LineInfo resolve_line(Address) const; + + const Module& module_with_online_base(Address) const; + const Module& module_with_offline_base(Address) const; + +private: + Symbol symbol_from_buffer(const SymbolInfo&) const; + static Symbol symbol_from_buffer(const Module&, const SymbolInfo&); + + const Module& module_from_online_address(Address) const; + const Module& module_from_offline_address(Address) const; + + Address address_offline_to_online(Address) const; + Address address_online_to_offline(Address) const; + + const DbgHelp dbghelp{DbgHelp::post_mortem()}; + + std::unordered_set file_ids; + std::map online_bases; + std::map offline_bases; +}; + +} // namespace pdb diff --git a/include/winapi/debug/symbol.hpp b/include/winapi/debug/symbol.hpp new file mode 100644 index 0000000..47e4fb1 --- /dev/null +++ b/include/winapi/debug/symbol.hpp @@ -0,0 +1,97 @@ +// Copyright (c) 2017 Egor Tensin +// This file is part of the "winapi-debug" project. +// For details, see https://github.com/egor-tensin/winapi-debug. +// Distributed under the MIT License. + +#pragma once + +#include "address.hpp" +#include "module.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +namespace pdb { +namespace symbol { + +// MinGW-w64 (as of version 7.0) doesn't have SymTagEnum +typedef ULONG Tag; + +constexpr Tag SYM_TAG_FUNCTION = 5; + +#ifdef _MSC_VER +static_assert(static_cast(SymTagFunction) == SYM_TAG_FUNCTION, + "unexpected SymTagFunction value"); +#endif + +} // namespace symbol + +class SymbolInfo { +public: + typedef SYMBOL_INFOW Impl; + + SymbolInfo(); + explicit SymbolInfo(const Impl& impl); + + explicit operator Impl&() { return get_impl(); } + explicit operator const Impl&() const { return get_impl(); } + + Address get_displacement() const { return displacement; } + void set_displacement(Address new_value) { displacement = new_value; } + + std::string get_name() const; + + Address get_offline_base() const { return get_impl().ModBase; } + Address get_offline_address() const { return get_impl().Address; } + + symbol::Tag get_tag() const { return get_impl().Tag; } + + enum class Type : symbol::Tag { + Function = symbol::SYM_TAG_FUNCTION, + RESERVED = ULONG_MAX, + }; + + Type get_type() const { return static_cast(get_tag()); } + + bool is_function() const { return get_type() == Type::Function; } + +private: + static constexpr std::size_t char_size = sizeof(std::remove_extent::type); + static_assert(char_size == sizeof(wchar_t), "Aren't we using the wide WinAPI?"); + static constexpr std::size_t max_buffer_size = sizeof(Impl) + (MAX_SYM_NAME - 1) * char_size; + + std::array buffer; + Address displacement = 0; + + const Impl& get_impl() const { return *reinterpret_cast(buffer.data()); } + Impl& get_impl() { return *reinterpret_cast(buffer.data()); } +}; + +class Symbol : public SymbolInfo { +public: + Symbol(Address online_address, const SymbolInfo& info) + : SymbolInfo{info}, online_address{online_address} {} + + Address get_online_address() const { return online_address; } + +private: + const Address online_address; +}; + +class LineInfo { +public: + typedef IMAGEHLP_LINEW64 Impl; + + explicit LineInfo(const Impl& impl); + + const std::string file_path; + const unsigned long line_number; +}; + +} // namespace pdb -- cgit v1.2.3