This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer_common] Added VS-style output for source locations
ClosedPublic

Authored by filcab on May 28 2015, 5:25 PM.

Details

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.

Diff Detail

Repository
rL LLVM

Event Timeline

filcab updated this revision to Diff 26759.May 28 2015, 5:25 PM
filcab retitled this revision from to [sanitizer_common] Added VS-style output for source locations.
filcab updated this object.
filcab edited the test plan for this revision. (Show Details)
filcab added reviewers: samsonov, rnk.
filcab added a subscriber: Unknown Object (MLST).
samsonov edited edge metadata.May 28 2015, 5:36 PM

Why does't passing "%s(%l,%c)" in stack_trace_format work for you?

It's possible, but has drawbacks:

  • ReportErrorSummary wouldn't pick it up (fixable), it's using "%L %F";
  • "%L" wouldn't be straightforward to use if the user wanted to change the

default (the user would have to explicitly pass "%s(%l,%c)" where they want
to have the location (instead of simply "%L");

  • We would have a different DEFAULT from trunk in our (internal) port,

which would add to merge work (I don't expect it to change much, of course.
But we'd need to take care of it whenever the default changed, in order to
keep up with trunk). This is not something you need to worry, of course.
I'm just adding for completeness.

Points 1 and 2 would also apply to any sanitizer running on Windows, too
(If someone were to use them with VS, it's much easier to simply double
click the output), if we decide to turn on VS-style location info output by
default on this platform.

Thanks,

Filipe

Alright, I agree with rationale for this change, and VS integration is nice to have...

lib/sanitizer_common/sanitizer_stacktrace_printer.cc
119 ↗(On Diff #26759)

Just curious, can you print file(line) or file(line,0) in VS?

119 ↗(On Diff #26759)

I'd rather handle VS case separately

if (vs_style && line > 0 && column > 0) {
  buffer->append("%s(%d,%d)", ....);
  return;
}

BTW, what is the expected behavior if, say, vs_style is true, but column is unknown. Is it really OK to fallback to traditional source location?

lib/sanitizer_common/sanitizer_stacktrace_printer.h
55 ↗(On Diff #26759)

I find it confusing, that you should pass strip_path_prefix and vs_style in different order, than in the function above.

filcab added inline comments.Jun 2 2015, 9:28 PM
lib/sanitizer_common/sanitizer_flags.inc
149 ↗(On Diff #26759)

This should probably default to SANITIZER_WINDOWS instead of false.
I think it would be the option that better matches what a user of that platform would expect, no?

lib/sanitizer_common/sanitizer_stacktrace_printer.cc
119 ↗(On Diff #26759)

Yes.

I tested these variations:

printf(__FILE__ ": hello world!\n");
printf(__FILE__ "(0,0): hello world!\n");
printf(__FILE__ "(%d,0): hello world!\n", __LINE__);
printf(__FILE__ "(%d): hello world!\n", __LINE__);
printf(__FILE__ "(%d,17): hello world!\n", __LINE__);

Both UNIX-style ("file:3:42") and the first two in that set will select the first line in the file (absence of line info).
The other three all select their respective lines.

I think the easiest option would be to do a variation of what you mentioned:

if (vs_style && line > 0) {
  buffer->append("%s(%d,%d)", ....);
  return;
} // Fallback to UNIX-style if there's no line info

(not caring about column info and printing 0 if absent)

The "prettiest" (read: less confusing output) might be:

if (vs_style && line > 0) {
  buffer->append("%s(%d", ...);
  if (column > 0)
    buffer->append(",%d)", ....);
  else
    buffer->append(")", ....);
  return;
} // Fallback to UNIX-style if there's no line info

(Only printing column info if we actually have column info)

I'm ok with either one (or even not having the else clause and splitting "%d" from ")"). Let me know which you would prefer.

lib/sanitizer_common/sanitizer_stacktrace_printer.h
55 ↗(On Diff #26759)

Will change.

samsonov added inline comments.Jun 2 2015, 9:34 PM
lib/sanitizer_common/sanitizer_flags.inc
149 ↗(On Diff #26759)

I'd let Reid comment on this. I don't have strong preference about Windows defaults.

lib/sanitizer_common/sanitizer_stacktrace_printer.cc
119 ↗(On Diff #26759)
if (vs_style && line > 0) {
  buffer->append("%s(%d", ...);
  if (column > 0) buffer->append(",%d", ...);
  buffer->append(")");
  return;
}
filcab updated this revision to Diff 27067.Jun 3 2015, 3:38 PM
filcab edited edge metadata.

Addressed Samsonov's comments.

filcab updated this revision to Diff 27068.Jun 3 2015, 3:46 PM

Forgot to git add the header

filcab updated this revision to Diff 27069.Jun 3 2015, 3:53 PM

Added more RenderFrame tests. ninja check-sanitizer succeeds

samsonov accepted this revision.Jun 3 2015, 5:44 PM
samsonov edited edge metadata.

LGTM

This revision is now accepted and ready to land.Jun 3 2015, 5:44 PM
This revision was automatically updated to reflect the committed changes.
rnk added inline comments.Jun 4 2015, 2:57 PM
lib/sanitizer_common/sanitizer_flags.inc
149 ↗(On Diff #26759)

Let's default this to defined(_MSC_VER). Thankfully it is very easy to override the default sanitizer options with __asan_default_options(), so I'd rather optimize for first time users of visual studio rather than people like us with big cross-platform projects.

filcab added a comment.Jun 4 2015, 3:58 PM

Sounds good to me. But there's a detail to be dealt with.

For out of the box _testing_, having the VS style output be the default
will force us to, either:

  • use a script to run the commands (doable, but ugly (except if you need

the script anyway, for remote testing. I'm ok with this))

  • or change all the tests to expect one of the output styles (I don't

really like this :-) )

I would like to avoid both of those solutions.

What do you think about doing something like this:

Have options get their values in this order:

  • Compiled-in defaults
  • $SANITIZER_OPTIONS (new)
  • __tool_default_options() (asan, ubsan, etc)
  • $TOOL_OPTIONS (ASAN, UBSAN, etc)

The rationale is:

  • Compiled-in defaults should be sensible defaults for the platform.
  • $SANITIZER_OPTIONS could set common flags (only, no tool-specific

options) for the user/machine

  • __tool_default_options() can be used in a program to override some flags

because the test/program expects this

  • $TOOL_OPTIONS is a final chance for the current user, running the

program, to override.

I'm ok with not doing this, and simply waiting until it's more necessary.
For the PS4, I can just work around it and "hack" our remote run script to
always add symbolize_vs_style=false to *_OPTIONS env vars when testing. But
it wouldn't be nice for local Windows testing (non-remote), since we would
default to vs-style (if _MSC_VER was defined) in some cases.

Any ideas?

Thanks,

Filipe