diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2020-03-24 01:34:52 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2020-03-24 02:06:22 +0300 |
commit | c073ed8f702e98ec56ed05e0c02167e355e6ee31 (patch) | |
tree | f726a5830ed4f47724ac6c447571398ef5b12ea2 | |
parent | add Process class (diff) | |
download | winapi-debug-c073ed8f702e98ec56ed05e0c02167e355e6ee31.tar.gz winapi-debug-c073ed8f702e98ec56ed05e0c02167e355e6ee31.zip |
switch to Boost.Nowide everywhere
-rw-r--r-- | include/pdb/module.hpp | 4 | ||||
-rw-r--r-- | include/pdb/symbol.hpp | 8 | ||||
-rw-r--r-- | src/dbghelp.cpp | 29 | ||||
-rw-r--r-- | src/error.cpp | 20 | ||||
-rw-r--r-- | src/module.cpp | 6 | ||||
-rw-r--r-- | src/symbol.cpp | 10 | ||||
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/call_stack.cpp | 13 | ||||
-rw-r--r-- | utils/CMakeLists.txt | 2 | ||||
-rw-r--r-- | utils/addr2name.cpp | 11 | ||||
-rw-r--r-- | utils/command_line.hpp | 28 | ||||
-rw-r--r-- | utils/enum_symbols.cpp | 9 | ||||
-rw-r--r-- | utils/name2addr.cpp | 11 |
13 files changed, 96 insertions, 56 deletions
diff --git a/include/pdb/module.hpp b/include/pdb/module.hpp index 1a5b227..81312b9 100644 --- a/include/pdb/module.hpp +++ b/include/pdb/module.hpp @@ -16,7 +16,7 @@ namespace pdb { class ModuleInfo { public: - typedef IMAGEHLP_MODULE64 Impl; + typedef IMAGEHLP_MODULEW64 Impl; ModuleInfo(); explicit ModuleInfo(const Impl& impl); @@ -26,7 +26,7 @@ public: Address get_offline_base() const { return impl.BaseOfImage; } - std::string get_name() const { return impl.ModuleName; } + std::string get_name() const; private: static Impl create_impl(); diff --git a/include/pdb/symbol.hpp b/include/pdb/symbol.hpp index 25e997b..6a62e22 100644 --- a/include/pdb/symbol.hpp +++ b/include/pdb/symbol.hpp @@ -8,8 +8,6 @@ #include "address.hpp" #include "module.hpp" -#include <SafeInt.hpp> - #include <dbghelp.h> #include <windows.h> @@ -35,7 +33,7 @@ static_assert(static_cast<Tag>(SymTagFunction) == SYM_TAG_FUNCTION, class SymbolInfo { public: - typedef SYMBOL_INFO Impl; + typedef SYMBOL_INFOW Impl; SymbolInfo(); explicit SymbolInfo(const Impl& impl); @@ -46,7 +44,7 @@ public: Address get_displacement() const { return displacement; } void set_displacement(Address new_value) { displacement = new_value; } - std::string get_name() const { return {get_impl().Name, get_impl().NameLen}; } + std::string get_name() const; Address get_offline_base() const { return get_impl().ModBase; } Address get_offline_address() const { return get_impl().Address; } @@ -85,7 +83,7 @@ private: class LineInfo { public: - typedef IMAGEHLP_LINE64 Impl; + typedef IMAGEHLP_LINEW64 Impl; explicit LineInfo(const Impl& impl); diff --git a/src/dbghelp.cpp b/src/dbghelp.cpp index cb71282..5b66914 100644 --- a/src/dbghelp.cpp +++ b/src/dbghelp.cpp @@ -5,6 +5,8 @@ #include "pdb/all.hpp" +#include <boost/nowide/convert.hpp> + #include <SafeInt.hpp> #include <dbghelp.h> @@ -48,7 +50,7 @@ Address gen_next_offline_base(std::size_t pdb_size) { ModuleInfo get_module_info(HANDLE id, Address offline_base) { ModuleInfo info; - if (!SymGetModuleInfo64(id, offline_base, &static_cast<ModuleInfo::Impl&>(info))) + if (!SymGetModuleInfoW64(id, offline_base, &static_cast<ModuleInfo::Impl&>(info))) throw error::windows(GetLastError()); return info; @@ -59,14 +61,14 @@ struct ModuleEnumerator { DbgHelp::OnModule callback; }; -BOOL CALLBACK enum_modules_callback(PCSTR, DWORD64 offline_base, PVOID raw_enumerator_ptr) { +BOOL CALLBACK enum_modules_callback(PCWSTR, DWORD64 offline_base, PVOID raw_enumerator_ptr) { const auto enumerator_ptr = reinterpret_cast<ModuleEnumerator*>(raw_enumerator_ptr); const auto& enumerator = *enumerator_ptr; enumerator.callback(get_module_info(enumerator.id, offline_base)); return TRUE; } -BOOL CALLBACK enum_symbols_callback(SYMBOL_INFO* info, ULONG, VOID* raw_callback_ptr) { +BOOL CALLBACK enum_symbols_callback(SYMBOL_INFOW* 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}); @@ -77,11 +79,11 @@ void enum_symbols(HANDLE id, Address module_base, const std::string& mask, const DbgHelp::OnSymbol& callback) { - if (!SymEnumSymbols(id, - module_base, - mask.c_str(), - &enum_symbols_callback, - const_cast<DbgHelp::OnSymbol*>(&callback))) + if (!SymEnumSymbolsW(id, + module_base, + boost::nowide::widen(mask).c_str(), + &enum_symbols_callback, + const_cast<DbgHelp::OnSymbol*>(&callback))) throw error::windows(GetLastError()); } @@ -128,6 +130,7 @@ ModuleInfo DbgHelp::load_pdb(const std::string& path) const { _path.assign(path.cbegin(), path.cend()); _path.emplace_back('\0'); + // TODO: switch to the W version? const auto offline_base = SymLoadModule64(id, NULL, _path.data(), NULL, gen_next_offline_base(size), size); @@ -139,7 +142,7 @@ ModuleInfo DbgHelp::load_pdb(const std::string& path) const { void DbgHelp::enum_modules(const OnModule& callback) const { ModuleEnumerator enumerator{id, callback}; - if (!SymEnumerateModules64(id, &enum_modules_callback, &enumerator)) + if (!SymEnumerateModulesW64(id, &enum_modules_callback, &enumerator)) throw error::windows(GetLastError()); } @@ -169,7 +172,7 @@ SymbolInfo DbgHelp::resolve_symbol(Address offline) const { Address displacement = 0; SymbolInfo symbol; - if (!SymFromAddr(id, offline, &displacement, &static_cast<SYMBOL_INFO&>(symbol))) + if (!SymFromAddrW(id, offline, &displacement, &static_cast<SYMBOL_INFOW&>(symbol))) throw error::windows(GetLastError()); symbol.set_displacement(displacement); @@ -179,20 +182,20 @@ SymbolInfo DbgHelp::resolve_symbol(Address offline) const { SymbolInfo DbgHelp::resolve_symbol(const std::string& name) const { SymbolInfo symbol; - if (!SymFromName(id, name.c_str(), &static_cast<SYMBOL_INFO&>(symbol))) + if (!SymFromNameW(id, boost::nowide::widen(name).c_str(), &static_cast<SYMBOL_INFOW&>(symbol))) throw error::windows(GetLastError()); return symbol; } LineInfo DbgHelp::resolve_line(Address offline) const { - IMAGEHLP_LINE64 impl; + IMAGEHLP_LINEW64 impl; std::memset(&impl, 0, sizeof(impl)); impl.SizeOfStruct = sizeof(impl); DWORD displacement = 0; - if (!SymGetLineFromAddr64(id, offline, &displacement, &impl)) + if (!SymGetLineFromAddrW64(id, offline, &displacement, &impl)) throw error::windows(GetLastError()); return LineInfo{impl}; diff --git a/src/error.cpp b/src/error.cpp index 16512b3..d305e88 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -5,6 +5,8 @@ #include "pdb/all.hpp" +#include <boost/nowide/convert.hpp> + #include <windows.h> #include <string> @@ -13,9 +15,9 @@ namespace pdb { namespace error { namespace { -std::string trim_trailing_newline(const std::string& s) { - const auto last_pos = s.find_last_not_of("\r\n"); - if (std::string::npos == last_pos) +std::wstring trim_trailing_newline(const std::wstring& s) { + const auto last_pos = s.find_last_not_of(L"\r\n"); + if (std::wstring::npos == last_pos) return {}; return s.substr(0, last_pos + 1); } @@ -23,25 +25,25 @@ std::string trim_trailing_newline(const std::string& s) { } // namespace std::string CategoryWindows::message(int code) const { - char* buf; + wchar_t* buf; - const auto nbwritten = FormatMessageA( + const auto len = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast<char*>(&buf), + reinterpret_cast<wchar_t*>(&buf), 0, NULL); - if (0 == nbwritten) { + if (0 == len) { LocalFree(buf); return "Couldn't format the error message"; } - std::string msg{buf, nbwritten}; + std::wstring msg{buf, len}; LocalFree(buf); - return trim_trailing_newline(msg); + return boost::nowide::narrow(trim_trailing_newline(msg)); } } // namespace error diff --git a/src/module.cpp b/src/module.cpp index 6ee0c08..f4f3eb9 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -5,6 +5,8 @@ #include "pdb/all.hpp" +#include <boost/nowide/convert.hpp> + #include <SafeInt.hpp> #include <cstring> @@ -28,6 +30,10 @@ ModuleInfo::Impl ModuleInfo::create_impl() { return impl; } +std::string ModuleInfo::get_name() const { + return boost::nowide::narrow(impl.ModuleName); +} + Address Module::translate_offline_address(Address offline) const { if (offline < get_offline_base()) throw std::range_error{invalid_offline_address(offline)}; diff --git a/src/symbol.cpp b/src/symbol.cpp index e679f4a..1973f0b 100644 --- a/src/symbol.cpp +++ b/src/symbol.cpp @@ -5,6 +5,8 @@ #include "pdb/all.hpp" +#include <boost/nowide/convert.hpp> + #include <SafeInt.hpp> #include <dbghelp.h> @@ -13,6 +15,7 @@ #include <cstddef> #include <cstring> #include <stdexcept> +#include <string> namespace pdb { namespace { @@ -51,7 +54,12 @@ SymbolInfo::SymbolInfo(const Impl& impl) : SymbolInfo{} { std::memcpy(buffer.data(), &impl, impl_size); } +std::string SymbolInfo::get_name() const { + return boost::nowide::narrow(std::wstring{get_impl().Name, get_impl().NameLen}); +} + LineInfo::LineInfo(const Impl& impl) - : file_path{impl.FileName}, line_number{cast_line_number(impl.LineNumber)} {} + : file_path{boost::nowide::narrow(impl.FileName)}, + line_number{cast_line_number(impl.LineNumber)} {} } // namespace pdb diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4574211..ac3e8b3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,6 @@ add_executable(call_stack call_stack.cpp) target_link_libraries(call_stack PRIVATE pdb_repo) +target_link_libraries(call_stack PRIVATE Boost::nowide) install(TARGETS call_stack RUNTIME DESTINATION bin) if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") diff --git a/test/call_stack.cpp b/test/call_stack.cpp index 1f6ce37..8eb3198 100644 --- a/test/call_stack.cpp +++ b/test/call_stack.cpp @@ -1,28 +1,29 @@ #include "pdb/all.hpp" +#include <boost/nowide/iostream.hpp> + #include <exception> -#include <iostream> namespace test { void call_stack() { const auto dbghelp = pdb::DbgHelp::current_process(); const auto call_stack = pdb::CallStack::capture(); - call_stack.dump(std::cout, dbghelp); + call_stack.dump(boost::nowide::cout, dbghelp); } void __declspec(noinline) baz() { - std::cout << "baz\n"; + boost::nowide::cout << "baz\n"; call_stack(); } void __declspec(noinline) bar() { - std::cout << "bar\n"; + boost::nowide::cout << "bar\n"; baz(); } void __declspec(noinline) foo() { - std::cout << "foo\n"; + boost::nowide::cout << "foo\n"; bar(); } @@ -32,7 +33,7 @@ int main() { try { test::foo(); } catch (const std::exception& e) { - std::cerr << e.what() << '\n'; + boost::nowide::cerr << e.what() << '\n'; return 1; } return 0; diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index ee5c5ba..a34d72a 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -3,7 +3,7 @@ find_package(Boost REQUIRED COMPONENTS filesystem program_options) function(add_util name src) add_executable("${name}" ${src}) target_link_libraries("${name}" PRIVATE pdb_repo) - target_link_libraries("${name}" PRIVATE Boost::filesystem Boost::program_options) + target_link_libraries("${name}" PRIVATE Boost::filesystem Boost::nowide Boost::program_options) install(TARGETS "${name}" RUNTIME DESTINATION bin) if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") install(FILES "$<TARGET_PDB_FILE:${name}>" DESTINATION bin OPTIONAL) diff --git a/utils/addr2name.cpp b/utils/addr2name.cpp index bac508e..710a2ff 100644 --- a/utils/addr2name.cpp +++ b/utils/addr2name.cpp @@ -7,6 +7,7 @@ #include "pdb/all.hpp" #include "pdb_descr.hpp" +#include <boost/nowide/iostream.hpp> #include <boost/program_options.hpp> #include <exception> @@ -19,7 +20,7 @@ namespace { class Addr2Name : public SettingsParser { public: - explicit Addr2Name(const std::string& argv0) : SettingsParser{argv0} { + explicit Addr2Name(int argc, char** argv) : SettingsParser{argc, argv} { namespace po = boost::program_options; visible.add_options()( @@ -57,7 +58,7 @@ std::string format_line_info(const pdb::LineInfo& line_info) { } void dump_error(const std::exception& e) { - std::cerr << "error: " << e.what() << '\n'; + boost::nowide::cerr << "error: " << e.what() << '\n'; } void resolve_symbol(const pdb::Repo& repo, pdb::Address address, bool lines = false) { @@ -77,10 +78,10 @@ void resolve_symbol(const pdb::Repo& repo, pdb::Address address, bool lines = fa } } - std::cout << msg.str() << '\n'; + boost::nowide::cout << msg.str() << '\n'; } catch (const std::exception& e) { dump_error(e); - std::cout << pdb::format_address(address) << '\n'; + boost::nowide::cout << pdb::format_address(address) << '\n'; } } @@ -88,7 +89,7 @@ void resolve_symbol(const pdb::Repo& repo, pdb::Address address, bool lines = fa int main(int argc, char* argv[]) { try { - Addr2Name settings{argv[0]}; + Addr2Name settings{argc, argv}; try { settings.parse(argc, argv); diff --git a/utils/command_line.hpp b/utils/command_line.hpp index f99c3c1..9fe6b98 100644 --- a/utils/command_line.hpp +++ b/utils/command_line.hpp @@ -6,6 +6,9 @@ #pragma once #include <boost/filesystem.hpp> +#include <boost/nowide/args.hpp> +#include <boost/nowide/filesystem.hpp> +#include <boost/nowide/iostream.hpp> #include <boost/program_options.hpp> #include <exception> @@ -13,9 +16,23 @@ #include <ostream> #include <string> +class Args { +public: + Args(int argc, char** argv) : argc{argc}, argv{argv}, impl{this->argc, this->argv} { + boost::nowide::nowide_filesystem(); + } + + int argc; + char** argv; + +private: + const boost::nowide::args impl; +}; + class SettingsParser { public: - explicit SettingsParser(const std::string& argv0) : prog_name{extract_filename(argv0)} { + explicit SettingsParser(int argc, char** argv) + : args{argc, argv}, prog_name{extract_filename(args.argv[0])} { visible.add_options()("help,h", "show this message and exit"); } @@ -40,11 +57,11 @@ public: bool exit_with_usage = false; - void usage() const { std::cout << *this; } + void usage() const { boost::nowide::cout << *this; } void usage_error(const std::exception& e) const { - std::cerr << "usage error: " << e.what() << '\n'; - std::cerr << *this; + boost::nowide::cerr << "usage error: " << e.what() << '\n'; + boost::nowide::cerr << *this; } protected: @@ -53,10 +70,11 @@ protected: boost::program_options::positional_options_description positional; private: - static std::string extract_filename(const std::string& path) { + static std::string extract_filename(char* path) { return boost::filesystem::path{path}.filename().string(); } + const Args args; const std::string prog_name; friend std::ostream& operator<<(std::ostream& os, const SettingsParser& parser) { diff --git a/utils/enum_symbols.cpp b/utils/enum_symbols.cpp index 123c9d1..49dbfed 100644 --- a/utils/enum_symbols.cpp +++ b/utils/enum_symbols.cpp @@ -6,6 +6,7 @@ #include "command_line.hpp" #include "pdb/all.hpp" +#include <boost/nowide/iostream.hpp> #include <boost/program_options.hpp> #include <exception> @@ -17,7 +18,7 @@ namespace { class EnumSymbols : public SettingsParser { public: - explicit EnumSymbols(const std::string& argv0) : SettingsParser{argv0} { + explicit EnumSymbols(int argc, char** argv) : SettingsParser{argc, argv} { namespace po = boost::program_options; visible.add_options()("pdb", @@ -58,7 +59,7 @@ constexpr pdb::symbol::Tag EnumSymbols::function_tag; int main(int argc, char* argv[]) { try { - EnumSymbols settings{argv[0]}; + EnumSymbols settings{argc, argv}; try { settings.parse(argc, argv); @@ -79,11 +80,11 @@ int main(int argc, char* argv[]) { dbghelp.enum_symbols(id, settings.get_mask(), [&](const pdb::SymbolInfo& symbol) { if (!settings.type_specified() || settings.get_type() == symbol.get_type()) - std::cout << symbol.get_name() << '\n'; + boost::nowide::cout << symbol.get_name() << '\n'; }); } } catch (const std::exception& e) { - std::cerr << "error: " << e.what() << '\n'; + boost::nowide::cerr << "error: " << e.what() << '\n'; return 1; } return 0; diff --git a/utils/name2addr.cpp b/utils/name2addr.cpp index aeaa13a..4b83757 100644 --- a/utils/name2addr.cpp +++ b/utils/name2addr.cpp @@ -7,6 +7,7 @@ #include "pdb/all.hpp" #include "pdb_descr.hpp" +#include <boost/nowide/iostream.hpp> #include <boost/program_options.hpp> #include <exception> @@ -18,7 +19,7 @@ namespace { class Name2Addr : public SettingsParser { public: - explicit Name2Addr(const std::string& argv0) : SettingsParser{argv0} { + explicit Name2Addr(int argc, char** argv) : SettingsParser{argc, argv} { namespace po = boost::program_options; visible.add_options()( @@ -38,16 +39,16 @@ public: }; void dump_error(const std::exception& e) { - std::cerr << "error: " << e.what() << '\n'; + boost::nowide::cerr << "error: " << e.what() << '\n'; } void resolve_symbol(const pdb::Repo& repo, const std::string& name) { try { const auto address = repo.resolve_symbol(name).get_online_address(); - std::cout << pdb::format_address(address) << '\n'; + boost::nowide::cout << pdb::format_address(address) << '\n'; } catch (const std::exception& e) { dump_error(e); - std::cout << name << '\n'; + boost::nowide::cout << name << '\n'; } } @@ -55,7 +56,7 @@ void resolve_symbol(const pdb::Repo& repo, const std::string& name) { int main(int argc, char* argv[]) { try { - Name2Addr settings{argv[0]}; + Name2Addr settings{argc, argv}; try { settings.parse(argc, argv); |