[PATCH v2] GDB/testsuite: Add a way to send multiple init commands

Maciej W. Rozycki
2014-07-10T00:17:54Z

On Fri, 20 Jun 2014, Pedro Alves wrote:

> > 2014-06-11 Maciej W. Rozycki <macro@mips.com>
> > Maciej W. Rozycki <macro@codesourcery.com>
> >
> > * lib/gdb.exp (gdb_run_cmd): Process `gdb_init_commands'.
> > * lib/mi-support.exp (mi_run_cmd): Process `gdb_init_commands'.
> > * README (Board Settings): Document `gdb_init_command' and
> > `gdb_init_commands'.
>
> I don't particularly see much need for this -- I do this in my
> boards instead:
>
> set GDBFLAGS ""
> set GDBFLAGS "${GDBFLAGS} -ex \"set breakpoint always-inserted on\""
> set GDBFLAGS "${GDBFLAGS} -ex \"set target-async 1\""
>
> See:
>
> https://sourceware.org/gdb/wiki/TestingGDB#Passing_an_option_to_GDB_.2BAC8_Running_the_whole_test_suite_in_a_non-default_mode
>
> But, given gdb_init_command exists and this can be made
> non-intrusive, it's fine with me to add the new option.

That and I think there are two issues with passing commands as
command-line arguments:

1. They are always executed, perhaps unnecessarily whereas
`gdb_init_command' and consequently `gdb_init_commands' are only
interpreted when a target connection is about to be made (this is more
of an aesthetic matter, but still).

2. Some environments have a limit, maybe quite low, on the maximum length
of a command line or command-line arguments they accept (now that is
more real).

BTW, in updating DejaGNU documentation that refers to `gdb_init_command'
I've noticed it lists a command that pokes at a CPU register there -- has
the semantics of the setting changed sometime, perhaps long ago? Does
anybody know/remember?

> Thought, I'd much prefer if this code that appears twice:
>
> > + set commands ""
> > if [target_info exists gdb_init_command] {
> > - send_gdb "[target_info gdb_init_command]\n"
> > + lappend commands [target_info gdb_init_command]
> > + }
> > + if [target_info exists gdb_init_commands] {
> > + set commands [concat $commands [target_info gdb_init_commands]]
> > + }
> > + foreach command $commands {
>
> was factored out to a procedure that returns the command list. Like:
>
> # Comment here
> proc gdb_init_commands {} {
> set commands {}
> if [target_info exists gdb_init_command] {
> lappend commands [target_info gdb_init_command]
> }
> if [target_info exists gdb_init_commands] {
> set commands [concat $commands [target_info gdb_init_commands]]
> }
> return commands
> }
>
> And then, both users can do
>
> foreach command [gdb_init_commands] {

Done, as below, and retested. Any other questions or comments?
Otherwise OK to apply?

Here's the original description repeated, for a reference:

--------------------------------------------------------------------------
Right now we provide a board info entry, `gdb_init_command', that allows
one to send a single command to GDB before the program to be debugged is
started. This is useful e.g. for slow remote targets to change the
default "remotetimeout" setting. Occasionally I found a need to send
multiple commands instead, however this cannot be achieved with
`gdb_init_command'.

This change therefore extends the mechanism by adding a TCL list of GDB
commands to send, via a board info entry called `gdb_init_commands'.
There is no limit as to the number of commands put there. The old
`gdb_init_command' mechanism remains supported for compatibility with
existing people's environments. I have a separate change for DejaGNU too,
being posted right away, that adds an `add_board_info' procedure that
makes it easy to append entries there; it's not strictly needed here or
anywhere in our testsuite though.
--------------------------------------------------------------------------

2014-07-10 Maciej W. Rozycki <macro@mips.com>
Maciej W. Rozycki <macro@codesourcery.com>

* lib/gdb-utils.exp: New file.
* lib/gdb.exp (gdb_run_cmd): Call gdb_init_commands, replacing
inline `gdb_init_command' processing.
* lib/mi-support.exp (mi_run_cmd): Likewise.
* README: Document `gdb_init_command' and `gdb_init_commands'.

Maciej

gdb-init-commands.diff
Index: gdb-fsf-trunk-quilt/gdb/testsuite/README
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/testsuite/README 2014-06-03 15:23:24.000000000 +0100
+++ gdb-fsf-trunk-quilt/gdb/testsuite/README 2014-06-11 19:29:49.538972371 +0100
@@ -271,6 +271,16 @@ gdb,use_precord

The board supports process record.

+gdb_init_command
+gdb_init_commands
+
+ Commands to send to GDB every time a program is about to be run. The
+ first of these settings defines a single command as a string. The
+ second defines a TCL list of commands being a string each. The commands
+ are sent one by one in a sequence, first from `gdb_init_command', if any,
+ followed by individual commands from `gdb_init_command', if any, in this
+ list's order.
+
gdb_server_prog

The location of GDBserver. If GDBserver somewhere other than its
Index: gdb-fsf-trunk-quilt/gdb/testsuite/lib/gdb.exp
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/testsuite/lib/gdb.exp 2014-06-07 18:27:52.000000000 +0100
+++ gdb-fsf-trunk-quilt/gdb/testsuite/lib/gdb.exp 2014-06-20 23:48:39.868925158 +0100
@@ -27,6 +27,7 @@ if {$tool == ""} {

load_lib libgloss.exp
load_lib cache.exp
+load_lib gdb-utils.exp

global GDB

@@ -209,8 +210,8 @@ proc delete_breakpoints {} {
proc gdb_run_cmd {args} {
global gdb_prompt use_gdb_stub

- if [target_info exists gdb_init_command] {
- send_gdb "[target_info gdb_init_command]\n"
+ foreach command [gdb_init_commands] {
+ send_gdb "$command\n"
gdb_expect 30 {
-re "$gdb_prompt $" { }
default {
@@ -311,8 +312,8 @@ proc gdb_run_cmd {args} {
proc gdb_start_cmd {args} {
global gdb_prompt use_gdb_stub

- if [target_info exists gdb_init_command] {
- send_gdb "[target_info gdb_init_command]\n"
+ foreach command [gdb_init_commands] {
+ send_gdb "$command\n"
gdb_expect 30 {
-re "$gdb_prompt $" { }
default {
Index: gdb-fsf-trunk-quilt/gdb/testsuite/lib/mi-support.exp
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/testsuite/lib/mi-support.exp 2014-06-07 18:27:50.000000000 +0100
+++ gdb-fsf-trunk-quilt/gdb/testsuite/lib/mi-support.exp 2014-06-20 23:47:57.868926864 +0100
@@ -17,6 +17,8 @@

# Test setup routines that work with the MI interpreter.

+load_lib gdb-utils.exp
+
# The variable mi_gdb_prompt is a regexp which matches the gdb mi prompt.
# Set it if it is not already set.
global mi_gdb_prompt
@@ -859,8 +861,8 @@ proc mi_run_cmd_full {use_mi_command arg
set run_match ""
}

- if [target_info exists gdb_init_command] {
- send_gdb "[target_info gdb_init_command]\n"
+ foreach command [gdb_init_commands] {
+ send_gdb "$command\n"
gdb_expect 30 {
-re "$mi_gdb_prompt$" { }
default {
Index: gdb-fsf-trunk-quilt/gdb/testsuite/lib/gdb-utils.exp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-fsf-trunk-quilt/gdb/testsuite/lib/gdb-utils.exp 2014-06-20 23:47:20.858922875 +0100
@@ -0,0 +1,30 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Utility procedures, shared between test suite domains.
+
+# A helper procedure to retrieve commands to send to GDB before a program
+# is started.
+
+proc gdb_init_commands {} {
+ set commands ""
+ if [target_info exists gdb_init_command] {
+ lappend commands [target_info gdb_init_command]
+ }
+ if [target_info exists gdb_init_commands] {
+ set commands [concat $commands [target_info gdb_init_commands]]
+ }
+ return $commands
+}