|
From: <sv...@va...> - 2005-11-17 14:26:57
|
Author: sewardj
Date: 2005-11-17 14:26:52 +0000 (Thu, 17 Nov 2005)
New Revision: 5169
Log:
sys_tgkill: hand the syscall to the kernel in the standard way, rather
than doing it inline. Doing it inline screws up on ppc32-linux if
we're sending an async signal to ourselves (the same thread) because
the kernel immediately hands the signal to async_sighandler() which
then dies at the assertion that this thread's state is VgTs_WaitSys.
From which I conclude this wrapper has always had a race against the
kernel which did not show up on x86 or amd64. (and/or that I don't
understand this stuff too well)
Modified:
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/coregrind/m_syswrap/syswrap-main.c
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_syswrap/syswrap-linux.c 2005-11-17 14:22:22 UTC (re=
v 5168)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c 2005-11-17 14:26:52 UTC (re=
v 5169)
@@ -895,18 +895,30 @@
return;
}
=20
+ /* Check to see if this kill gave us a pending signal */
+ *flags |=3D SfPollAfter;
+
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg, "tgkill: sending signal %d to pid %d/%d"=
,
+ ARG3, ARG1, ARG2);
+
/* If we're sending SIGKILL, check to see if the target is one of
our threads and handle it specially. */
- if (ARG3 =3D=3D VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1))
+ if (ARG3 =3D=3D VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
SET_STATUS_Success(0);
- else
- SET_STATUS_from_SysRes(VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3));
+ return;
+ }
=20
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
- ARG3, ARG1, ARG2);
- /* Check to see if this kill gave us a pending signal */
- *flags |=3D SfPollAfter;
+ /* Ask to handle this syscall via the slow route, since that's the
+ only one that sets tst->status to VgTs_WaitSys. If the result
+ of doing the syscall is an immediate run of
+ async_signalhandler() in m_signals, then we need the thread to
+ be properly tidied away. I have the impression the previous
+ version of this wrapper worked on x86/amd64 only because the
+ kernel did not immediately deliver the async signal to this
+ thread (on ppc it did, which broke the assertion re tst->status
+ at the top of async_signalhandler()). */
+ *flags |=3D SfMayBlock;
}
POST(sys_tgkill)
{
Modified: trunk/coregrind/m_syswrap/syswrap-main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_syswrap/syswrap-main.c 2005-11-17 14:22:22 UTC (rev=
5168)
+++ trunk/coregrind/m_syswrap/syswrap-main.c 2005-11-17 14:26:52 UTC (rev=
5169)
@@ -713,9 +713,9 @@
by doing it directly in this thread, which is a lot
simpler. */
=20
- /* Check that the given flags are allowable: MayBlock and
- PostOnFail are ok. */
- vg_assert(0 =3D=3D (sci->flags & ~(SfMayBlock | SfPostOnFail)));
+ /* Check that the given flags are allowable: MayBlock, PollAfter
+ and PostOnFail are ok. */
+ vg_assert(0 =3D=3D (sci->flags & ~(SfMayBlock | SfPostOnFail | SfP=
ollAfter)));
=20
if (sci->flags & SfMayBlock) {
=20
|