aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2016-02-09 12:12:17 +0000
committerPedro Alves <palves@redhat.com>2016-02-09 12:12:17 +0000
commit2a7f3dffced7a20c992e1488d9f05fed8b8001fd (patch)
treea4d5c032f9b09535774b313c579bf12916f7af89 /gdb/testsuite
parent8adce0342f5f50aba0154fc56ca59df45b219738 (diff)
downloadgdb-2a7f3dffced7a20c992e1488d9f05fed8b8001fd.zip
gdb-2a7f3dffced7a20c992e1488d9f05fed8b8001fd.tar.gz
gdb-2a7f3dffced7a20c992e1488d9f05fed8b8001fd.tar.bz2
Fix PR19548: Breakpoint re-set inserts breakpoints when it shouldn't
PR19548 shows that we still have problems related to 13fd3ff34329: [PR17431: following execs with "breakpoint always-inserted on"] https://sourceware.org/ml/gdb-patches/2014-09/msg00733.html The problem this time is that we currently update the global location list and try to insert breakpoint locations after re-setting _each_ breakpoint in turn. Say: - We have _more_ than one breakpoint set. Let's assume 2. - There's a breakpoint with a pre-exec address that ends up being an unmapped address after the exec. - That breakpoint is NOT the first in the breakpoint list. Then when handling an exec, and we re-set the first breakpoint in the breakpoint list, we mistakently try to install the old pre-exec / un-re-set locations of the other breakpoint, which fails: (gdb) continue Continuing. process 28295 is executing new program: (...)/execl-update-breakpoints2 Error in re-setting breakpoint 1: Warning: Cannot insert breakpoint 2. Cannot access memory at address 0x1000764 Breakpoint 1, main (argc=1, argv=0x7fffffffd368) at /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.base/execl-update-breakpoints.c:34 34 len = strlen (argv[0]); (gdb) Fix this by deferring the global location list update till after all breakpoints are re-set. Tested on x86_64 Fedora 20, native and gdbserver. gdb/ChangeLog: 2016-02-09 Pedro Alves <palves@redhat.com> PR breakpoints/19548 * breakpoint.c (create_overlay_event_breakpoint): Don't update global location list here. (create_longjmp_master_breakpoint) (create_std_terminate_master_breakpoint) (create_exception_master_breakpoint, create_jit_event_breakpoint) (update_breakpoint_locations): (breakpoint_re_set): Update global location list after all breakpoints are re-set. gdb/testsuite/ChangeLog: 2016-02-09 Pedro Alves <palves@redhat.com> PR breakpoints/19548 * gdb.base/execl-update-breakpoints.c (some_function): New function. (main): Call it. * gdb.base/execl-update-breakpoints.exp: Add a second breakpoint. Tighten expected GDB output.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/ChangeLog9
-rw-r--r--gdb/testsuite/gdb.base/execl-update-breakpoints.c6
-rw-r--r--gdb/testsuite/gdb.base/execl-update-breakpoints.exp31
3 files changed, 44 insertions, 2 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 2a71930..f8e0800 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2016-02-09 Pedro Alves <palves@redhat.com>
+
+ PR breakpoints/19548
+ * gdb.base/execl-update-breakpoints.c (some_function): New
+ function.
+ (main): Call it.
+ * gdb.base/execl-update-breakpoints.exp: Add a second breakpoint.
+ Tighten expected GDB output.
+
2016-02-08 Simon Marchi <simon.marchi@ericsson.com>
* Makefile.in (ALL_SUBDIRS): Remove.
diff --git a/gdb/testsuite/gdb.base/execl-update-breakpoints.c b/gdb/testsuite/gdb.base/execl-update-breakpoints.c
index 3978a70..38f1cea 100644
--- a/gdb/testsuite/gdb.base/execl-update-breakpoints.c
+++ b/gdb/testsuite/gdb.base/execl-update-breakpoints.c
@@ -20,6 +20,11 @@
#include <stdlib.h>
#include <string.h>
+void
+some_function (void)
+{
+}
+
int
main (int argc, char **argv)
{
@@ -34,5 +39,6 @@ main (int argc, char **argv)
execl (bin, bin, (char *) NULL);
perror ("execl failed");
+ some_function ();
exit (1);
}
diff --git a/gdb/testsuite/gdb.base/execl-update-breakpoints.exp b/gdb/testsuite/gdb.base/execl-update-breakpoints.exp
index 4f35999..47a848e 100644
--- a/gdb/testsuite/gdb.base/execl-update-breakpoints.exp
+++ b/gdb/testsuite/gdb.base/execl-update-breakpoints.exp
@@ -96,6 +96,7 @@ if {!$cannot_access} {
proc test { always_inserted } {
global exec1
+ global gdb_prompt
clean_restart ${exec1}
@@ -106,13 +107,39 @@ proc test { always_inserted } {
return -1
}
- # On a buggy GDB, with always-inserted on, we'd see:
+ # Set a second breakpoint (whose original address also ends up
+ # unmmapped after the exec), for PR 19548.
+ gdb_test "break some_function" "Breakpoint .*"
+
+ # PR17431: with always-inserted on, we'd see:
# (gdb) continue
# Continuing.
# Warning:
# Cannot insert breakpoint 1.
# Cannot access memory at address 0x10000ff
- gdb_test "continue" "Breakpoint 1, main.*" "continue across exec"
+
+ # PR 19548: with more than one breakpoint, we'd see:
+ # (gdb) continue
+ # Continuing.
+ # process (...) is executing new program: (...)/execl-update-breakpoints2
+ # Error in re-setting breakpoint 1: Warning:
+ # Cannot insert breakpoint 2.
+ # Cannot access memory at address 0x1000764
+ set not_nl "\[^\r\n\]*"
+ set regex ""
+ append regex \
+ "^continue\r\n" \
+ "Continuing\\.\r\n" \
+ "${not_nl} is executing new program: ${not_nl}\r\n" \
+ "(Reading ${not_nl} from remote target\\.\\.\\.\r\n)*" \
+ "\r\n" \
+ "Breakpoint 1, main.*$gdb_prompt $"
+ set message "continue across exec"
+ gdb_test_multiple "continue" $message {
+ -re $regex {
+ pass $message
+ }
+ }
}
foreach always_inserted { "off" "on" } {