Fix next over threaded execl with "set scheduler-locking step".
authorPedro Alves <palves@redhat.com>
Thu, 19 Jun 2014 10:59:03 +0000 (11:59 +0100)
committerPedro Alves <palves@redhat.com>
Thu, 19 Jun 2014 10:59:03 +0000 (11:59 +0100)
commit034f788c5ec1e5b20fae3b6efc7fe961631e014d
tree039c2ea366839afb8a82d98df115b5c60f8ad80d
parent46e3325277e604face2848eec78247826b94d5c9
Fix next over threaded execl with "set scheduler-locking step".

Running gdb.threads/thread-execl.exp with scheduler-locking set to
"step" reveals a problem:

 (gdb) next^M
 [Thread 0x7ffff7fda700 (LWP 27168) exited]^M
 [New LWP 27168]^M
 [Thread 0x7ffff74ee700 (LWP 27174) exited]^M
 process 27168 is executing new program: /home/jkratoch/redhat/gdb-clean/gdb/testsuite/gdb.threads/thread-execl^M
 [Thread debugging using libthread_db enabled]^M
 Using host libthread_db library "/lib64/libthread_db.so.1".^M
 infrun.c:5225: internal-error: switch_back_to_stepped_thread: Assertion `!schedlock_applies (1)' failed.^M
 A problem internal to GDB has been detected,^M
 further debugging may prove unreliable.^M
 Quit this debugging session? (y or n) FAIL: gdb.threads/thread-execl.exp: schedlock step: get to main in new image (GDB internal error)

The assertion is correct.  The issue is that GDB is mistakenly trying
to switch back to an exited thread, that was previously stepping when
it exited.  This is exactly the sort of thing the test wants to make
sure doesn't happen:

# Now set a breakpoint at `main', and step over the execl call.  The
# breakpoint at main should be reached.  GDB should not try to revert
# back to the old thread from the old image and resume stepping it

We don't see this bug with schedlock off only because a different
sequence of events makes GDB manage to delete the thread instead of
marking it exited.

This particular internal error can be fixed by making the loop over
all threads in switch_back_to_stepped_thread skip exited threads.
But, looking over other ALL_THREADS users, all either can or should be
skipping exited threads too.  So for simplicity, this patch replaces
ALL_THREADS with a new macro that skips exited threads itself, and
updates everything to use it.

Tested on x86_64 Fedora 20.

gdb/
2014-06-19  Pedro Alves  <palves@redhat.com>

* gdbthread.h (ALL_THREADS): Delete.
(ALL_NON_EXITED_THREADS): New macro.
* btrace.c (btrace_free_objfile): Use ALL_NON_EXITED_THREADS
instead of ALL_THREADS.
* infrun.c (find_thread_needs_step_over)
(switch_back_to_stepped_thread): Use ALL_NON_EXITED_THREADS
instead of ALL_THREADS.
* record-btrace.c (record_btrace_open)
(record_btrace_stop_recording, record_btrace_close)
(record_btrace_is_replaying, record_btrace_resume)
(record_btrace_find_thread_to_move, record_btrace_wait): Likewise.
* remote.c (append_pending_thread_resumptions): Likewise.
* thread.c (thread_apply_all_command): Likewise.

gdb/testsuite/
2014-06-19  Pedro Alves  <palves@redhat.com>

* gdb.threads/thread-execl.exp (do_test): New procedure, factored
out from ...
(top level): ... here.  Iterate running tests under different
scheduler-locking settings.
gdb/ChangeLog
gdb/btrace.c
gdb/gdbthread.h
gdb/infrun.c
gdb/record-btrace.c
gdb/remote.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.threads/thread-execl.exp
gdb/thread.c
This page took 0.028534 seconds and 4 git commands to generate.