|
From: Jeremy F. <je...@go...> - 2005-02-04 22:44:26
|
CVS commit by fitzhardinge:
Fix a little logic bug in the scheduler loop structure. If
VG_(poll_signals)() found a fatal signal, then exit the scheduler
immediately, rather than continuing to run a bit more.
Also, handle async-sync signals correctly.
A none/tests/async-sigs.c 1.1 [no copyright]
A none/tests/async-sigs.stderr.exp 1.1
A none/tests/async-sigs.stdout.exp 1.1
A none/tests/async-sigs.vgtest 1.1
M +5 -5 coregrind/vg_scheduler.c 1.219
M +17 -7 coregrind/vg_signals.c 1.119
M +3 -1 none/tests/Makefile.am 1.62
--- valgrind/coregrind/vg_scheduler.c #1.218:1.219
@@ -672,4 +672,7 @@ VgSchedReturnCode VG_(scheduler) ( Threa
VG_(poll_signals)(tid);
+ if (VG_(is_exiting)(tid))
+ break; /* poll_signals picked up a fatal signal */
+
/* For stats purposes only. */
n_scheduling_events_MAJOR++;
@@ -734,9 +737,6 @@ VgSchedReturnCode VG_(scheduler) ( Threa
case VG_TRC_FAULT_SIGNAL:
- /* Make sure we've unblocked the signals which the handler
- blocked. This should never block more signals that
- before (ie, there's no window that unsafe signals could
- sneak in). */
- VG_(block_signals)(tid);
+ /* Everything should be set up (either we're exiting, or
+ about to start in a signal handler). */
break;
--- valgrind/coregrind/vg_signals.c #1.118:1.119
@@ -1688,8 +1688,11 @@ void vg_sync_signalhandler ( Int sigNo,
sigNo == VKI_SIGTRAP);
- if (!VG_(is_running_thread)(tid)) {
- /* This may possibly happen if someone sent us one of the sync
- signals with a kill syscall. Get the CPU before going on. */
- vg_assert(info->si_code <= VKI_SI_USER);
+ if (info->si_code <= VKI_SI_USER) {
+ /* If some user-process sent us one of these signals (ie,
+ they're not the result of a faulting instruction), then treat
+ it as an async signal. This recipient thread may or may not
+ be running at the time, so we need to make sure we have the
+ CPU before going on. */
+ if (!VG_(is_running_thread)(tid))
VG_(set_running)(tid);
@@ -1697,6 +1700,13 @@ void vg_sync_signalhandler ( Int sigNo,
on the kernel to route them properly, so we need to queue
them manually. */
- queue_signal(0, info);
- VG_(resume_scheduler)(tid);
+ if (info->si_code == VKI_SI_TKILL)
+ queue_signal(tid, info); /* directed to us specifically */
+ else
+ queue_signal(0, info); /* shared pending */
+
+ /* Just return; either the thread was running so we just return
+ to the instruction that happened to be interrupted, or it was
+ not running - but it is now. */
+ return;
}
--- valgrind/none/tests/Makefile.am #1.61:1.62
@@ -5,4 +5,5 @@
EXTRA_DIST = $(noinst_SCRIPTS) \
args.stderr.exp args.stdout.exp args.vgtest \
+ async-sigs.stderr.exp async-sigs.stdout.exp async-sigs.vgtest \
bitfield1.stderr.exp bitfield1.vgtest \
blockfault.vgtest \
@@ -64,5 +65,5 @@
check_PROGRAMS = \
- args bitfield1 blockfault closeall coolo_strlen \
+ args async-sigs bitfield1 blockfault closeall coolo_strlen \
discard exec-sigmask execve faultstatus fcntl_setown floored fork \
fucomip getseg \
@@ -83,4 +84,5 @@
# generic C ones
args_SOURCES = args.c
+async_sigs_SOURCES = async-sigs.c
bitfield1_SOURCES = bitfield1.c
blockfault_SOURCES = blockfault.c
|