aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--include/pdb/dbghelp.hpp2
-rw-r--r--include/pdb/repo.hpp2
-rw-r--r--include/pdb/symbol.hpp25
-rw-r--r--src/dbghelp.cpp32
-rw-r--r--src/repo.cpp5
-rw-r--r--utils/addr2name.cpp36
6 files changed, 93 insertions, 9 deletions
diff --git a/include/pdb/dbghelp.hpp b/include/pdb/dbghelp.hpp
index d6b6899..2555de1 100644
--- a/include/pdb/dbghelp.hpp
+++ b/include/pdb/dbghelp.hpp
@@ -32,6 +32,8 @@ namespace pdb
SymbolInfo resolve_symbol(Address) const;
SymbolInfo resolve_symbol(const std::string&) const;
+ LineInfo resolve_line(Address) const;
+
private:
ModuleInfo get_module_info(Address offline_base) const;
diff --git a/include/pdb/repo.hpp b/include/pdb/repo.hpp
index dd41b17..c8a2964 100644
--- a/include/pdb/repo.hpp
+++ b/include/pdb/repo.hpp
@@ -33,6 +33,8 @@ namespace pdb
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;
diff --git a/include/pdb/symbol.hpp b/include/pdb/symbol.hpp
index fc200c7..81a40e3 100644
--- a/include/pdb/symbol.hpp
+++ b/include/pdb/symbol.hpp
@@ -111,4 +111,29 @@ namespace pdb
private:
const Address online_address;
};
+
+ class LineInfo
+ {
+ public:
+ typedef IMAGEHLP_LINE64 Raw;
+
+ explicit LineInfo(const Raw& raw)
+ : file_path{raw.FileName}
+ , line_number{cast_line_number(raw.LineNumber)}
+ { }
+
+ const std::string file_path;
+ const unsigned long line_number;
+
+ private:
+ static unsigned long cast_line_number(DWORD raw)
+ {
+ unsigned long dest = 0;
+
+ if (!msl::utilities::SafeCast(raw, dest))
+ throw std::runtime_error{"invalid line number"};
+
+ return dest;
+ }
+ };
}
diff --git a/src/dbghelp.cpp b/src/dbghelp.cpp
index 30829d4..0a78e4d 100644
--- a/src/dbghelp.cpp
+++ b/src/dbghelp.cpp
@@ -11,6 +11,7 @@
#include <DbgHelp.h>
#include <cstddef>
+#include <cstring>
#include <stdexcept>
#include <string>
@@ -19,14 +20,17 @@ namespace pdb
{
namespace
{
- void enable_debug_output()
+ void set_dbghelp_options()
{
- SymSetOptions(SymGetOptions() | SYMOPT_DEBUG | SYMOPT_UNDNAME);
+ SymSetOptions(SymGetOptions()
+ | SYMOPT_DEBUG
+ | SYMOPT_LOAD_LINES
+ | SYMOPT_UNDNAME);
}
void initialize(HANDLE id)
{
- enable_debug_output();
+ set_dbghelp_options();
if (!SymInitialize(id, NULL, FALSE))
throw error::windows(GetLastError());
@@ -129,14 +133,14 @@ namespace pdb
throw error::windows(GetLastError());
}
- SymbolInfo DbgHelp::resolve_symbol(Address online) const
+ SymbolInfo DbgHelp::resolve_symbol(Address offline) const
{
Address displacement = 0;
SymbolInfo symbol;
if (!SymFromAddr(
id,
- online,
+ offline,
&displacement,
&static_cast<SYMBOL_INFO&>(symbol)))
throw error::windows(GetLastError());
@@ -157,4 +161,22 @@ namespace pdb
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};
+ }
}
diff --git a/src/repo.cpp b/src/repo.cpp
index edd62d5..7a19c83 100644
--- a/src/repo.cpp
+++ b/src/repo.cpp
@@ -155,6 +155,11 @@ namespace pdb
return symbol_from_buffer(dbghelp.resolve_symbol(name));
}
+ LineInfo Repo::resolve_line(Address online) const
+ {
+ return dbghelp.resolve_line(address_online_to_offline(online));
+ }
+
const Module& Repo::module_with_online_base(Address base) const
{
return lookup_module(online_bases, base);
diff --git a/utils/addr2name.cpp b/utils/addr2name.cpp
index d611bac..b2f0a51 100644
--- a/utils/addr2name.cpp
+++ b/utils/addr2name.cpp
@@ -34,6 +34,7 @@ namespace
std::vector<PDB> pdbs;
std::vector<pdb::Address> addresses;
+ bool lines = false;
private:
Options build_options()
@@ -51,7 +52,10 @@ namespace
("address",
program_options::value<std::vector<pdb::Address>>(&addresses)
->value_name("ADDR"),
- "add an address to resolve");
+ "add an address to resolve")
+ ("lines,l",
+ program_options::bool_switch(&lines),
+ "try to resolve source files & line numbers");
return descr;
}
@@ -75,18 +79,42 @@ namespace
return oss.str();
}
+ std::string format_line_info(const pdb::LineInfo& line_info)
+ {
+ std::ostringstream oss;
+ oss << '[' << line_info.file_path << " @ " << line_info.line_number << ']';
+ return oss.str();
+ }
+
void dump_error(const std::exception& e)
{
std::cerr << "error: " << e.what() << '\n';
}
- void resolve_symbol(const pdb::Repo& repo, pdb::Address address)
+ void resolve_symbol(const pdb::Repo& repo, pdb::Address address, bool lines = false)
{
try
{
const auto symbol = repo.resolve_symbol(address);
const auto& module = repo.module_with_offline_base(symbol.get_offline_base());
- std::cout << format_symbol(module, symbol) << '\n';
+
+ std::ostringstream msg;
+ msg << format_symbol(module, symbol);
+
+ if (lines)
+ {
+ try
+ {
+ const auto line_info = repo.resolve_line(address);
+ msg << ' ' << format_line_info(line_info);
+ }
+ catch (const std::exception& e)
+ {
+ dump_error(e);
+ }
+ }
+
+ std::cout << msg.str() << '\n';
}
catch (const std::exception& e)
{
@@ -124,7 +152,7 @@ int main(int argc, char* argv[])
repo.add_pdb(pdb.online_base, pdb.path);
for (const auto& address : settings.addresses)
- resolve_symbol(repo, address);
+ resolve_symbol(repo, address, settings.lines);
}
catch (const std::exception& e)
{