@@ -854,24 +854,19 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
854
854
# include < dbghelp.h>
855
855
# include < windows.h>
856
856
857
- # ifdef _MSC_VER
858
- # pragma comment(lib, "dbghelp")
859
- # endif
860
-
861
857
namespace google {
862
858
863
- class SymInitializer {
859
+ class SymInitializer final {
864
860
public:
865
861
HANDLE process;
866
862
bool ready;
867
- SymInitializer () : process(nullptr ), ready(false ) {
863
+ SymInitializer () : process(GetCurrentProcess() ), ready(false ) {
868
864
// Initialize the symbol handler.
869
865
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx
870
- process = GetCurrentProcess ();
871
866
// Defer symbol loading.
872
867
// We do not request undecorated symbols with SYMOPT_UNDNAME
873
868
// because the mangling library calls UnDecorateSymbolName.
874
- SymSetOptions (SYMOPT_DEFERRED_LOADS);
869
+ SymSetOptions (SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES );
875
870
if (SymInitialize (process, nullptr , true )) {
876
871
ready = true ;
877
872
}
@@ -881,9 +876,10 @@ class SymInitializer {
881
876
// We do not need to close `HANDLE process` because it's a "pseudo handle."
882
877
}
883
878
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 ;
887
883
};
888
884
889
885
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle (void * pc, char * out,
@@ -902,12 +898,42 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
902
898
// This could break if a symbol has Unicode in it.
903
899
BOOL ret = SymFromAddr (symInitializer.process , reinterpret_cast <DWORD64>(pc),
904
900
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
+
909
914
// Symbolization succeeded. Now we try to demangle the symbol.
910
915
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
+
911
937
return true ;
912
938
}
913
939
return false ;
0 commit comments