Fix PR19548: Breakpoint re-set inserts breakpoints when it shouldn't
authorPedro Alves <palves@redhat.com>
Tue, 9 Feb 2016 12:12:17 +0000 (12:12 +0000)
committerPedro Alves <palves@redhat.com>
Tue, 9 Feb 2016 12:12:17 +0000 (12:12 +0000)
commit2a7f3dffced7a20c992e1488d9f05fed8b8001fd
treea4d5c032f9b09535774b313c579bf12916f7af89
parent8adce0342f5f50aba0154fc56ca59df45b219738
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.
gdb/ChangeLog
gdb/breakpoint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/execl-update-breakpoints.c
gdb/testsuite/gdb.base/execl-update-breakpoints.exp