|
From: Nicholas N. <nj...@ca...> - 2004-06-15 10:54:50
|
CVS commit by nethercote:
Fixed up various command line option scenarios:
- If no tool is specified, V now gives a short message and a list of
available tools. This was meant to happen previously, but a bug prevented
it from working properly; it gave the usage message instead.
- If a bad option is given, V now gives a short message rather than the full
--help. This make V consistent with all other programs I looked at.
- Now returning 0 when you do 'valgrind --help' and 'valgrind --version'
as other programs do.
- Removed VG_(startup_logging)() and VG_(shutdown_logging)() as they were
empty and have been for a long time (always?).
- Added various tests for these scenarios. Had to change the regtest
script slightly to allow for malformed command lines.
This addresses bug (wishlist) #82999.
A none/tests/cmdline1.stderr.exp 1.1
A none/tests/cmdline1.stdout.exp 1.1
A none/tests/cmdline1.vgtest 1.1
A none/tests/cmdline2.stderr.exp 1.1
A none/tests/cmdline2.stdout.exp 1.1
A none/tests/cmdline2.vgtest 1.1
A none/tests/cmdline3.stderr.exp 1.1
A none/tests/cmdline3.vgtest 1.1
A none/tests/cmdline4.stderr.exp 1.1
A none/tests/cmdline4.vgtest 1.1
A none/tests/cmdline5.stderr.exp 1.1
A none/tests/cmdline5.vgtest 1.1
A none/tests/cmdline6.stderr.exp 1.1
A none/tests/cmdline6.vgtest 1.1
M +2 -0 coregrind/.cvsignore 1.4
M +106 -75 coregrind/vg_main.c 1.152 [POSSIBLY UNSAFE: printf]
M +6 -0 none/tests/Makefile.am 1.37
M +12 -10 tests/vg_regtest.in 1.22
--- valgrind/coregrind/.cvsignore #1.3:1.4
@@ -5,2 +5,4 @@
vg_toolint.h
vg_toolint.c
+vg_intercept.c
+vg_replace_malloc.c
--- valgrind/coregrind/vg_main.c #1.151:1.152
@@ -1244,5 +1244,5 @@ static void list_tools(void)
}
- while((de = readdir(dir)) != NULL) {
+ while ((de = readdir(dir)) != NULL) {
int len = strlen(de->d_name);
@@ -1252,9 +1252,9 @@ static void list_tools(void)
VG_STREQ(de->d_name + len - 3, ".so")) {
if (first) {
- printf("Available tools:\n");
+ fprintf(stderr, "Available tools:\n");
first = 0;
}
de->d_name[len-3] = '\0';
- printf("\t%s\n", de->d_name+7);
+ fprintf(stderr, "\t%s\n", de->d_name+7);
}
}
@@ -1263,5 +1263,5 @@ static void list_tools(void)
if (first)
- printf("No tools available in \"%s\" (installation problem?)\n",
+ fprintf(stderr, "No tools available in \"%s\" (installation problem?)\n",
VG_(libdir));
}
@@ -1355,24 +1355,68 @@ static void load_tool( const char *tooln
dlclose(handle);
- fprintf(stderr, "Aborting: couldn't load tool\n");
+ fprintf(stderr, "valgrind: couldn't load tool\n");
list_tools();
exit(127);
}
+
+/*====================================================================*/
+/*=== Command line errors ===*/
+/*====================================================================*/
+
+static void abort_msg ( void )
+{
+ VG_(clo_log_to) = VgLogTo_Fd;
+ VG_(clo_logfile_fd) = 2; /* stderr */
+}
+
+void VG_(bad_option) ( Char* opt )
+{
+ abort_msg();
+ VG_(printf)("valgrind: Bad option `%s'; aborting.\n", opt);
+ VG_(printf)("valgrind: Use --help for more information.\n");
+ VG_(exit)(1);
+}
+
+static void missing_tool_option ( void )
+{
+ abort_msg();
+ VG_(printf)("valgrind: Missing --tool option\n");
+ list_tools();
+ VG_(printf)("valgrind: Use --help for more information.\n");
+ VG_(exit)(1);
+}
+
+static void missing_prog ( void )
+{
+ abort_msg();
+ VG_(printf)("valgrind: no program specified\n");
+ VG_(printf)("valgrind: Use --help for more information.\n");
+ VG_(exit)(1);
+}
+
+static void config_error ( Char* msg )
+{
+ abort_msg();
+ VG_(printf)("valgrind: Startup or configuration error:\n %s\n", msg);
+ VG_(printf)("valgrind: Unable to start up properly. Giving up.\n");
+ VG_(exit)(1);
+}
+
+
/*====================================================================*/
/*=== Loading the client ===*/
/*====================================================================*/
-static void load_client(char* cl_argv[], const char* exec,
- /*inout*/Int* need_help,
+static void load_client(char* cl_argv[], const char* exec, Int need_help,
/*out*/struct exeinfo* info, /*out*/Addr* client_eip)
{
// If they didn't specify an executable with --exec, and didn't specify
// --help, then use client argv[0] (searching $PATH if necessary).
- if (NULL == exec && !*need_help) {
+ if (NULL == exec && !need_help) {
if (cl_argv[0] == NULL ||
( NULL == (exec = find_executable(cl_argv[0])) ) )
{
- *need_help = 1;
+ missing_prog();
}
}
@@ -1384,5 +1428,5 @@ static void load_client(char* cl_argv[],
info->argv = cl_argv;
- if (*need_help) {
+ if (need_help) {
VG_(clexecfd) = -1;
info->argv0 = NULL;
@@ -1393,5 +1437,5 @@ static void load_client(char* cl_argv[],
ret = do_exec(exec, info);
if (ret != 0) {
- fprintf(stderr, "do_exec(%s) failed: %s\n", exec, strerror(ret));
+ fprintf(stderr, "valgrind: do_exec(%s) failed: %s\n", exec, strerror(ret));
exit(127);
}
@@ -1459,25 +1503,4 @@ Bool VG_(clo_lowlat_signals) = False;
-void VG_(bad_option) ( Char* opt )
-{
- VG_(shutdown_logging)();
- VG_(clo_log_to) = VgLogTo_Fd;
- VG_(clo_logfile_fd) = 2; /* stderr */
- VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
- VG_(exit)(1);
-}
-
-static void config_error ( Char* msg )
-{
- VG_(shutdown_logging)();
- VG_(clo_log_to) = VgLogTo_Fd;
- VG_(clo_logfile_fd) = 2; /* stderr */
- VG_(printf)(
- "valgrind: Startup or configuration error:\n %s\n", msg);
- VG_(printf)(
- "valgrind: Unable to start up properly. Giving up.\n");
- VG_(exit)(1);
-}
-
void usage ( Bool debug_help )
{
@@ -1561,5 +1584,4 @@ void usage ( Bool debug_help )
if (VG_(details).name) {
VG_(printf)(" user options for %s:\n", VG_(details).name);
- /* Don't print skin string directly for security, ha! */
if (VG_(needs).command_line_options)
SK_(print_usage)();
@@ -1580,9 +1602,5 @@ void usage ( Bool debug_help )
}
VG_(printf)(usage3, VG_BUGS_TO);
-
- VG_(shutdown_logging)();
- VG_(clo_log_to) = VgLogTo_Fd;
- VG_(clo_logfile_fd) = 2; /* stderr */
- VG_(exit)(1);
+ VG_(exit)(0);
}
@@ -1597,32 +1615,35 @@ static void pre_process_cmd_line_options
if (strcmp(VG_(vg_argv)[i], "--version") == 0) {
printf("valgrind-" VERSION "\n");
- exit(1);
+ exit(0);
- } else if (strcmp(VG_(vg_argv)[i], "--help") == 0) {
+ } else if (VG_CLO_STREQ(VG_(vg_argv)[i], "--help")) {
*need_help = 1;
- } else if (strcmp(VG_(vg_argv)[i], "--help-debug") == 0) {
+ } else if (VG_CLO_STREQ(VG_(vg_argv)[i], "--help-debug")) {
*need_help = 2;
- } else if (strncmp(VG_(vg_argv)[i], "--tool=", 7) == 0 ||
- strncmp(VG_(vg_argv)[i], "--skin=", 7) == 0) {
+ } else if (VG_CLO_STREQN(7, VG_(vg_argv)[i], "--tool=") ||
+ VG_CLO_STREQN(7, VG_(vg_argv)[i], "--skin=")) {
*tool = &VG_(vg_argv)[i][7];
- } else if (strncmp(VG_(vg_argv)[i], "--exec=", 7) == 0) {
+ } else if (VG_CLO_STREQN(7, VG_(vg_argv)[i], "--exec=")) {
*exec = &VG_(vg_argv)[i][7];
}
}
- /* If no tool specified, can give usage message without loading tool */
+ /* If no tool specified, can act appropriately without loading tool */
if (*tool == NULL) {
- if (!need_help)
- list_tools();
- usage(/*help-debug?*/False);
+ if (0 == *need_help) {
+ // neither --tool nor --help/--help-debug specified
+ missing_tool_option();
+ } else {
+ // Give help message, without any tool-specific help
+ usage(/*help-debug?*/2 == *need_help);
+ }
}
}
static void process_cmd_line_options
- ( UInt* client_auxv, Addr esp_at_startup,
- const char* toolname, Int need_help )
+ ( UInt* client_auxv, Addr esp_at_startup, const char* toolname )
{
Int i, eventually_logfile_fd;
@@ -1633,8 +1654,4 @@ static void process_cmd_line_options
eventually_logfile_fd = 2;
- /* Once logging is started, we can safely send messages pertaining
- to failures in initialisation. */
- VG_(startup_logging)();
-
/* Check for sane path in ./configure --prefix=... */
if (VG_LIBDIR[0] != '/')
@@ -1652,7 +1669,4 @@ static void process_cmd_line_options
}
- if (need_help)
- usage(/*--help-debug?*/need_help == 2);
-
/* We know the initial ESP is pointing at argc/argv */
VG_(client_argc) = *(Int *)esp_at_startup;
@@ -1888,5 +1902,5 @@ static void process_cmd_line_options
else if ( ! VG_(needs).command_line_options
|| ! SK_(process_cmd_line_option)(arg) ) {
- usage(/*--help-debug?*/need_help == 2);
+ VG_(bad_option)(arg);
}
}
@@ -2081,6 +2095,9 @@ static void process_cmd_line_options
if (VG_(clo_gen_suppressions) &&
!VG_(needs).core_errors && !VG_(needs).skin_errors) {
- config_error("Can't use --gen-suppressions=yes with this skin,\n"
- " as it doesn't generate errors.");
+ VG_(message)(Vg_UserMsg,
+ "Can't use --gen-suppressions=yes with this tool,");
+ VG_(message)(Vg_UserMsg,
+ "as it doesn't generate errors.");
+ VG_(bad_option)("--gen-suppressions=yes");
}
}
@@ -2718,4 +2735,13 @@ int main(int argc, char **argv)
//============================================================
+ //============================================================
+ // Command line argument handling order:
+ // * If --help/--help-debug are present, show usage message
+ // (if --tool is also present, that includes the tool-specific usage)
+ // * Then, if --tool is missing, abort with error msg
+ // * Then, if client is missing, abort with error msg
+ // * Then, if any cmdline args are bad, abort with error msg
+ //============================================================
+
// Get the current process datasize rlimit, and set it to zero.
// This prevents any internal uses of brk() from having any effect.
@@ -2796,5 +2822,5 @@ int main(int argc, char **argv)
// p: layout_remaining_space [so there's space]
//--------------------------------------------------------------
- load_client(cl_argv, exec, /*inout*/&need_help, &info, &client_eip);
+ load_client(cl_argv, exec, need_help, &info, &client_eip);
//--------------------------------------------------------------
@@ -2862,11 +2888,19 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
+ // If --tool and --help/--help-debug was given, now give the core+tool
+ // help message
+ // p: pre_clo_init()
+ //--------------------------------------------------------------
+ if (need_help) {
+ usage(/*--help-debug?*/2 == need_help);
+ }
+
+ //--------------------------------------------------------------
// Process Valgrind's + tool's command-line options
// p: load_tool() [for 'tool']
- // p: load_client() [for 'need_help']
// p: setup_file_descriptors() [for 'VG_(max_fd)']
// p: sk_pre_clo_init [to set 'command_line_options' need]
//--------------------------------------------------------------
- process_cmd_line_options(client_auxv, esp_at_startup, tool, need_help);
+ process_cmd_line_options(client_auxv, esp_at_startup, tool);
//--------------------------------------------------------------
@@ -3088,7 +3122,4 @@ int main(int argc, char **argv)
VGP_(done_profiling)();
- /* Must be after all messages are done */
- VG_(shutdown_logging)();
-
/* We're exiting, so nuke all the threads and clean up the proxy LWPs */
vg_assert(src == VgSrc_FatalSig ||
--- valgrind/none/tests/Makefile.am #1.36:1.37
@@ -13,4 +13,10 @@
bt_literal.vgtest \
closeall.stderr.exp closeall.vgtest \
+ cmdline1.stderr.exp cmdline1.stdout.exp cmdline1.vgtest \
+ cmdline2.stderr.exp cmdline2.stdout.exp cmdline2.vgtest \
+ cmdline3.stderr.exp cmdline3.vgtest \
+ cmdline4.stderr.exp cmdline4.vgtest \
+ cmdline5.stderr.exp cmdline5.vgtest \
+ cmdline6.stderr.exp cmdline6.vgtest \
coolo_sigaction.stderr.exp \
coolo_sigaction.stdout.exp coolo_sigaction.vgtest \
--- valgrind/tests/vg_regtest.in #1.21:1.22
@@ -114,7 +114,7 @@
#
# Also checks the program exists and is executable.
-sub validate_program ($$$)
+sub validate_program ($$$$)
{
- my ($dir, $prog, $must_be_executable) = @_;
+ my ($dir, $prog, $must_exist, $must_be_executable) = @_;
# If absolute path, leave it alone. If relative, make it
@@ -122,7 +122,9 @@
# dirs and still use it.
$prog = "$dir/$prog" if ($prog !~ /^\//);
- (-f $prog) or die "vg_regtest: `$prog' not found or not a file ($dir)\n";
+ if ($must_exist) {
+ (-f $prog) or die "vg_regtest: `$prog' not found or not a file ($dir)\n";
+ }
if ($must_be_executable) {
- (-x $prog) or die "vg_regtest: `$prog' not executable ($dir)\n";
+ (-x $prog) or die "vg_regtest: `$prog' not executable ($dir)\n";
}
@@ -148,5 +150,5 @@
}
}
- $valgrind = validate_program($tests_dir, $valgrind, 0);
+ $valgrind = validate_program($tests_dir, $valgrind, 1, 0);
if ($alldirs) {
@@ -174,5 +176,5 @@
# Every test directory must have a "filter_stderr"
- $stderr_filter = validate_program(".", $default_stderr_filter, 1);
+ $stderr_filter = validate_program(".", $default_stderr_filter, 1, 1);
open(INPUTFILE, "< $f") || die "File $f not openable\n";
@@ -182,11 +184,11 @@
$vgopts = $1;
} elsif ($line =~ /^\s*prog:\s*(.*)$/) {
- $prog = validate_program(".", $1, 1);
+ $prog = validate_program(".", $1, 0, 0);
} elsif ($line =~ /^\s*args:\s*(.*)$/) {
$args = $1;
} elsif ($line =~ /^\s*stdout_filter:\s*(.*)$/) {
- $stdout_filter = validate_program(".", $1, 1);
+ $stdout_filter = validate_program(".", $1, 1, 1);
} elsif ($line =~ /^\s*stderr_filter:\s*(.*)$/) {
- $stderr_filter = validate_program(".", $1, 1);
+ $stderr_filter = validate_program(".", $1, 1, 1);
} elsif ($line =~ /^\s*cpu_test:\s*(.*)$/) {
$cpu_test = $1;
@@ -200,5 +202,5 @@
if (!defined $prog) {
- die "no `prog:' line in `$f'\n";
+ $prog = ""; # allow no prog for testing error and --help cases
}
}
|