This is the mail archive of the
gdb-prs@sources.redhat.com
mailing list for the GDB project.
pending/969: [RFA] Copy the command lines and value when copying a bpstat.
- From: Klee Dienes <klee at apple dot com>
- To: gdb-gnats at sources dot redhat dot com
- Date: Wed, 30 Oct 2002 04:27:00 -0500
- Subject: pending/969: [RFA] Copy the command lines and value when copying a bpstat.
>Number: 969
>Category: pending
>Synopsis: [RFA] Copy the command lines and value when copying a bpstat.
>Confidential: yes
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Thu Jan 30 03:28:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:
>Release:
>Organization:
>Environment:
>Description:
--Apple-Mail-3--319237899
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
If you try to call a function in the inferior from user-defined
breakpoint commands, GDB crashes:
$ ./gdb -nx -q ./gdb
(gdb) break main
Breakpoint 1 at 0x8074686: file
./../../source/cygnus.cygnus/gdb/gdb.c, line 29.
(gdb) commands
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>print (int) printf ("bobo\n")
>end
(gdb) run
Starting program: /home/klee/build/cygnus.cygnus/gdb/gdb
Breakpoint 1, main (argc=1, argv=0xbfffea34) at
./../../source/cygnus.cygnus/gdb/gdb.c:29
29 memset (&args, 0, sizeof args);
Program received signal SIGSEGV, Segmentation fault.
0x0807a246 in free_command_lines (lptr=0x18) at
./../../source/cygnus.cygnus/gdb/cli/cli-script.c:983
I believe this problem was introduced in the changes to breakpoint.c on
2002-08-26 --- the problem is that stop_bpstat gets cleared as part of
the cleanup after hand_function_call, which now includes removing the
commands data. But unfortunately, it's restored by
restore_inferior_status, including a pointer to now-obsolete commands,
which eventually causes the crash in free_command_lines.
save_inferior_status tries to "do the right thing," by making a copy of
stop_bpstat, but unfortunately, stop_bpstat only does a shallow copy,
not a deep one.
The following patch updates stop_bpstat to do a deep copy of the
commands and the old watchpoint value. It doesn't copy the breakpoint,
since I suspect this is supposed to just be a reference, and it's not
freed in clear_bpstat.
2002-10-29 Klee Dienes <kdienes@apple.com>
* breakpoint.c (bpstat_copy): Copy the command lines as well
as the old value, to match what is freed in bpstat_clear.
* Makefile.in: Rename INTL_DEPS to INTL_DEP, to match other
variable names.
Index: breakpoint.c
===================================================================
RCS file: /cvs/Darwin/src/live/cygnus/src/gdb/breakpoint.c,v
retrieving revision 1.48
diff -u -r1.48 breakpoint.c
--- breakpoint.c 2002/10/26 09:20:12 1.48
+++ breakpoint.c 2002/10/30 09:01:01
@@ -1844,6 +1844,10 @@
{
tmp = (bpstat) xmalloc (sizeof (*tmp));
memcpy (tmp, bs, sizeof (*tmp));
+ if (bs->commands != NULL)
+ tmp->commands = copy_command_lines (bs->commands);
+ if (bs->old_val != NULL)
+ tmp->old_val = value_copy (bs->old_val);
if (p == NULL)
/* This is the first thing in the chain. */
retval = tmp;
This patch adds a check for calls to the inferior to the testsuite.
The first part is straightforward --- it adds a call to the inferior to
the initial "silent" breakpoint check, and checks for the correct
output from it. The second part, I'm less sure about: it makes a
second call to marker2(), after setting breakpoint commands on it to
call the inferior as well. Currently, these commands aren't hit (and
the test fails). I'm appending the test-suite part of the patch as an
attachment, because, as you all know, my mailer is officially weird.
2002-10-29 Klee Dienes <kdienes@apple.com>
* gdb.base/break.exp: Add multiple calls to the inferior in
the user-commands for 'break 79'. Add a check for the calls
to the inferior in the check for the result. Add new test, to
check that user-defined breakpoint commands are called for
functions
called by the user (currently fails).
--Apple-Mail-3--319237899
Content-Disposition: attachment;
filename=testsuite-diffs.txt
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
x-unix-mode=0644;
name="testsuite-diffs.txt"
Index: testsuite/gdb.base/break.exp
===================================================================
RCS file: /cvs/Darwin/src/live/cygnus/src/gdb/testsuite/gdb.base/break.exp,v
retrieving revision 1.3
diff -u -r1.3 break.exp
--- break.exp 2002/08/13 20:06:14 1.3
+++ break.exp 2002/10/30 09:01:25
@@ -440,7 +440,9 @@
}
# Verify that a "silent" breakpoint can be set, and that GDB is indeed
-# "silent" about its triggering.
+# "silent" about its triggering. Include multiple nested calls to the
+# inferior in the user-commands for the breakpoint, to verify that the
+# cleanup code isn't trashing stop_bpstat.
#
if ![runto_main] then { fail "break tests suppressed" }
@@ -455,6 +457,7 @@
send_gdb "commands $expect_out(1,string)\n"
send_gdb "silent\n"
+send_gdb "call (int) printf (\"PREFIXbobo\\n\" + (int) strlen (\"PREFIXbobo\\n\") - 5)\n"
send_gdb "end\n"
gdb_expect {
-re ".*$gdb_prompt $"\
@@ -472,7 +475,7 @@
}
send_gdb "continue\n"
gdb_expect {
- -re "Continuing.\r\n$gdb_prompt $"\
+ -re "Continuing.\r\nbobo\r\n\\\$\[0-9\]* = 5\r\n$gdb_prompt $"\
{pass "hit silent break 79"}
-re "$gdb_prompt $"\
{fail "hit silent break 79"}
@@ -602,6 +605,13 @@
{fail "set breakpoint on to-be-called function"}
timeout {fail "(timeout) set breakpoint on to-be-called function"}
}
+
+# save the breakpoint identifier for future use
+#
+set marker2_bpnum $expect_out(1,string)
+
+# Call the function.
+#
send_gdb "print marker2(99)\n"
gdb_expect {
-re "The program being debugged stopped while in a function called from GDB.\r\nWhen the function .marker2$proto. is done executing, GDB will silently\r\nstop .instead of continuing to evaluate the expression containing\r\nthe function call...*$gdb_pr ompt $"\
@@ -626,6 +636,46 @@
-re "$gdb_prompt $"\
{fail "backtrace while in called function"}
timeout {fail "(timeout) backtrace while in called function"}
+}
+
+# Return from the called function. For remote targets, it's important to do
+# this before runto_main, which otherwise may silently stop on the dummy
+# breakpoint inserted by GDB at the program's entry point.
+#
+send_gdb "finish\n"
+gdb_expect {
+ -re "Run till exit from .*marker2.* at .*4\[49\]\r\n.* in _sr4export.*$gdb_prompt $"\
+ {pass "finish from called function"}
+ -re "Run till exit from .*marker2.* at .*4\[49\]\r\n.*function called from gdb.*$gdb_prompt $"\
+ {pass "finish from called function"}
+ -re "Run till exit from .*marker2.* at .*4\[49\]\r\n.*Value returned.*$gdb_prompt $"\
+ {pass "finish from called function"}
+ -re "$gdb_prompt $"\
+ {fail "finish from called function"}
+ timeout {fail "(timeout) finish from called function"}
+}
+
+# Add a user-command that calls the inferior to the breakpoint for marker2.
+#
+send_gdb "commands $marker2_bpnum\n"
+send_gdb "silent\n"
+send_gdb "call (int) printf (\"PREFIXbobo\\n\" + (int) strlen (\"PREFIXbobo\\n\") - 5)\n"
+send_gdb "end\n"
+gdb_expect {
+ -re ".*$gdb_prompt $"\
+ {pass "set printf break marker2"}
+ timeout {fail "(timeout) set printf break marker2"}
+}
+
+# Call the function again.
+#
+send_gdb "print marker2(99)\n"
+gdb_expect {
+ -re "The program being debugged stopped while in a function called from GDB.\r\nWhen the function .marker2$proto. is done executing, GDB will silently\r\nstop .instead of continuing to evaluate the expression containing\r\nthe function call...*bobo. *$gdb_prompt $"\
+ {pass "called user-defined function on breakpoint in called function"}
+ -re "$gdb_prompt $"\
+ {fail "called user-defined function on breakpoint in called function"}
+ timeout {fail "called user-defined function on breakpoint in called function"}
}
# Return from the called function. For remote targets, it's important to do
--Apple-Mail-3--319237899
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
--Apple-Mail-3--319237899--
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: