From owner-freebsd-bugs@FreeBSD.ORG Mon Aug 13 15:30:02 2007 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4014616A419 for ; Mon, 13 Aug 2007 15:30:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 1DCD413C481 for ; Mon, 13 Aug 2007 15:30:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l7DFU13G064974 for ; Mon, 13 Aug 2007 15:30:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l7DFU18E064970; Mon, 13 Aug 2007 15:30:01 GMT (envelope-from gnats) Resent-Date: Mon, 13 Aug 2007 15:30:01 GMT Resent-Message-Id: <200708131530.l7DFU18E064970@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Tijl Coosemans Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1470616A419 for ; Mon, 13 Aug 2007 15:23:32 +0000 (UTC) (envelope-from tijl@kalimero.kotnet.org) Received: from mailrelay008.isp.belgacom.be (mailrelay008.isp.belgacom.be [195.238.6.174]) by mx1.freebsd.org (Postfix) with ESMTP id A986C13C45D for ; Mon, 13 Aug 2007 15:23:31 +0000 (UTC) (envelope-from tijl@kalimero.kotnet.org) Received: from 67.215-245-81.adsl-dyn.isp.belgacom.be (HELO kalimero.kotnet.org) ([81.245.215.67]) by mailrelay008.isp.belgacom.be with ESMTP; 13 Aug 2007 17:23:25 +0200 Received: from kalimero.kotnet.org (localhost [127.0.0.1]) by kalimero.kotnet.org (8.14.1/8.14.1) with ESMTP id l7DFNOaW004432 for ; Mon, 13 Aug 2007 17:23:24 +0200 (CEST) (envelope-from tijl@kalimero.kotnet.org) Received: (from tijl@localhost) by kalimero.kotnet.org (8.14.1/8.14.1/Submit) id l7DFNORI004431; Mon, 13 Aug 2007 17:23:24 +0200 (CEST) (envelope-from tijl) Message-Id: <200708131523.l7DFNORI004431@kalimero.kotnet.org> Date: Mon, 13 Aug 2007 17:23:24 +0200 (CEST) From: Tijl Coosemans To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: kern/115469: [patch] ptrace(2) signal delivery broken X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Tijl Coosemans List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Aug 2007 15:30:02 -0000 >Number: 115469 >Category: kern >Synopsis: [patch] ptrace(2) signal delivery broken >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Aug 13 15:30:01 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Tijl Coosemans >Release: FreeBSD 7.0-CURRENT i386 >Organization: >Environment: >Description: In kern_sig.c:issignal(), when a thread receives a signal and the process is being traced, ptracestop() is called, which suspends all threads in the process and notifies the parent. When the threads are resumed, ptracestop() returns td->td_xsig, the signal to be actually delivered to the process. Resuming the process is done by the parent calling ptrace(PT_CONTINUE, sig) which stores sig in td->td_xsig but currently also calls psignal(). The latter causes the signal to be queued again and the process stops on it again when it is handled. >How-To-Repeat: You can hit on this problem when debugging a process that has its own signal handlers. In that case when a signal is sent to the process, the process stops and gdb notifies you of the signal. When you let the process continue and deal with the signal, the signal handler is called, but then when the process returns from the handler, it stops again and again and again... >Fix: If a process is stopped ptrace should use td_xsig to deliver the signal and otherwise (PT_ATTACH case) it should use psignal(), which is what the following patch does. --- patch-ptrace begins here --- --- sys/kern/sys_process.c.orig 2007-08-02 15:53:10.000000000 +0200 +++ sys/kern/sys_process.c 2007-08-02 19:49:56.000000000 +0200 @@ -779,14 +779,15 @@ sx_xunlock(&proctree_lock); proctree_locked = 0; } - /* deliver or queue signal */ - thread_lock(td2); - td2->td_flags &= ~TDF_XSIG; - thread_unlock(td2); - td2->td_xsig = data; p->p_xstat = data; p->p_xthread = NULL; if ((p->p_flag & (P_STOPPED_SIG | P_STOPPED_TRACE)) != 0) { + /* deliver or queue signal */ + thread_lock(td2); + td2->td_flags &= ~TDF_XSIG; + thread_unlock(td2); + td2->td_xsig = data; + PROC_SLOCK(p); if (req == PT_DETACH) { struct thread *td3; @@ -809,11 +810,10 @@ p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG|P_WAITED); thread_unsuspend(p); PROC_SUNLOCK(p); + } else { + if (data) + psignal(p, data); } - - if (data) - psignal(p, data); - break; case PT_WRITE_I: --- patch-ptrace ends here --- >Release-Note: >Audit-Trail: >Unformatted: