1313#include " stacktrace.hpp"
1414#include " ur_sanitizer_layer.hpp"
1515
16+ extern " C" {
17+
18+ __attribute__ ((weak)) bool SymbolizeCode(const std::string ModuleName,
19+ uint64_t ModuleOffset,
20+ std::string &Result);
21+ }
22+
1623namespace ur_sanitizer_layer {
1724
1825namespace {
@@ -21,6 +28,54 @@ bool Contains(const std::string &s, const char *p) {
2128 return s.find (p) != std::string::npos;
2229}
2330
31+ // Parse back trace information in the following formats:
32+ // <module_name>([function_name]+function_offset) [offset]
33+ void ParseBacktraceInfo (BacktraceInfo BI, std::string &ModuleName,
34+ uptr &Offset) {
35+ // Parse module name
36+ size_t End = BI.find_first_of (' (' );
37+ assert (End != std::string::npos);
38+ ModuleName = BI.substr (0 , End);
39+ // Parse offset
40+ size_t Start = BI.find_first_of (' [' );
41+ assert (Start != std::string::npos);
42+ Start = BI.substr (Start + 1 , 2 ) == " 0x" ? Start + 3 : Start + 1 ;
43+ End = BI.find_first_of (' ]' );
44+ assert (End != std::string::npos);
45+ Offset = std::stoull (BI.substr (Start, End), nullptr , 16 );
46+ return ;
47+ }
48+
49+ // Parse symbolizer output in the following formats:
50+ // <function_name>
51+ // <file_name>:<line_number>[:<column_number>]
52+ SourceInfo ParseSymbolizerOutput (std::string Output) {
53+ SourceInfo Info;
54+ // Parse function name
55+ size_t End = Output.find_first_of (' \n ' );
56+ assert (End != std::string::npos);
57+ Info.function = Output.substr (0 , End);
58+ // Parse file name
59+ size_t Start = End + 1 ;
60+ End = Output.find_first_of (' :' , Start);
61+ assert (End != std::string::npos);
62+ Info.file = Output.substr (Start, End - Start);
63+ // Parse line number
64+ Start = End + 1 ;
65+ End = Output.find_first_of (" :\n " , Start);
66+ assert (End != std::string::npos);
67+ Info.line = std::stoi (Output.substr (Start, End - Start));
68+ // Parse column number if exists
69+ if (Output[End] == ' :' ) {
70+ Start = End + 1 ;
71+ End = Output.find_first_of (" \n " , Start);
72+ assert (End != std::string::npos);
73+ Info.column = std::stoi (Output.substr (Start, End - Start));
74+ }
75+
76+ return Info;
77+ }
78+
2479} // namespace
2580
2681void StackTrace::print () const {
@@ -37,6 +92,26 @@ void StackTrace::print() const {
3792 Contains (BI, " libur_loader.so" )) {
3893 continue ;
3994 }
95+
96+ if (&SymbolizeCode != nullptr ) {
97+ std::string Result;
98+ std::string ModuleName;
99+ uptr Offset;
100+ ParseBacktraceInfo (BI, ModuleName, Offset);
101+ if (SymbolizeCode (ModuleName, Offset, Result)) {
102+ SourceInfo SrcInfo = ParseSymbolizerOutput (Result);
103+ if (SrcInfo.file != " ??" ) {
104+ getContext ()->logger .always (" #{} in {} {}:{}:{}" , index,
105+ SrcInfo.function , SrcInfo.file ,
106+ SrcInfo.line , SrcInfo.column );
107+ } else {
108+ getContext ()->logger .always (" #{} in {} ({}+{})" , index,
109+ SrcInfo.function , ModuleName,
110+ (void *)Offset);
111+ }
112+ continue ;
113+ }
114+ }
40115 getContext ()->logger .always (" #{} {}" , index, BI);
41116 ++index;
42117 }
0 commit comments