From: Alan Hayward <Alan.Hayward@arm.com>
To: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Cc: nd <nd@arm.com>, Alan Hayward <Alan.Hayward@arm.com>
Subject: [PATCH] testsuite: Record all gdb input to gdb.in
Date: Mon, 29 Apr 2019 16:08:00 -0000 [thread overview]
Message-ID: <20190429160736.34276-1-alan.hayward@arm.com> (raw)
When debugging testsuite failures, it can be awkward parsing gdb.log to
obtain all the commands run in order to manually re-run the test.
This patch adds the functionality to save all gdb commands to the file gdb.in
when the testsuite is run. The file is saved in the directory for the test and
if gdb is restarted then .1, .2, .3 etc is added to the filename.
Once a test has been run, the .in file can be used to re-run the test in the
following way:
gdb -x outputs/gdb.store/gdb.in outputs/gdb.store/store
Note, this functionality is ALWAYS on when running a test. I considered this
would be more useful than making it optional.
The code works by intercepting send_gdb. I've added a TYPE to ensure that any
commands that would destroy the playback are kept from the log (for example the
Y from an answer to a y/n question).
I've re-run a random selection of .in files to check they do not error. Logs with
commands such as "attach <pid>" will not directly work when re-run.
gdb/testsuite/ChangeLog:
2019-04-29 Alan Hayward <alan.hayward@arm.com>
* lib/gdb.exp (gdb_unload): Mark Y as an answer.
(delete_breakpoints): Likewise.
(gdb_run_cmd): Likewise.
(gdb_start_cmd): Likewise.
(gdb_starti_cmd): Likewise.
(gdb_internal_error_resync): Likewise.
(gdb_test_multiple): Likewise.
(gdb_reinitialize_dir): Likewise.
(default_gdb_exit): Likewise.
(gdb_file_cmd): Mark kill as optional.
(default_gdb_start): Call gdb_stdin_log_init.
(send_gdb): Call gdb_stdin_log_write.
(rerun_to_main): Mark Y as an answer.
(gdb_stdin_log_init): New function.
(gdb_stdin_log_write): Likewise.
---
gdb/testsuite/lib/gdb.exp | 90 +++++++++++++++++++++++++++++++--------
1 file changed, 72 insertions(+), 18 deletions(-)
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index c5042ae28f..e08abd6e98 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -167,11 +167,11 @@ proc gdb_unload {} {
-re "No executable file now\[^\r\n\]*\[\r\n\]" { exp_continue }
-re "No symbol file now\[^\r\n\]*\[\r\n\]" { exp_continue }
-re "A program is being debugged already.*Are you sure you want to change the file.*y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-re "Discard symbol table from .*y or n.*$" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-re "$gdb_prompt $" {}
@@ -201,7 +201,7 @@ proc delete_breakpoints {} {
set deleted 0
gdb_test_multiple "delete breakpoints" "$msg" {
-re "Delete all breakpoints.*y or n.*$" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-re "$gdb_prompt $" {
@@ -307,7 +307,7 @@ proc gdb_run_cmd {args} {
set start_attempt 0
}
-re "Line.* Jump anyway.*y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
}
-re "The program is not being run.*$gdb_prompt $" {
if { [gdb_reload] != 0 } {
@@ -335,7 +335,7 @@ proc gdb_run_cmd {args} {
# may test for additional start-up messages.
gdb_expect 60 {
-re "The program .* has been started already.*y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-notransfer -re "Starting program: \[^\r\n\]*" {}
@@ -374,7 +374,7 @@ proc gdb_start_cmd {args} {
# may test for additional start-up messages.
gdb_expect 60 {
-re "The program .* has been started already.*y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-notransfer -re "Starting program: \[^\r\n\]*" {
@@ -411,7 +411,7 @@ proc gdb_starti_cmd {args} {
send_gdb "starti $args\n"
gdb_expect 60 {
-re "The program .* has been started already.*y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-re "Starting program: \[^\r\n\]*" {
@@ -673,11 +673,11 @@ proc gdb_internal_error_resync {} {
while {$count < 10} {
gdb_expect {
-re "Quit this debugging session\\? \\(y or n\\) $" {
- send_gdb "n\n"
+ send_gdb "n\n" answer
incr count
}
-re "Create a core file of GDB\\? \\(y or n\\) $" {
- send_gdb "n\n"
+ send_gdb "n\n" answer
incr count
}
-re "$gdb_prompt $" {
@@ -971,7 +971,7 @@ proc gdb_test_multiple { command message user_code } {
set result -1
}
-re "\\((y or n|y or \\\[n\\\]|\\\[y\\\] or n)\\) " {
- send_gdb "n\n"
+ send_gdb "n\n" answer
gdb_expect -re "$gdb_prompt $"
fail "$message (got interactive prompt)"
set result -1
@@ -1421,7 +1421,7 @@ proc gdb_reinitialize_dir { subdir } {
send_gdb "dir\n"
gdb_expect 60 {
-re "Reinitialize source path to empty.*y or n. " {
- send_gdb "y\n"
+ send_gdb "y\n" answer
gdb_expect 60 {
-re "Source directories searched.*$gdb_prompt $" {
send_gdb "dir $subdir\n"
@@ -1481,7 +1481,7 @@ proc default_gdb_exit {} {
send_gdb "quit\n"
gdb_expect 10 {
-re "y or n" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-re "DOSEXIT code" { }
@@ -1538,11 +1538,12 @@ proc gdb_file_cmd { arg } {
}
# The file command used to kill the remote target. For the benefit
- # of the testsuite, preserve this behavior.
- send_gdb "kill\n"
+ # of the testsuite, preserve this behavior. Mark as optional so it doesn't
+ # get written to the stdin log.
+ send_gdb "kill\n" optional
gdb_expect 120 {
-re "Kill the program being debugged. .y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
verbose "\t\tKilling previous program being debugged"
exp_continue
}
@@ -1569,7 +1570,7 @@ proc gdb_file_cmd { arg } {
return 0
}
-re "Load new symbol table from \".*\".*y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
gdb_expect 120 {
-re "Reading symbols from.*$gdb_prompt $" {
verbose "\t\tLoaded $arg with new symbol table into $GDB"
@@ -1665,6 +1666,8 @@ proc default_gdb_start { } {
return 0
}
+ gdb_stdin_log_init
+
set res [gdb_spawn]
if { $res != 0} {
return $res
@@ -3930,11 +3933,15 @@ proc gdb_compile_objc {source dest type options} {
}
}
-proc send_gdb { string } {
+# Send a command to GDB.
+# For options for TYPE see gdb_stdin_log_write
+
+proc send_gdb { string {type standard}} {
global suppress_flag
if { $suppress_flag } {
return "suppressed"
}
+ gdb_stdin_log_write $string $type
return [remote_send host "$string"]
}
@@ -5062,7 +5069,7 @@ proc rerun_to_main {} {
send_gdb "run\n"
gdb_expect {
-re "The program .* has been started already.*y or n. $" {
- send_gdb "y\n"
+ send_gdb "y\n" answer
exp_continue
}
-re "Starting program.*$gdb_prompt $"\
@@ -6423,5 +6430,52 @@ proc gdbserver_debug_enabled { } {
return 0
}
+# Open the file for logging gdb input
+
+proc gdb_stdin_log_init { } {
+ global in_file
+ global in_file_count
+
+ if {[info exists in_file]} {
+ # Close existing file. Increase count.
+ catch "close $in_file"
+ incr in_file_count
+ set logfile [standard_output_file gdb.in.$in_file_count]
+ } else {
+ # First time opening.
+ set in_file_count 0
+ set logfile [standard_output_file gdb.in]
+ }
+
+ set in_file [open $logfile w]
+}
+
+# Write to the file for logging gdb input.
+# TYPE can be one of the following:
+# STANDARD : Default. Standard message written to the log
+# ANSWER : Answer to a question (eg "Y"). Not written the log.
+# OPTIONAL : Optional message. Not written to the log.
+
+proc gdb_stdin_log_write { message {type standard} } {
+
+ global in_file
+ if {![info exists in_file]} {
+ return
+ }
+
+ # Check message types.
+ switch -regexp -- $type {
+ "answer" {
+ return
+ }
+ "optional" {
+ return
+ }
+ }
+
+ #Write to the log
+ puts -nonewline $in_file "$message"
+}
+
# Always load compatibility stuff.
load_lib future.exp
--
2.20.1 (Apple Git-117)
next reply other threads:[~2019-04-29 16:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-29 16:08 Alan Hayward [this message]
2019-04-30 15:06 ` Tom Tromey
2019-04-30 18:02 ` Alan Hayward
2019-05-01 14:20 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190429160736.34276-1-alan.hayward@arm.com \
--to=alan.hayward@arm.com \
--cc=gdb-patches@sourceware.org \
--cc=nd@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).