diff options
-rw-r--r-- | gdb/main.c | 17 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/corefile.exp | 116 | ||||
-rw-r--r-- | gdbsupport/common-utils.cc | 21 | ||||
-rw-r--r-- | gdbsupport/common-utils.h | 5 |
4 files changed, 88 insertions, 71 deletions
@@ -1235,7 +1235,8 @@ captured_main_1 (struct captured_main_args *context) if (corearg != NULL) { - ret = catch_command_errors (core_file_command, corearg, + ret = catch_command_errors (core_file_command, + make_quoted_string (corearg).c_str (), !batch_flag); } else if (pidarg != NULL) @@ -1253,16 +1254,18 @@ captured_main_1 (struct captured_main_args *context) ret = catch_command_errors (attach_command, pid_or_core_arg, !batch_flag); if (ret == 0) - ret = catch_command_errors (core_file_command, - pid_or_core_arg, - !batch_flag); + ret = catch_command_errors + (core_file_command, + make_quoted_string (pid_or_core_arg).c_str (), + !batch_flag); } else { /* Can't be a pid, better be a corefile. */ - ret = catch_command_errors (core_file_command, - pid_or_core_arg, - !batch_flag); + ret = catch_command_errors + (core_file_command, + make_quoted_string (pid_or_core_arg).c_str (), + !batch_flag); } } diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp index dc3c8b1..039f189 100644 --- a/gdb/testsuite/gdb.base/corefile.exp +++ b/gdb/testsuite/gdb.base/corefile.exp @@ -34,81 +34,69 @@ if {$corefile == ""} { return 0 } -# Test that we can simply startup with a "-core=$corefile" command line arg -# and recognize that the core file is a valid, usable core file. -# To do this, we must shutdown the currently running gdb and restart -# with the -core args. We can't use gdb_start because it looks for -# the first gdb prompt, and the message we are looking for occurs -# before the first prompt. +# Start GDB with COREFILE passed as a command line argument. COREOPT +# is prefixed before COREFILE and is the command line flag to specify +# the corefile, i.e. one of '--core=', '-core=', '-c '. # -# Another problem is that on some systems (solaris for example), there -# is apparently a limit on the length of a fully specified path to -# the corefile executable, at about 80 chars. For this case, consider -# it a pass, but note that the program name is bad. - -gdb_exit -if {$verbose>1} { - send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$corefile\n" -} - -set oldtimeout $timeout -set timeout [expr "$timeout + 60"] -verbose "Timeout is now $timeout seconds" 2 -eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$corefile" -expect { - -re "Couldn't find .* registers in core file.*$gdb_prompt $" { - fail "args: -core=[file tail $corefile] (couldn't find regs)" - } - -re "Core was generated by .*corefile.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: -core=[file tail $corefile]" - } - -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: -core=[file tail $corefile] (with bad program name)" - } - -re ".*registers from core file: File in wrong format.* $" { - fail "args: -core=[file tail $corefile] (could not read registers from core file)" - } - -re ".*$gdb_prompt $" { fail "args: -core=[file tail $corefile]" } - timeout { fail "(timeout) starting with -core" } -} - - +# If BINFILE is not the empty string then it is also added as a +# command line argument and is the executable to load. # -# Test that startup with both an executable file and -core argument. -# See previous comments above, they are still applicable. -# - -close +# TESTNAME is used for naming the tests. +proc start_gdb_with_corefile { testname coreopt corefile {binfile ""} } { + gdb_exit -if {$verbose>1} { - send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$corefile\n" -} + global GDBFLAGS + save_vars { GDBFLAGS } { + append GDBFLAGS " $binfile $coreopt$corefile" + set res [gdb_spawn] + if { $res != 0 } { + fail "$testname (start GDB)" + return + } -eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$corefile" -expect { - -re "Core was generated by .*corefile.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: execfile -core=[file tail $corefile]" - } - -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: execfile -core=[file tail $corefile] (with bad program name)" - } - -re ".*registers from core file: File in wrong format.* $" { - fail "args: execfile -core=[file tail $corefile] (could not read registers from core file)" + gdb_test_multiple "" $testname { + -re -wrap "Couldn't find .* registers in core file.*" { + fail "$gdb_test_name (couldn't find regs)" + } + -re -wrap "Core was generated by `[string_to_regexp $corefile]'\\.\r\n.*\#0 \[^\r\n\]+\(\).*" { + pass $gdb_test_name + } + -re -wrap "Core was generated by .*\r\n\#0 .*\(\).*" { + # This case is hit when the executable name is + # truncated in the output. + pass "$gdb_test_name (with bad program name)" + } + -re -wrap ".*registers from core file: File in wrong format.*" { + fail "$gdb_test_name (could not read registers from core file)" + } + -re -wrap "" { + fail "$gdb_test_name (core not loaded)" + } + } } - -re ".*$gdb_prompt $" { fail "args: execfile -core=[file tail $corefile]" } - timeout { fail "(timeout) starting with -core" } } -set timeout $oldtimeout -verbose "Timeout is now $timeout seconds" 2 -close +# Create a copy of the corefile, but with a space in the filename. +set alt_corefile [standard_output_file "core\\ file.core"] +remote_exec host "cp $corefile $alt_corefile" + +# Test that we can start GDB with a corefile command line argument and +# recognize that the core file is a valid, usable core file. We test +# using '--core=...', '-core=...', and '-c ...' style arguments. We +# also test with, and without an executable. +foreach_with_prefix coreopt {--core= -core= "-c "} { + start_gdb_with_corefile "just core file" $coreopt $corefile + start_gdb_with_corefile "core file and executable" $coreopt $corefile $binfile + start_gdb_with_corefile "core file with white space in name" \ + $coreopt $alt_corefile + start_gdb_with_corefile "core file with white space in name and executable" \ + $coreopt $alt_corefile $binfile +} # Now restart normally. -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_load ${binfile} +clean_restart $binfile # Test basic corefile recognition via core-file command. diff --git a/gdbsupport/common-utils.cc b/gdbsupport/common-utils.cc index 91c14a0..af25bf0 100644 --- a/gdbsupport/common-utils.cc +++ b/gdbsupport/common-utils.cc @@ -222,6 +222,27 @@ extract_string_maybe_quoted (const char **arg) return result; } +/* See gdbsupport/common-utils.h. */ + +std::string +make_quoted_string (const char *str) +{ + gdb_assert (str != nullptr); + + std::string result; + + for (; *str != '\0'; ++str) + { + const char ch = *str; + + if (strchr ("\"' \t\n", ch) != nullptr) + result.push_back ('\\'); + result.push_back (ch); + } + + return result; +} + /* The bit offset of the highest byte in a ULONGEST, for overflow checking. */ diff --git a/gdbsupport/common-utils.h b/gdbsupport/common-utils.h index 2fb2291..6515838 100644 --- a/gdbsupport/common-utils.h +++ b/gdbsupport/common-utils.h @@ -84,6 +84,11 @@ char *savestring (const char *ptr, size_t len); std::string extract_string_maybe_quoted (const char **arg); +/* Return a copy of STR, but with any white space, single quote, or + double quote characters escaped with a backslash. */ + +std::string make_quoted_string (const char *str); + /* The strerror() function can return NULL for errno values that are out of range. Provide a "safe" version that always returns a printable string. This version is also thread-safe. */ |