Skip to content
This repository was archived by the owner on Jun 30, 2025. It is now read-only.

Commit d65d2a4

Browse files
committed
feat(dbghelp): show source line number if present
1 parent c469cc2 commit d65d2a4

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

bazel/glog.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ def glog_library(with_gflags = 1, **kwargs):
210210
"@bazel_tools//src/conditions:windows": [":strip_include_prefix_hack"],
211211
"//conditions:default": [],
212212
}),
213+
linkopts = select({
214+
"@bazel_tools//src/conditions:windows": ["dbghelp.lib"],
215+
"//conditions:default": [],
216+
}),
213217
**kwargs
214218
)
215219

src/symbolize.cc

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -854,24 +854,19 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
854854
# include <dbghelp.h>
855855
# include <windows.h>
856856

857-
# ifdef _MSC_VER
858-
# pragma comment(lib, "dbghelp")
859-
# endif
860-
861857
namespace google {
862858

863-
class SymInitializer {
859+
class SymInitializer final {
864860
public:
865861
HANDLE process;
866862
bool ready;
867-
SymInitializer() : process(nullptr), ready(false) {
863+
SymInitializer() : process(GetCurrentProcess()), ready(false) {
868864
// Initialize the symbol handler.
869865
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx
870-
process = GetCurrentProcess();
871866
// Defer symbol loading.
872867
// We do not request undecorated symbols with SYMOPT_UNDNAME
873868
// because the mangling library calls UnDecorateSymbolName.
874-
SymSetOptions(SYMOPT_DEFERRED_LOADS);
869+
SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
875870
if (SymInitialize(process, nullptr, true)) {
876871
ready = true;
877872
}
@@ -881,9 +876,10 @@ class SymInitializer {
881876
// We do not need to close `HANDLE process` because it's a "pseudo handle."
882877
}
883878

884-
private:
885-
SymInitializer(const SymInitializer&);
886-
SymInitializer& operator=(const SymInitializer&);
879+
SymInitializer(const SymInitializer&) = delete;
880+
SymInitializer& operator=(const SymInitializer&) = delete;
881+
SymInitializer(SymInitializer&&) = delete;
882+
SymInitializer& operator=(SymInitializer&&) = delete;
887883
};
888884

889885
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
@@ -902,12 +898,42 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
902898
// This could break if a symbol has Unicode in it.
903899
BOOL ret = SymFromAddr(symInitializer.process, reinterpret_cast<DWORD64>(pc),
904900
0, symbol);
905-
if (ret == 1 && static_cast<ssize_t>(symbol->NameLen) < out_size) {
906-
// `NameLen` does not include the null terminating character.
907-
strncpy(out, symbol->Name, static_cast<size_t>(symbol->NameLen) + 1);
908-
out[static_cast<size_t>(symbol->NameLen)] = '\0';
901+
std::size_t namelen = static_cast<size_t>(symbol->NameLen);
902+
if (ret && namelen < out_size) {
903+
std::strncpy(out, symbol->Name, namelen);
904+
905+
out[namelen] = '\0';
906+
907+
DWORD displacement;
908+
IMAGEHLP_LINE64 line{sizeof(IMAGEHLP_LINE64)};
909+
910+
BOOL found = SymGetLineFromAddr64(symInitializer.process,
911+
reinterpret_cast<DWORD64>(pc),
912+
&displacement, &line);
913+
909914
// Symbolization succeeded. Now we try to demangle the symbol.
910915
DemangleInplace(out, out_size);
916+
917+
out_size -= std::strlen(out);
918+
919+
if (found) {
920+
std::size_t fnlen = std::strlen(line.FileName);
921+
922+
// Determine the number of digits (base 10) necessary to represent the
923+
// line number
924+
std::size_t digits = 1; // At least one digit required
925+
for (DWORD value = line.LineNumber; (value /= 10) != 0; ++digits) {
926+
}
927+
928+
constexpr std::size_t extralen = 4; // space + parens () + :
929+
const std::size_t suffixlen = fnlen + extralen + fnlen + digits;
930+
931+
if (suffixlen < out_size) {
932+
out_size -= std::snprintf(out + namelen, out_size, " (%s:%u)",
933+
line.FileName, line.LineNumber);
934+
}
935+
}
936+
911937
return true;
912938
}
913939
return false;

0 commit comments

Comments
 (0)