2013-08-19 16:54:11 +00:00
|
|
|
/* Target waitstatus implementations.
|
2013-07-24 16:20:12 +00:00
|
|
|
|
2016-01-01 04:33:14 +00:00
|
|
|
Copyright (C) 1990-2016 Free Software Foundation, Inc.
|
2013-07-24 16:20:12 +00:00
|
|
|
|
|
|
|
This file is part of GDB.
|
|
|
|
|
|
|
|
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/>. */
|
|
|
|
|
2014-09-12 09:11:42 +00:00
|
|
|
#include "common-defs.h"
|
2013-08-19 16:54:11 +00:00
|
|
|
#include "waitstatus.h"
|
2013-07-24 16:20:12 +00:00
|
|
|
|
|
|
|
/* Return a pretty printed form of target_waitstatus.
|
|
|
|
Space for the result is malloc'd, caller must free. */
|
|
|
|
|
|
|
|
char *
|
|
|
|
target_waitstatus_to_string (const struct target_waitstatus *ws)
|
|
|
|
{
|
|
|
|
const char *kind_str = "status->kind = ";
|
|
|
|
|
|
|
|
switch (ws->kind)
|
|
|
|
{
|
|
|
|
case TARGET_WAITKIND_EXITED:
|
|
|
|
return xstrprintf ("%sexited, status = %d",
|
|
|
|
kind_str, ws->value.integer);
|
|
|
|
case TARGET_WAITKIND_STOPPED:
|
|
|
|
return xstrprintf ("%sstopped, signal = %s",
|
infrun debug output: print enum gdb_signal symbol names instead of POSIX signal names.
The other day while debugging something related to random signals, I
got confused with "set debug infrun 1" output, for it said:
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal 20
On GNU/Linux, 20 is SIGTSTP. For some reason, it took me a few
minutes to realize that 20 is actually a GDB signal number, not a
target signal number (duh!). In any case, I propose making GDB's
output clearer here:
One way would be to use gdb_signal_to_name, like already used
elsewhere:
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal SIGCHLD (20)
but I think that might confuse someone too ("20? Why does GDB believe
SIGCHLD is 20?"). So I thought of printing the enum string instead:
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal GDB_SIGNAL_CHLD (20)
Looking at a more complete infrun debug log, we had actually printed
the (POSIX) signal name name a bit before:
infrun: target_wait (-1, status) =
infrun: 9300 [Thread 0x7ffff7fcb740 (LWP 9300)],
infrun: status->kind = stopped, signal = SIGCHLD
...
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal 20
So I'm now thinking that it'd be even better to make infrun output
consistently use the enum symbol string, like so:
infrun: clear_proceed_status_thread (Thread 0x7ffff7fca700 (LWP 25663))
infrun: clear_proceed_status_thread (Thread 0x7ffff7fcb740 (LWP 25659))
- infrun: proceed (addr=0xffffffffffffffff, signal=144, step=1)
+ infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT, step=1)
- infrun: resume (step=1, signal=0), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
+ infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
infrun: wait_for_inferior ()
infrun: target_wait (-1, status) =
infrun: 25659 [Thread 0x7ffff7fcb740 (LWP 25659)],
- infrun: status->kind = stopped, signal = SIGCHLD
+ infrun: status->kind = stopped, signal = GDB_SIGNAL_CHLD
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x400700
- infrun: random signal 20
+ infrun: random signal (GDB_SIGNAL_CHLD)
infrun: random signal, keep going
- infrun: resume (step=1, signal=20), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
+ infrun: resume (step=1, signal=GDB_SIGNAL_CHLD), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
infrun: prepare_to_wait
infrun: target_wait (-1, status) =
infrun: 25659 [Thread 0x7ffff7fcb740 (LWP 25659)],
- infrun: status->kind = stopped, signal = SIGTRAP
+ infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x400704
infrun: stepi/nexti
infrun: stop_stepping
GDB's signal numbers are public and hardcoded (see
include/gdb/signals.h), so there's really no need to clutter the
output with numeric values in some places while others not. Replacing
the magic "144" with GDB_SIGNAL_DEFAULT in "proceed"'s debug output
(see above) I think is quite nice.
I posit that all this makes it clearer to newcomers that GDB has its
own signal numbering (and that there must be some mapping going on).
Tested on x86_64 Fedora 17.
gdb/
2013-10-23 Pedro Alves <palves@redhat.com>
* common/gdb_signals.h (gdb_signal_to_symbol_string): Declare.
* common/signals.c: Include "gdb_assert.h".
(signals): New field 'symbol'.
(SET): Use the 'symbol' parameter.
(gdb_signal_to_symbol_string): New function.
* infrun.c (handle_inferior_event) <random signal>: In debug
output, print the random signal enum as string in addition to its
number.
* target/waitstatus.c (target_waitstatus_to_string): Print the
signal's enum value as string instead of the (POSIX) signal name.
2013-10-23 15:14:53 +00:00
|
|
|
kind_str,
|
|
|
|
gdb_signal_to_symbol_string (ws->value.sig));
|
2013-07-24 16:20:12 +00:00
|
|
|
case TARGET_WAITKIND_SIGNALLED:
|
|
|
|
return xstrprintf ("%ssignalled, signal = %s",
|
infrun debug output: print enum gdb_signal symbol names instead of POSIX signal names.
The other day while debugging something related to random signals, I
got confused with "set debug infrun 1" output, for it said:
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal 20
On GNU/Linux, 20 is SIGTSTP. For some reason, it took me a few
minutes to realize that 20 is actually a GDB signal number, not a
target signal number (duh!). In any case, I propose making GDB's
output clearer here:
One way would be to use gdb_signal_to_name, like already used
elsewhere:
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal SIGCHLD (20)
but I think that might confuse someone too ("20? Why does GDB believe
SIGCHLD is 20?"). So I thought of printing the enum string instead:
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal GDB_SIGNAL_CHLD (20)
Looking at a more complete infrun debug log, we had actually printed
the (POSIX) signal name name a bit before:
infrun: target_wait (-1, status) =
infrun: 9300 [Thread 0x7ffff7fcb740 (LWP 9300)],
infrun: status->kind = stopped, signal = SIGCHLD
...
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x323d4e8b94
infrun: random signal 20
So I'm now thinking that it'd be even better to make infrun output
consistently use the enum symbol string, like so:
infrun: clear_proceed_status_thread (Thread 0x7ffff7fca700 (LWP 25663))
infrun: clear_proceed_status_thread (Thread 0x7ffff7fcb740 (LWP 25659))
- infrun: proceed (addr=0xffffffffffffffff, signal=144, step=1)
+ infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT, step=1)
- infrun: resume (step=1, signal=0), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
+ infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
infrun: wait_for_inferior ()
infrun: target_wait (-1, status) =
infrun: 25659 [Thread 0x7ffff7fcb740 (LWP 25659)],
- infrun: status->kind = stopped, signal = SIGCHLD
+ infrun: status->kind = stopped, signal = GDB_SIGNAL_CHLD
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x400700
- infrun: random signal 20
+ infrun: random signal (GDB_SIGNAL_CHLD)
infrun: random signal, keep going
- infrun: resume (step=1, signal=20), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
+ infrun: resume (step=1, signal=GDB_SIGNAL_CHLD), trap_expected=0, current thread [Thread 0x7ffff7fcb740 (LWP 25659)] at 0x400700
infrun: prepare_to_wait
infrun: target_wait (-1, status) =
infrun: 25659 [Thread 0x7ffff7fcb740 (LWP 25659)],
- infrun: status->kind = stopped, signal = SIGTRAP
+ infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x400704
infrun: stepi/nexti
infrun: stop_stepping
GDB's signal numbers are public and hardcoded (see
include/gdb/signals.h), so there's really no need to clutter the
output with numeric values in some places while others not. Replacing
the magic "144" with GDB_SIGNAL_DEFAULT in "proceed"'s debug output
(see above) I think is quite nice.
I posit that all this makes it clearer to newcomers that GDB has its
own signal numbering (and that there must be some mapping going on).
Tested on x86_64 Fedora 17.
gdb/
2013-10-23 Pedro Alves <palves@redhat.com>
* common/gdb_signals.h (gdb_signal_to_symbol_string): Declare.
* common/signals.c: Include "gdb_assert.h".
(signals): New field 'symbol'.
(SET): Use the 'symbol' parameter.
(gdb_signal_to_symbol_string): New function.
* infrun.c (handle_inferior_event) <random signal>: In debug
output, print the random signal enum as string in addition to its
number.
* target/waitstatus.c (target_waitstatus_to_string): Print the
signal's enum value as string instead of the (POSIX) signal name.
2013-10-23 15:14:53 +00:00
|
|
|
kind_str,
|
|
|
|
gdb_signal_to_symbol_string (ws->value.sig));
|
2013-07-24 16:20:12 +00:00
|
|
|
case TARGET_WAITKIND_LOADED:
|
|
|
|
return xstrprintf ("%sloaded", kind_str);
|
|
|
|
case TARGET_WAITKIND_FORKED:
|
|
|
|
return xstrprintf ("%sforked", kind_str);
|
|
|
|
case TARGET_WAITKIND_VFORKED:
|
|
|
|
return xstrprintf ("%svforked", kind_str);
|
|
|
|
case TARGET_WAITKIND_EXECD:
|
|
|
|
return xstrprintf ("%sexecd", kind_str);
|
|
|
|
case TARGET_WAITKIND_VFORK_DONE:
|
|
|
|
return xstrprintf ("%svfork-done", kind_str);
|
|
|
|
case TARGET_WAITKIND_SYSCALL_ENTRY:
|
|
|
|
return xstrprintf ("%sentered syscall", kind_str);
|
|
|
|
case TARGET_WAITKIND_SYSCALL_RETURN:
|
|
|
|
return xstrprintf ("%sexited syscall", kind_str);
|
|
|
|
case TARGET_WAITKIND_SPURIOUS:
|
|
|
|
return xstrprintf ("%sspurious", kind_str);
|
|
|
|
case TARGET_WAITKIND_IGNORE:
|
|
|
|
return xstrprintf ("%signore", kind_str);
|
|
|
|
case TARGET_WAITKIND_NO_HISTORY:
|
|
|
|
return xstrprintf ("%sno-history", kind_str);
|
|
|
|
case TARGET_WAITKIND_NO_RESUMED:
|
|
|
|
return xstrprintf ("%sno-resumed", kind_str);
|
Remote thread create/exit events
When testing with "maint set target-non-stop on", a few
threading-related tests expose an issue that requires new RSP packets.
Say there are 3 threads running, 1-3. If GDB tries to stop thread 1,
2 and 3, and then waits for their stops, but meanwhile say, thread 2
exits, GDB hangs forever waiting for a stop for thread 2 that won't
ever happen.
This patch fixes the issue by adding support for thread exit events to
the protocol. However, we don't want these always enabled, as they're
useless most of the time, and would slow down remote debugging. So I
made it so that GDB can enable/disable them, and then made gdb do that
around the cases that need it, which currently is only
infrun.c:stop_all_threads.
In turn, if we have thread exit events, then the extra "thread x
exited" traffic slows down attach-many-short-lived-threads.exp enough
that gdb has trouble keeping up with new threads that are spawned
while gdb tries to stop existing ones. To fix that I added support
for the counterpart thread created events too. Enabling those when we
try to stop threads ensures that new threads never get a chance to
themselves start new threads, killing the race.
gdb/doc/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Remote Configuration): List "set/show remote
thread-events" command in configuration table.
(Stop Reply Packets): Document "T05 create" stop
reason and 'w' stop reply.
(General Query Packets): Document QThreadEvents packet. Document
QThreadEvents qSupported feature.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* linux-low.c (handle_extended_wait): Assert that the LWP's
waitstatus is TARGET_WAITKIND_IGNORE. If GDB wants to hear about
thread create events, leave the new child's status pending.
(linux_low_filter_event): If GDB wants to hear about thread exit
events, leave the LWP marked dead and don't delete it.
(linux_wait_for_event_filtered): Don't check for thread exit.
(filter_exit_event): New function.
(linux_wait_1): Use it, when returning an exit event.
(linux_resume_one_lwp_throw): Assert that the LWP's
waitstatus is TARGET_WAITKIND_IGNORE.
* remote-utils.c (prepare_resume_reply): Handle
TARGET_WAITKIND_THREAD_CREATED and TARGET_WAITKIND_THREAD_EXITED.
* server.c (report_thread_events): New global.
(handle_general_set): Handle QThreadEvents.
(handle_query) <qSupported>: Handle and report QThreadEvents+;
(handle_target_event): Handle TARGET_WAITKIND_THREAD_CREATED and
TARGET_WAITKIND_THREAD_EXITED.
* server.h (report_thread_events): Declare.
gdb/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* NEWS (New commands): Mention "set/show remote thread-events"
commands.
(New remote packets): Mention thread created/exited stop reasons
and QThreadEvents packet.
* infrun.c (disable_thread_events): New function.
(stop_all_threads): Disable/enable thread create/exit events.
Handle TARGET_WAITKIND_THREAD_EXITED.
(handle_inferior_event_1): Handle TARGET_WAITKIND_THREAD_CREATED
and TARGET_WAITKIND_THREAD_EXITED.
* remote.c (remove_child_of_pending_fork): Also remove threads of
threads that have TARGET_WAITKIND_THREAD_EXITED events.
(remote_parse_stop_reply): Handle "create" magic register. Handle
'w' stop reply.
(initialize_remote): Install remote_thread_events as
to_thread_events target hook.
(remote_thread_events): New function.
* target-delegates.c: Regenerate.
* target.c (target_thread_events): New function.
* target.h (struct target_ops) <to_thread_events>: New field.
(target_thread_events): Declare.
* target/waitstatus.c (target_waitstatus_to_string): Handle
TARGET_WAITKIND_THREAD_CREATED and TARGET_WAITKIND_THREAD_EXITED.
* target/waitstatus.h (enum target_waitkind)
<TARGET_WAITKIND_THREAD_CREATED, TARGET_WAITKIND_THREAD_EXITED):
New values.
2015-11-30 16:05:21 +00:00
|
|
|
case TARGET_WAITKIND_THREAD_CREATED:
|
|
|
|
return xstrprintf ("%sthread created", kind_str);
|
|
|
|
case TARGET_WAITKIND_THREAD_EXITED:
|
|
|
|
return xstrprintf ("%sthread exited, status = %d",
|
|
|
|
kind_str, ws->value.integer);
|
2013-07-24 16:20:12 +00:00
|
|
|
default:
|
|
|
|
return xstrprintf ("%sunknown???", kind_str);
|
|
|
|
}
|
|
|
|
}
|