From: Julian Seward Date: Tue, 12 Oct 2010 00:44:05 +0000 (+0000) Subject: Make the --prefix-to-strip=... command-line option added in r11312 X-Git-Tag: svn/VALGRIND_3_6_0~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1375448f10b4484f99615e9280725d97d380f041;p=thirdparty%2Fvalgrind.git Make the --prefix-to-strip=... command-line option added in r11312 behave more like the original proposal in #245535. This makes it more flexible and general. Also rename it. * new name is --fullpath-after= * allow multiple instances of --fullpath-after= * don't require the specified strings to be prefixes, only substrings But retain the elegant backwards-compatibility trick in Bart's r11312 commit: if --fullpath-after= is not specified at all, then behave exactly as before. Fixes #245535. A mixture of patches from Bart Van Assche (bart.vanassche@gmail.com), Alexander Potapenko (glider@google.com), and me (integration and documentation). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11430 --- diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 73f311b71e..303c001ac7 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -1774,10 +1774,13 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 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) @@ -1789,6 +1792,11 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 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; @@ -1858,20 +1866,32 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 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(":"); diff --git a/coregrind/m_main.c b/coregrind/m_main.c index c98bf087cb..bea5258acf 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -157,15 +157,18 @@ static void usage_NORETURN ( Bool debug_help ) " --alignment= 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= If not empty, specifies that full source file\n" -" paths must be printed in call stacks and also\n" " that 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" @@ -482,13 +485,6 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd, 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)) {} @@ -560,6 +556,16 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_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, diff --git a/coregrind/m_options.c b/coregrind/m_options.c index 8438cae7f5..a347c7d492 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -64,6 +64,8 @@ Bool VG_(clo_time_stamp) = False; 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; @@ -83,7 +85,6 @@ Int VG_(clo_backtrace_size) = 12; 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; diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index d737cdfd0b..06b5701c47 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -45,6 +45,9 @@ /* 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. @@ -91,6 +94,10 @@ extern Int VG_(clo_n_suppressions); /* 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 ) */ diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml index 1c41b0430b..3ca982133a 100644 --- a/docs/xml/manual-core.xml +++ b/docs/xml/manual-core.xml @@ -997,16 +997,53 @@ that can report errors, e.g. Memcheck, but not Cachegrind. - + - + - By default Valgrind only shows the filename in stack traces and - not the full path of the source file. When using - , 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. + 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. + 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 is found in the path, then the path + up to and including is omitted, else the + path is shown unmodified. Note that is + not required to be a prefix of the path. + + For example, consider a file named + /home/janedoe/blah/src/foo/bar/xyzzy.c. + Specifying + will cause Valgrind to show the name + as foo/bar/xyzzy.c. + + Because the string is not required to be a prefix, + will produce the same + output. This is useful when the path contains arbitrary + machine-generated characters. For example, the + path + /my/build/dir/C32A1B47/blah/src/foo/xyzzy + can be pruned to foo/xyzzy + using + . + + If you simply want to see the full path, just specify an + empty string: . This isn't a + special case, merely a logical consequence of the above rules. + + Finally, you can use + 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 -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. diff --git a/memcheck/tests/badfree3.vgtest b/memcheck/tests/badfree3.vgtest index 97283abe00..876cced879 100644 --- a/memcheck/tests/badfree3.vgtest +++ b/memcheck/tests/badfree3.vgtest @@ -1,2 +1,2 @@ prog: badfree -vgopts: -q --prefix-to-strip=${PWD} +vgopts: -q --fullpath-after=${PWD}/ diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp index 9ce72c05f3..7306e7587b 100644 --- a/none/tests/cmdline1.stdout.exp +++ b/none/tests/cmdline1.stdout.exp @@ -45,16 +45,18 @@ usage: valgrind [options] prog-and-args --alignment= 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= If not empty, specifies that full source file - paths must be printed in call stacks and also - that 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] diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp index 9ab2d126c8..0d39df8114 100644 --- a/none/tests/cmdline2.stdout.exp +++ b/none/tests/cmdline2.stdout.exp @@ -45,16 +45,18 @@ usage: valgrind [options] prog-and-args --alignment= 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= If not empty, specifies that full source file - paths must be printed in call stacks and also - that 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]