Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Nov 2010 21:24:21 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r214756 - in stable/8/sys: kern sys
Message-ID:  <201011032124.oA3LOLJ7033869@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Nov  3 21:24:21 2010
New Revision: 214756
URL: http://svn.freebsd.org/changeset/base/214756

Log:
  MFC r209688:
  Extend ptrace(PT_LWPINFO) to report siginfo for the signal that caused
  debugee stop.

Modified:
  stable/8/sys/kern/kern_sig.c
  stable/8/sys/kern/sys_process.c
  stable/8/sys/sys/proc.h
  stable/8/sys/sys/ptrace.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/kern/kern_sig.c
==============================================================================
--- stable/8/sys/kern/kern_sig.c	Wed Nov  3 21:21:12 2010	(r214755)
+++ stable/8/sys/kern/kern_sig.c	Wed Nov  3 21:24:21 2010	(r214756)
@@ -2517,7 +2517,6 @@ issignal(struct thread *td, int stop_all
 	struct sigacts *ps;
 	struct sigqueue *queue;
 	sigset_t sigpending;
-	ksiginfo_t ksi;
 	int sig, prop, newsig;
 
 	p = td->td_proc;
@@ -2560,10 +2559,10 @@ issignal(struct thread *td, int stop_all
 			 * be thrown away.
 			 */
 			queue = &td->td_sigqueue;
-			ksi.ksi_signo = 0;
-			if (sigqueue_get(queue, sig, &ksi) == 0) {
+			td->td_dbgksi.ksi_signo = 0;
+			if (sigqueue_get(queue, sig, &td->td_dbgksi) == 0) {
 				queue = &p->p_sigqueue;
-				sigqueue_get(queue, sig, &ksi);
+				sigqueue_get(queue, sig, &td->td_dbgksi);
 			}
 
 			mtx_unlock(&ps->ps_mtx);
@@ -2590,13 +2589,13 @@ issignal(struct thread *td, int stop_all
 					continue;
 				signotify(td);
 			} else {
-				if (ksi.ksi_signo != 0) {
-					ksi.ksi_flags |= KSI_HEAD;
+				if (td->td_dbgksi.ksi_signo != 0) {
+					td->td_dbgksi.ksi_flags |= KSI_HEAD;
 					if (sigqueue_add(&td->td_sigqueue, sig,
-					    &ksi) != 0)
-						ksi.ksi_signo = 0;
+					    &td->td_dbgksi) != 0)
+						td->td_dbgksi.ksi_signo = 0;
 				}
-				if (ksi.ksi_signo == 0)
+				if (td->td_dbgksi.ksi_signo == 0)
 					sigqueue_add(&td->td_sigqueue, sig,
 					    NULL);
 			}

Modified: stable/8/sys/kern/sys_process.c
==============================================================================
--- stable/8/sys/kern/sys_process.c	Wed Nov  3 21:21:12 2010	(r214755)
+++ stable/8/sys/kern/sys_process.c	Wed Nov  3 21:24:21 2010	(r214756)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 
 #ifdef COMPAT_FREEBSD32
 #include <sys/procfs.h>
+#include <compat/freebsd32/freebsd32_signal.h>
 
 struct ptrace_io_desc32 {
 	int		piod_op;
@@ -84,6 +85,15 @@ struct ptrace_vm_entry32 {
 	uint32_t	pve_path;
 };
 
+struct ptrace_lwpinfo32 {
+	lwpid_t	pl_lwpid;	/* LWP described. */
+	int	pl_event;	/* Event that stopped the LWP. */
+	int	pl_flags;	/* LWP flags. */
+	sigset_t	pl_sigmask;	/* LWP signal mask */
+	sigset_t	pl_siglist;	/* LWP pending signal */
+	struct siginfo32 pl_siginfo;	/* siginfo for signal */
+};
+
 #endif
 
 /*
@@ -495,6 +505,19 @@ ptrace_vm_entry32(struct thread *td, str
 	pve32->pve_pathlen = pve.pve_pathlen;
 	return (error);
 }
+
+static void
+ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
+    struct ptrace_lwpinfo32 *pl32)
+{
+
+	pl32->pl_lwpid = pl->pl_lwpid;
+	pl32->pl_event = pl->pl_event;
+	pl32->pl_flags = pl->pl_flags;
+	pl32->pl_sigmask = pl->pl_sigmask;
+	pl32->pl_siglist = pl->pl_siglist;
+	siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
+}
 #endif /* COMPAT_FREEBSD32 */
 
 /*
@@ -549,6 +572,7 @@ ptrace(struct thread *td, struct ptrace_
 		struct fpreg32 fpreg32;
 		struct reg32 reg32;
 		struct ptrace_io_desc32 piod32;
+		struct ptrace_lwpinfo32 pl32;
 		struct ptrace_vm_entry32 pve32;
 #endif
 	} r;
@@ -659,6 +683,8 @@ kern_ptrace(struct thread *td, int req, 
 #ifdef COMPAT_FREEBSD32
 	int wrap32 = 0, safe = 0;
 	struct ptrace_io_desc32 *piod32 = NULL;
+	struct ptrace_lwpinfo32 *pl32 = NULL;
+	struct ptrace_lwpinfo plr;
 #endif
 
 	curp = td->td_proc;
@@ -1100,15 +1126,44 @@ kern_ptrace(struct thread *td, int req, 
 		break;
 
 	case PT_LWPINFO:
-		if (data <= 0 || data > sizeof(*pl)) {
+		if (data <= 0 ||
+#ifdef COMPAT_FREEBSD32
+		    (!wrap32 && data > sizeof(*pl)) ||
+		    (wrap32 && data > sizeof(*pl32))) {
+#else
+		    data > sizeof(*pl)) {
+#endif
 			error = EINVAL;
 			break;
 		}
+#ifdef COMPAT_FREEBSD32
+		if (wrap32) {
+			pl = &plr;
+			pl32 = addr;
+		} else
+#endif
 		pl = addr;
 		pl->pl_lwpid = td2->td_tid;
-		if (td2->td_dbgflags & TDB_XSIG)
-			pl->pl_event = PL_EVENT_SIGNAL;
 		pl->pl_flags = 0;
+		if (td2->td_dbgflags & TDB_XSIG) {
+			pl->pl_event = PL_EVENT_SIGNAL;
+			if (td2->td_dbgksi.ksi_signo != 0 &&
+#ifdef COMPAT_FREEBSD32
+			    ((!wrap32 && data >= offsetof(struct ptrace_lwpinfo,
+			    pl_siginfo) + sizeof(pl->pl_siginfo)) ||
+			    (wrap32 && data >= offsetof(struct ptrace_lwpinfo32,
+			    pl_siginfo) + sizeof(struct siginfo32)))
+#else
+			    data >= offsetof(struct ptrace_lwpinfo, pl_siginfo)
+			    + sizeof(pl->pl_siginfo)
+#endif
+			){
+				pl->pl_flags |= PL_FLAG_SI;
+				pl->pl_siginfo = td2->td_dbgksi.ksi_info;
+			}
+		}
+		if ((pl->pl_flags & PL_FLAG_SI) == 0)
+			bzero(&pl->pl_siginfo, sizeof(pl->pl_siginfo));
 		if (td2->td_dbgflags & TDB_SCE)
 			pl->pl_flags |= PL_FLAG_SCE;
 		else if (td2->td_dbgflags & TDB_SCX)
@@ -1117,6 +1172,10 @@ kern_ptrace(struct thread *td, int req, 
 			pl->pl_flags |= PL_FLAG_EXEC;
 		pl->pl_sigmask = td2->td_sigmask;
 		pl->pl_siglist = td2->td_siglist;
+#ifdef COMPAT_FREEBSD32
+		if (wrap32)
+			ptrace_lwpinfo_to32(pl, pl32);
+#endif
 		break;
 
 	case PT_GETNUMLWPS:

Modified: stable/8/sys/sys/proc.h
==============================================================================
--- stable/8/sys/sys/proc.h	Wed Nov  3 21:21:12 2010	(r214755)
+++ stable/8/sys/sys/proc.h	Wed Nov  3 21:24:21 2010	(r214756)
@@ -257,6 +257,7 @@ struct thread {
 	char		td_name[MAXCOMLEN + 1];	/* (*) Thread name. */
 	struct file	*td_fpop;	/* (k) file referencing cdev under op */
 	int		td_dbgflags;	/* (c) Userland debugger flags */
+	struct ksiginfo td_dbgksi;	/* (c) ksi reflected to debugger. */
 	int		td_ng_outbound;	/* (k) Thread entered ng from above. */
 	struct osd	td_osd;		/* (k) Object specific data. */
 #define	td_endzero td_base_pri

Modified: stable/8/sys/sys/ptrace.h
==============================================================================
--- stable/8/sys/sys/ptrace.h	Wed Nov  3 21:21:12 2010	(r214755)
+++ stable/8/sys/sys/ptrace.h	Wed Nov  3 21:24:21 2010	(r214756)
@@ -33,7 +33,7 @@
 #ifndef	_SYS_PTRACE_H_
 #define	_SYS_PTRACE_H_
 
-#include <sys/_sigset.h>
+#include <sys/signal.h>
 #include <machine/reg.h>
 
 #define	PT_TRACE_ME	0	/* child declares it's being traced */
@@ -102,8 +102,10 @@ struct ptrace_lwpinfo {
 #define	PL_FLAG_SCE	0x04	/* syscall enter point */
 #define	PL_FLAG_SCX	0x08	/* syscall leave point */
 #define	PL_FLAG_EXEC	0x10	/* exec(2) succeeded */
+#define	PL_FLAG_SI	0x20	/* siginfo is valid */
 	sigset_t	pl_sigmask;	/* LWP signal mask */
 	sigset_t	pl_siglist;	/* LWP pending signal */
+	struct __siginfo pl_siginfo;	/* siginfo for signal */
 };
 
 /* Argument structure for PT_VM_ENTRY. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011032124.oA3LOLJ7033869>