Skip to content

Commit 215046b

Browse files
committedJun 4, 2015
[sanitizer_common] Added VS-style output for source locations
Summary: With this patch, we have a flag to toggle displaying source locations in the regular style: file:line:column or Visual Studio style: file(line,column) This way, they get picked up on the Visual Studio output window and one can double-click them to get to that file location. Reviewers: samsonov, rnk Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10113 llvm-svn: 239000
1 parent 1ba52fe commit 215046b

8 files changed

+75
-26
lines changed
 

‎compiler-rt/lib/sanitizer_common/sanitizer_common.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ void ReportErrorSummary(const char *error_type, const AddressInfo &info) {
243243
return;
244244
InternalScopedString buff(kMaxSummaryLength);
245245
buff.append("%s ", error_type);
246-
RenderFrame(&buff, "%L %F", 0, info, common_flags()->strip_path_prefix);
246+
RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style,
247+
common_flags()->strip_path_prefix);
247248
ReportErrorSummary(buff.data());
248249
}
249250
#endif

‎compiler-rt/lib/sanitizer_common/sanitizer_flags.inc

+3
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ COMMON_FLAG(bool, use_madv_dontdump, true,
146146
"in core file.")
147147
COMMON_FLAG(bool, symbolize_inline_frames, true,
148148
"Print inlined frames in stacktraces. Defaults to true.")
149+
COMMON_FLAG(bool, symbolize_vs_style, false,
150+
"Print file locations in Visual Studio style (e.g: "
151+
" file(10,42): ...")
149152
COMMON_FLAG(const char *, stack_trace_format, "DEFAULT",
150153
"Format string used to render stack frames. "
151154
"See sanitizer_stacktrace_printer.h for the format description. "

‎compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ void StackTrace::Print() const {
3535
for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
3636
frame_desc.clear();
3737
RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,
38-
cur->info, common_flags()->strip_path_prefix);
38+
cur->info, common_flags()->symbolize_vs_style,
39+
common_flags()->strip_path_prefix);
3940
Printf("%s\n", frame_desc.data());
4041
}
4142
frames->ClearAll();

‎compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cc

+16-7
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ static const char *StripFunctionName(const char *function, const char *prefix) {
2626
static const char kDefaultFormat[] = " #%n %p %F %L";
2727

2828
void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
29-
const AddressInfo &info, const char *strip_path_prefix,
30-
const char *strip_func_prefix) {
29+
const AddressInfo &info, bool vs_style,
30+
const char *strip_path_prefix, const char *strip_func_prefix) {
3131
if (0 == internal_strcmp(format, "DEFAULT"))
3232
format = kDefaultFormat;
3333
for (const char *p = format; *p != '\0'; p++) {
@@ -82,14 +82,14 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
8282
break;
8383
case 'S':
8484
// File/line information.
85-
RenderSourceLocation(buffer, info.file, info.line, info.column,
85+
RenderSourceLocation(buffer, info.file, info.line, info.column, vs_style,
8686
strip_path_prefix);
8787
break;
8888
case 'L':
8989
// Source location, or module location.
9090
if (info.file) {
9191
RenderSourceLocation(buffer, info.file, info.line, info.column,
92-
strip_path_prefix);
92+
vs_style, strip_path_prefix);
9393
} else if (info.module) {
9494
RenderModuleLocation(buffer, info.module, info.module_offset,
9595
strip_path_prefix);
@@ -106,15 +106,24 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
106106
buffer->append("(%p)", (void *)info.address);
107107
break;
108108
default:
109-
Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n",
110-
*p, *p);
109+
Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p,
110+
*p);
111111
Die();
112112
}
113113
}
114114
}
115115

116116
void RenderSourceLocation(InternalScopedString *buffer, const char *file,
117-
int line, int column, const char *strip_path_prefix) {
117+
int line, int column, bool vs_style,
118+
const char *strip_path_prefix) {
119+
if (vs_style && line > 0) {
120+
buffer->append("%s(%d", StripPathPrefix(file, strip_path_prefix), line);
121+
if (column > 0)
122+
buffer->append(",%d", column);
123+
buffer->append(")");
124+
return;
125+
}
126+
118127
buffer->append("%s", StripPathPrefix(file, strip_path_prefix));
119128
if (line > 0) {
120129
buffer->append(":%d", line);

‎compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ namespace __sanitizer {
4848
// module+offset if it is known, or (<unknown module>) string.
4949
// %M - prints module basename and offset, if it is known, or PC.
5050
void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
51-
const AddressInfo &info, const char *strip_path_prefix = "",
51+
const AddressInfo &info, bool vs_style,
52+
const char *strip_path_prefix = "",
5253
const char *strip_func_prefix = "");
5354

5455
void RenderSourceLocation(InternalScopedString *buffer, const char *file,
55-
int line, int column, const char *strip_path_prefix);
56+
int line, int column, bool vs_style,
57+
const char *strip_path_prefix);
5658

5759
void RenderModuleLocation(InternalScopedString *buffer, const char *module,
5860
uptr offset, const char *strip_path_prefix);

‎compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc

+44-14
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,36 @@ namespace __sanitizer {
1818

1919
TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
2020
InternalScopedString str(128);
21-
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "");
21+
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "");
2222
EXPECT_STREQ("/dir/file.cc:10:5", str.data());
2323

2424
str.clear();
25-
RenderSourceLocation(&str, "/dir/file.cc", 11, 0, "");
25+
RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, "");
2626
EXPECT_STREQ("/dir/file.cc:11", str.data());
2727

2828
str.clear();
29-
RenderSourceLocation(&str, "/dir/file.cc", 0, 0, "");
29+
RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, "");
3030
EXPECT_STREQ("/dir/file.cc", str.data());
3131

3232
str.clear();
33-
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "/dir/");
33+
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/");
3434
EXPECT_STREQ("file.cc:10:5", str.data());
35+
36+
str.clear();
37+
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "");
38+
EXPECT_STREQ("/dir/file.cc(10,5)", str.data());
39+
40+
str.clear();
41+
RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, "");
42+
EXPECT_STREQ("/dir/file.cc(11)", str.data());
43+
44+
str.clear();
45+
RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, "");
46+
EXPECT_STREQ("/dir/file.cc", str.data());
47+
48+
str.clear();
49+
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/");
50+
EXPECT_STREQ("file.cc(10,5)", str.data());
3551
}
3652

3753
TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
@@ -62,7 +78,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
6278
RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
6379
"Function:%f FunctionOffset:%q Source:%s Line:%l "
6480
"Column:%c",
65-
frame_no, info, "/path/to/", "function_");
81+
frame_no, info, false, "/path/to/", "function_");
6682
EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
6783
"Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
6884
"Column:5",
@@ -72,50 +88,64 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
7288

7389
// Test special format specifiers.
7490
info.address = 0x400000;
75-
RenderFrame(&str, "%M", frame_no, info);
91+
RenderFrame(&str, "%M", frame_no, info, false);
7692
EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
7793
str.clear();
7894

79-
RenderFrame(&str, "%L", frame_no, info);
95+
RenderFrame(&str, "%L", frame_no, info, false);
8096
EXPECT_STREQ("(<unknown module>)", str.data());
8197
str.clear();
8298

8399
info.module = internal_strdup("/path/to/module");
84100
info.module_offset = 0x200;
85-
RenderFrame(&str, "%M", frame_no, info);
101+
RenderFrame(&str, "%M", frame_no, info, false);
86102
EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
87103
EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
88104
str.clear();
89105

90-
RenderFrame(&str, "%L", frame_no, info);
106+
RenderFrame(&str, "%L", frame_no, info, false);
91107
EXPECT_STREQ("(/path/to/module+0x200)", str.data());
92108
str.clear();
93109

94110
info.function = internal_strdup("my_function");
95-
RenderFrame(&str, "%F", frame_no, info);
111+
RenderFrame(&str, "%F", frame_no, info, false);
96112
EXPECT_STREQ("in my_function", str.data());
97113
str.clear();
98114

99115
info.function_offset = 0x100;
100-
RenderFrame(&str, "%F %S", frame_no, info);
116+
RenderFrame(&str, "%F %S", frame_no, info, false);
101117
EXPECT_STREQ("in my_function+0x100 <null>", str.data());
102118
str.clear();
103119

104120
info.file = internal_strdup("my_file");
105-
RenderFrame(&str, "%F %S", frame_no, info);
121+
RenderFrame(&str, "%F %S", frame_no, info, false);
106122
EXPECT_STREQ("in my_function my_file", str.data());
107123
str.clear();
108124

109125
info.line = 10;
110-
RenderFrame(&str, "%F %S", frame_no, info);
126+
RenderFrame(&str, "%F %S", frame_no, info, false);
111127
EXPECT_STREQ("in my_function my_file:10", str.data());
112128
str.clear();
113129

114130
info.column = 5;
115-
RenderFrame(&str, "%S %L", frame_no, info);
131+
RenderFrame(&str, "%S %L", frame_no, info, false);
116132
EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
117133
str.clear();
118134

135+
RenderFrame(&str, "%S %L", frame_no, info, true);
136+
EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());
137+
str.clear();
138+
139+
info.column = 0;
140+
RenderFrame(&str, "%F %S", frame_no, info, true);
141+
EXPECT_STREQ("in my_function my_file(10)", str.data());
142+
str.clear();
143+
144+
info.line = 0;
145+
RenderFrame(&str, "%F %S", frame_no, info, true);
146+
EXPECT_STREQ("in my_function my_file", str.data());
147+
str.clear();
148+
119149
info.Clear();
120150
}
121151

‎compiler-rt/lib/tsan/rtl/tsan_report.cc

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ void PrintStack(const ReportStack *ent) {
120120
for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {
121121
InternalScopedString res(2 * GetPageSizeCached());
122122
RenderFrame(&res, common_flags()->stack_trace_format, i, frame->info,
123+
common_flags()->symbolize_vs_style,
123124
common_flags()->strip_path_prefix, "__interceptor_");
124125
Printf("%s\n", res.data());
125126
}

‎compiler-rt/lib/ubsan/ubsan_diag.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ static void renderLocation(Location Loc) {
121121
LocBuffer.append("<unknown>");
122122
else
123123
RenderSourceLocation(&LocBuffer, SLoc.getFilename(), SLoc.getLine(),
124-
SLoc.getColumn(), common_flags()->strip_path_prefix);
124+
SLoc.getColumn(), common_flags()->symbolize_vs_style,
125+
common_flags()->strip_path_prefix);
125126
break;
126127
}
127128
case Location::LK_Memory:
@@ -131,6 +132,7 @@ static void renderLocation(Location Loc) {
131132
const AddressInfo &Info = Loc.getSymbolizedStack()->info;
132133
if (Info.file) {
133134
RenderSourceLocation(&LocBuffer, Info.file, Info.line, Info.column,
135+
common_flags()->symbolize_vs_style,
134136
common_flags()->strip_path_prefix);
135137
} else if (Info.module) {
136138
RenderModuleLocation(&LocBuffer, Info.module, Info.module_offset,

0 commit comments

Comments
 (0)
Please sign in to comment.