Re: [PATCH] add -s option to make -break-insert support dprintf

Hui Zhu
2013-04-15T14:58:00Z

[-- Attachment #1: Type: text/plain, Size: 3052 bytes --]

On Fri, Apr 12, 2013 at 7:34 PM, Pedro Alves <palves@redhat.com> wrote:
> On 04/12/2013 11:38 AM, Hui Zhu wrote:
>>> >
>>> > I still get:
>>> >
>>> > $ make check gdbserver RUNTESTFLAGS="--target_board=native-gdbserver mi-dprintf.exp"
>> This part is really odd.
>> In my part, without "sleep 1" will random get fail with "Set dprintf
>> style to agent ".
>> The reason of fail is test try to check the output before it call
>> send_gdb "set dprintf-style agent\n".
>> This is why I add a "sleep 1" for it.
>>
>> But looks it still not OK in your part, so I change it to:
>> mi_gdb_test "pwd" ".*"
>>
>> If it is still not OK in your part, I suggest remove this part of test
>> because it is not very important for this test. The "set
>> dprintf-style agent" is tested in "dprintf.exp".
>>
>
> No, it's not okay. And it's not okay to just sweep it under the rug.
>
> I believe the problem is that the test is sending CLI resumption commands:
>
> + mi_gdb_test "continue" ".*At foo entry.*arg=1234, g=1234.*" "mi 1st dprintf"
> + mi_gdb_test "continue" ".*At foo entry.*arg=1235, g=2222.*" "mi 2nd dprintf"
>
> "continue" sent from MI causes two prompts to appear:
>
> (gdb)
> continue
> &"continue\n"
> ~"Continuing.\n"
> ^running
> *running,thread-id="all"
> (gdb)
> =breakpoint-modified,bkpt={number="6",type="breakpoint",disp="keep",enabled="y",addr="0x000000000045a3ff",func="main",file="../../src/gdb/gdb.c",fullname="/home/pedro/gdb/mygit/src/gdb/gdb.c",line="32",thread-groups=["i1"],times="1",original-location="/home/pedro/gdb/mygit/src/gdb/gdb.c:32"}
> ~"\nBreakpoint "
> ~"6, main (argc=1, argv=0x7fffffffdc58) at ../../src/gdb/gdb.c:32\n"
> ~"32\t args.use_windows = 0;\n"
> *stopped,reason="breakpoint-hit",disp="keep",bkptno="6",frame={addr="0x000000000045a3ff",func="main",args=[{name="argc",value="1"},{name="argv",value="0x7fffffffdc58"}],file="../../src/gdb/gdb.c",fullname="/home/pedro/gdb/mygit/src/gdb/gdb.c",line="32"},thread-id="1",stopped-threads="all",core="0"
> (gdb)
>
> and that is confusing the test (the regex for the prompt is probably stopping
> at the first prompt sometimes).
>
> The test should be adjusted to do MI -exec-continue instead, with
> mi_execute_to "exec-continue", mi_send_resuming_command "exec-continue"
> or something like that.
>
> BTW, you don't need to use gdbserver to trigger the issue. Native
> works too. E.g., leave this running, and eventually, it should FAIL
> and stop:
>
> $ (set -e; while true; do make check RUNTESTFLAGS="mi-dprintf.exp"; done)
>
> gdb/contrib/expect-read1.sh probably makes this reproducible all
> the time, though I haven't tried.

Post a new version change the continue to mi_run_cmd, gdb_expect and
mi_send_resuming_command.
It works OK with loop test.

Please help me review it.

Thanks,
Hui

>
> --
> Pedro Alves
>

2013-04-15 Hui Zhu <hui@codesourcery.com>

* gdb.mi/Makefile.in (PROGS): Add "mi-dprintf".
* gdb.mi/mi-dprintf.exp, gdb.mi/mi-dprintf.c: New.

[-- Attachment #2: mi-dprintf-test.txt --]
[-- Type: text/plain, Size: 7565 bytes --]

--- a/testsuite/gdb.mi/Makefile.in
+++ b/testsuite/gdb.mi/Makefile.in
@@ -3,7 +3,7 @@ srcdir = @srcdir@

PROGS = basics c_variable cpp_variable var-cmd dw2-ref-missing-frame \
gdb669-pthreads gdb701 gdb792 mi-async mi-basics mi-break \
- mi-cli mi-console mi-disassemble mi-eval mi-file \
+ mi-cli mi-console mi-disassemble mi-dprintf mi-eval mi-file \
mi-file-transfer mi-non-stop mi-non-stop-exit \
mi-ns-stale-regcache mi-nsintrall mi-nsmoribund mi-nsthrexec \
mi-pending mi-pthreads mi-read-memory mi-regs mi-return \
--- /dev/null
+++ b/testsuite/gdb.mi/mi-dprintf.c
@@ -0,0 +1,59 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Hui Zhu <hui@codesourcery.com>
+
+ 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/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static int g;
+
+void
+foo (int arg)
+{
+ g += arg;
+ g *= 2; /* set dprintf 1 here */
+ g /= 2.5; /* set breakpoint 1 here */
+}
+
+int
+main (int argc, char *argv[])
+{
+ int loc = 1234;
+
+ /* Ensure these functions are available. */
+ printf ("kickoff %d\n", loc);
+ fprintf (stderr, "also to stderr %d\n", loc);
+
+ foo (loc++);
+ foo (loc++);
+ foo (loc++);
+ return g;
+}
+
+/* Make sure function 'malloc' is linked into program. On some bare-metal
+ port, if we don't use 'malloc', it will not be linked in program. 'malloc'
+ is needed, otherwise we'll see such error message
+ evaluation of this expression requires the program to have a function
+ "malloc". */
+
+void
+bar (void)
+{
+ void *p = malloc (16);
+
+ free (p);
+}
--- /dev/null
+++ b/testsuite/gdb.mi/mi-dprintf.exp
@@ -0,0 +1,148 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+# Contributed by Hui Zhu <hui@codesourcery.com>
+
+# 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/>.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+standard_testfile
+
+if {[build_executable $testfile.exp $testfile $srcfile {debug}] == -1} {
+ untested "failed to compile $testfile"
+ return -1
+}
+
+mi_delete_breakpoints
+
+set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
+set dp_location1 [gdb_get_line_number "set dprintf 1 here"]
+
+mi_run_to_main
+
+mi_gdb_test "1-break-insert -s" \
+ "1\\^error,msg=\"-break-insert: Option -s requires an argument\"" "mi insert without location"
+
+mi_gdb_test "2-break-insert -s foo" \
+ "2\\^error,msg=\"-break-insert: Missing <location>\"" "mi insert breakpoint without format string"
+
+mi_gdb_test "3-break-insert -s 29" \
+ "3\\^error,msg=\"-break-insert: Missing <location>\"" "mi insert second breakpoint without format string"
+
+mi_gdb_test "-break-insert main" ".*" "mi insert breakpoint main"
+mi_delete_breakpoints
+
+mi_gdb_test "4-break-insert -s \"\\\"At foo entry\\\\n\\\"\" foo" \
+ "4\\^done,bkpt=\{number=\".*\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\".*\".*" "mi insert dprintf foo"
+
+mi_gdb_test "5-break-insert -s \"\\\"arg=%d, g=%d\\\\n\\\", arg, g\" $dp_location1" \
+ "5\\^done,bkpt=\{number=\".*\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\"$dp_location1\".*" \
+ "mi insert dprintf dp_location1"
+
+mi_gdb_test "6-break-info" \
+ "6\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\},\{width=\".*\",alignment=\".*\",col_name=\"type\",colhdr=\"Type\"\},\{width=\".*\",alignment=\".*\",col_name=\"disp\",colhdr=\"Disp\"\},\{width=\".*\",alignment=\".*\",col_name=\"enabled\",colhdr=\"Enb\"\},\{width=\".*\",alignment=\".*\",col_name=\"addr\",colhdr=\"Address\"\},\{width=\".*\",alignment=\".*\",col_name=\"what\",colhdr=\"What\"\}\\\],body=\\\[bkpt=\{number=\"3\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\".*\".*,bkpt=\{number=\".*\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\"$dp_location1\".*" \
+ "mi info dprintf"
+
+mi_gdb_test "-break-insert $bp_location1" ".*" "mi insert breakpoint bp_location1"
+
+proc mi_continue_dprintf {args} {
+ with_test_prefix $args {
+ global mi_gdb_prompt
+
+ mi_run_cmd
+ set msg "mi 1st dprintf"
+ gdb_expect {
+ -re ".*At foo entry.*arg=1234, g=1234.*" {
+ pass $msg
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail $msg
+ }
+ timeout {
+ fail $msg
+ }
+ }
+ mi_expect_stop ".*" ".*" ".*" ".*" ".*" "" "$msg stop"
+
+ set msg "mi 2nd dprintf"
+ mi_send_resuming_command "exec-continue" "$msg continue"
+ gdb_expect {
+ -re ".*At foo entry.*arg=1235, g=2222.*" {
+ pass $msg
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail $msg
+ }
+ timeout {
+ fail $msg
+ }
+ }
+ }
+}
+
+mi_continue_dprintf "gdb"
+
+# The "call" style depends on having I/O functions available, so test.
+
+if ![target_info exists gdb,noinferiorio] {
+
+ # Now switch styles and rerun; in the absence of redirection the
+ # output should be the same.
+
+ mi_gdb_test "set dprintf-style call" ".*" "mi set dprintf style to call"
+ mi_continue_dprintf "call"
+
+ mi_gdb_test "set dprintf-function fprintf" ".*" "mi set dprintf-channel stderr"
+ mi_gdb_test "set dprintf-channel stderr" ".*" "mi set dprintf channel"
+ mi_continue_dprintf "fprintf"
+}
+
+# To make sure set dprintf-style agent get right output.
+mi_gdb_test "pwd" ".*"
+
+set target_can_dprintf 0
+set msg "set dprintf style to agent"
+send_gdb "set dprintf-style agent\n"
+gdb_expect {
+ -re "warning: Target cannot run dprintf commands, falling back to GDB printf.*$mi_gdb_prompt$" {
+ unsupported "$msg"
+ }
+ -re ".*done.*$mi_gdb_prompt$" {
+ set target_can_dprintf 1
+ pass "$msg"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "$msg"
+ }
+ timeout {
+ fail "$msg"
+ }
+}
+
+if $target_can_dprintf {
+ mi_run_cmd
+
+ mi_gdb_test "continue" ".*breakpoint-hit.*func=\"foo\".*" "mi 1st dprintf, agent"
+
+ mi_gdb_test "continue" ".*breakpoint-hit.*func=\"foo\".*" "mi 2nd dprintf, agent"
+
+ mi_gdb_test "6-break-info" ".*modified.*" "mi info dprintf second time"
+}
+
+mi_gdb_test "set dprintf-style foobar" ".*error.*" "mi set dprintf style to an unrecognized type"