13
13
#include " stacktrace.hpp"
14
14
#include " ur_sanitizer_layer.hpp"
15
15
16
+ extern " C" {
17
+
18
+ __attribute__ ((weak)) bool SymbolizeCode(const std::string ModuleName,
19
+ uint64_t ModuleOffset,
20
+ std::string &Result);
21
+ }
22
+
16
23
namespace ur_sanitizer_layer {
17
24
18
25
namespace {
@@ -21,6 +28,54 @@ bool Contains(const std::string &s, const char *p) {
21
28
return s.find (p) != std::string::npos;
22
29
}
23
30
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
+
24
79
} // namespace
25
80
26
81
void StackTrace::print () const {
@@ -37,6 +92,26 @@ void StackTrace::print() const {
37
92
Contains (BI, " libur_loader.so" )) {
38
93
continue ;
39
94
}
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
+ }
40
115
getContext ()->logger .always (" #{} {}" , index, BI);
41
116
++index;
42
117
}
0 commit comments