UInt lineno;
UChar ibuf[50];
Int n = 0;
+
static UChar buf_fn[BUF_LEN];
static UChar buf_obj[BUF_LEN];
static UChar buf_srcloc[BUF_LEN];
static UChar buf_dirname[BUF_LEN];
+ buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0;
+
Bool know_dirinfo = False;
Bool know_fnname = VG_(clo_sym_offsets)
? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN)
buf_dirname, BUF_LEN, &know_dirinfo,
&lineno
);
+ buf_fn [ sizeof(buf_fn)-1 ] = 0;
+ buf_obj [ sizeof(buf_obj)-1 ] = 0;
+ buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0;
+ buf_dirname[ sizeof(buf_dirname)-1 ] = 0;
+
if (VG_(clo_xml)) {
Bool human_readable = True;
APPEND("???");
}
if (know_srcloc) {
- const Char* const pfx = VG_(clo_prefix_to_strip);
APPEND(" (");
- if (pfx) {
- const int pfxlen = VG_(strlen)(pfx);
- const int matchlen = VG_(strncmp)(pfx, buf_dirname, pfxlen) == 0
- ? pfxlen : 0;
- if (matchlen && buf_dirname[matchlen] == '/'
- && buf_dirname[matchlen + 1]) {
- APPEND(buf_dirname + matchlen + 1);
- APPEND("/");
- } else if (buf_dirname[matchlen]) {
- APPEND(buf_dirname + matchlen);
- APPEND("/");
- }
+ // Get the directory name, if any, possibly pruned, into dirname.
+ UChar* dirname = NULL;
+ if (VG_(clo_n_fullpath_after) > 0) {
+ Int i;
+ dirname = buf_dirname;
+ // Remove leading prefixes from the dirname.
+ // If user supplied --fullpath-after=foo, this will remove
+ // a leading string which matches '.*foo' (not greedy).
+ for (i = 0; i < VG_(clo_n_fullpath_after); i++) {
+ UChar* prefix = VG_(clo_fullpath_after)[i];
+ UChar* str = VG_(strstr)(dirname, prefix);
+ if (str) {
+ dirname = str + VG_(strlen)(prefix);
+ break;
+ }
+ }
+ /* remove leading "./" */
+ if (dirname[0] == '.' && dirname[1] == '/')
+ dirname += 2;
+ }
+ // do we have any interesting directory name to show? If so
+ // add it in.
+ if (dirname && dirname[0] != 0) {
+ APPEND(dirname);
+ APPEND("/");
}
APPEND(buf_srcloc);
APPEND(":");
" --alignment=<number> set minimum alignment of heap allocations [%ld]\n"
"\n"
" uncommon user options for all Valgrind tools:\n"
+" --fullpath-after= (with nothing after the '=')\n"
+" show full source paths in call stacks\n"
+" --fullpath-after=string like --fullpath-after=, but only show the\n"
+" part of the path after 'string'. Allows removal\n"
+" of path prefixes. Use this flag multiple times\n"
+" to specify a set of prefixes to remove.\n"
" --smc-check=none|stack|all checks for self-modifying code: none,\n"
" only for code found in stacks, or all [stack]\n"
" --read-var-info=yes|no read debug info on stack and global variables\n"
" and use it to print better error messages in\n"
" tools that make use of it (Memcheck, Helgrind,\n"
" DRD) [no]\n"
-" --prefix-to-strip=<pfx> If not empty, specifies that full source file\n"
-" paths must be printed in call stacks and also\n" " that <pfx> must be stripped from these paths.\n"
-" [""].\n"
" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
" --sim-hints=hint1,hint2,... known hints:\n"
" lax-ioctls, enable-outer [none]\n"
else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
- else if VG_STR_CLO (arg, "--prefix-to-strip", VG_(clo_prefix_to_strip)) {
- Char *const pfx = VG_(clo_prefix_to_strip);
- Char *const pfx_end = pfx + VG_(strlen)(pfx);
- Char *const last_slash = VG_(strrchr)(pfx, '/');
- if (last_slash == pfx_end - 1)
- *last_slash = '\0';
- }
else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
VG_(clo_n_suppressions)++;
}
+ else if VG_STR_CLO (arg, "--fullpath-after", tmp_str) {
+ if (VG_(clo_n_fullpath_after) >= VG_CLO_MAX_FULLPATH_AFTER) {
+ VG_(fmsg_bad_option)(arg,
+ "Too many --fullpath-after= specifications.\n"
+ "Increase VG_CLO_MAX_FULLPATH_AFTER and recompile.\n");
+ }
+ VG_(clo_fullpath_after)[VG_(clo_n_fullpath_after)] = tmp_str;
+ VG_(clo_n_fullpath_after)++;
+ }
+
else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
VG_(fmsg_bad_option)(arg,
Int VG_(clo_input_fd) = 0; /* stdin */
Int VG_(clo_n_suppressions) = 0;
Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
+Int VG_(clo_n_fullpath_after) = 0;
+Char* VG_(clo_fullpath_after)[VG_CLO_MAX_FULLPATH_AFTER];
UChar VG_(clo_trace_flags) = 0; // 00000000b
UChar VG_(clo_profile_flags) = 0; // 00000000b
Int VG_(clo_trace_notbelow) = 999999999;
Char* VG_(clo_sim_hints) = NULL;
Bool VG_(clo_sym_offsets) = False;
Bool VG_(clo_read_var_info) = False;
-Char* VG_(clo_prefix_to_strip) = NULL;
Int VG_(clo_n_req_tsyms) = 0;
HChar* VG_(clo_req_tsyms)[VG_CLO_MAX_REQ_TSYMS];
HChar* VG_(clo_require_text_symbol) = NULL;
/* The max number of --require-text-symbol= specification strings. */
#define VG_CLO_MAX_REQ_TSYMS 100
+/* The max number of --fullpath-after= parameters. */
+#define VG_CLO_MAX_FULLPATH_AFTER 100
+
/* Should we stop collecting errors if too many appear? default: YES */
extern Bool VG_(clo_error_limit);
/* Alternative exit code to hand to parent if errors were found.
/* The names of the suppression files. */
extern Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
+/* An array of strings harvested from --fullpath-after= flags. */
+extern Int VG_(clo_n_fullpath_after);
+extern Char* VG_(clo_fullpath_after)[VG_CLO_MAX_FULLPATH_AFTER];
+
/* DEBUG: print generated code? default: 00000000 ( == NO ) */
extern UChar VG_(clo_trace_flags);
/* DEBUG: do bb profiling? default: 00000000 ( == NO ) */
</listitem>
</varlistentry>
- <varlistentry id="opt.prefix-to-strip" xreflabel="--prefix-to-strip">
+ <varlistentry id="opt.fullpath-after" xreflabel="--fullpath-after">
<term>
- <option><![CDATA[--prefix-to-strip=<prefix> [default: off] ]]></option>
+ <option><![CDATA[--fullpath-after=<string>
+ [default: don't show source paths] ]]></option>
</term>
<listitem>
- <para>By default Valgrind only shows the filename in stack traces and
- not the full path of the source file. When using
- <option>--prefix-to-strip</option>, Valgrind will include the full
- path of source files in stack traces. If a path starts with the
- specified prefix, the prefix will be left out from the printed path.
+ <para>By default Valgrind only shows the filenames in stack
+ traces, but not full paths to source files. When using Valgrind
+ in large projects where the sources reside in multiple different
+ directories, this can be inconvenient.
+ <option>--fullpath-after</option> provides a flexible solution
+ to this problem. When this option is present, the path to each
+ source file is shown, with the following all-important caveat:
+ if <option>string</option> is found in the path, then the path
+ up to and including <option>string</option> is omitted, else the
+ path is shown unmodified. Note that <option>string</option> is
+ not required to be a prefix of the path.</para>
+
+ <para>For example, consider a file named
+ <computeroutput>/home/janedoe/blah/src/foo/bar/xyzzy.c</computeroutput>.
+ Specifying <option>--fullpath-after=/home/janedoe/blah/src/</option>
+ will cause Valgrind to show the name
+ as <computeroutput>foo/bar/xyzzy.c</computeroutput>.</para>
+
+ <para>Because the string is not required to be a prefix,
+ <option>--fullpath-after=src/</option> will produce the same
+ output. This is useful when the path contains arbitrary
+ machine-generated characters. For example, the
+ path
+ <computeroutput>/my/build/dir/C32A1B47/blah/src/foo/xyzzy</computeroutput>
+ can be pruned to <computeroutput>foo/xyzzy</computeroutput>
+ using
+ <option>--fullpath-after=/blah/src/</option>.</para>
+
+ <para>If you simply want to see the full path, just specify an
+ empty string: <option>--fullpath-after=</option>. This isn't a
+ special case, merely a logical consequence of the above rules.</para>
+
+ <para>Finally, you can use <option>--fullpath-after</option>
+ multiple times. Any appearance of it causes Valgrind to switch
+ to producing full paths and applying the above filtering rule.
+ Each produced path is compared against all
+ the <option>--fullpath-after</option>-specified strings, in the
+ order specified. The first string to match causes the path to
+ be truncated as described above. If none match, the full path
+ is shown. This facilitates chopping off prefixes when the
+ sources are drawn from a number of unrelated directories.
</para>
</listitem>
</varlistentry>
prog: badfree
-vgopts: -q --prefix-to-strip=${PWD}
+vgopts: -q --fullpath-after=${PWD}/
--alignment=<number> set minimum alignment of heap allocations [...]
uncommon user options for all Valgrind tools:
+ --fullpath-after= (with nothing after the '=')
+ show full source paths in call stacks
+ --fullpath-after=string like --fullpath-after=, but only show the
+ part of the path after 'string'. Allows removal
+ of path prefixes. Use this flag multiple times
+ to specify a set of prefixes to remove.
--smc-check=none|stack|all checks for self-modifying code: none,
only for code found in stacks, or all [stack]
--read-var-info=yes|no read debug info on stack and global variables
and use it to print better error messages in
tools that make use of it (Memcheck, Helgrind,
DRD) [no]
- --prefix-to-strip=<pfx> If not empty, specifies that full source file
- paths must be printed in call stacks and also
- that <pfx> must be stripped from these paths.
- [].
--run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]
--sim-hints=hint1,hint2,... known hints:
lax-ioctls, enable-outer [none]
--alignment=<number> set minimum alignment of heap allocations [...]
uncommon user options for all Valgrind tools:
+ --fullpath-after= (with nothing after the '=')
+ show full source paths in call stacks
+ --fullpath-after=string like --fullpath-after=, but only show the
+ part of the path after 'string'. Allows removal
+ of path prefixes. Use this flag multiple times
+ to specify a set of prefixes to remove.
--smc-check=none|stack|all checks for self-modifying code: none,
only for code found in stacks, or all [stack]
--read-var-info=yes|no read debug info on stack and global variables
and use it to print better error messages in
tools that make use of it (Memcheck, Helgrind,
DRD) [no]
- --prefix-to-strip=<pfx> If not empty, specifies that full source file
- paths must be printed in call stacks and also
- that <pfx> must be stripped from these paths.
- [].
--run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]
--sim-hints=hint1,hint2,... known hints:
lax-ioctls, enable-outer [none]