changeset 14101:d267bde9b5cf

3918 "pargs -l" dies on incomplete core dumps 3919 mdb/pmap should show unresolved map names on core dumps 3920 executable mapping in core dump misreported when file isn't found 3921 Pfindexec() finds wrong binary, wreaking havoc Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Eric Schrock <eric.schrock@delphix.com> Approved by: Dan McDonald <danmcd@nexenta.com>
author Bryan Cantrill <bryan@joyent.com>
date Thu, 28 Feb 2013 07:21:34 +0000
parents 2c12d65cf215
children 971fb4176acf
files usr/src/cmd/mdb/common/mdb/mdb_proc.c usr/src/cmd/ptools/pargs/pargs.c usr/src/cmd/ptools/pmap/pmap_common.c usr/src/lib/libproc/common/Psymtab.c usr/src/lib/libproc/common/Pzone.c
diffstat 5 files changed, 45 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/mdb/mdb_proc.c	Wed Jul 10 10:58:11 2013 -0400
+++ b/usr/src/cmd/mdb/common/mdb/mdb_proc.c	Thu Feb 28 07:21:34 2013 +0000
@@ -23,6 +23,9 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
+ */
 
 /*
  * User Process Target
@@ -122,6 +125,13 @@
     psaddr_t *);
 
 /*
+ * When debugging postmortem, we don't resolve names as we may very well not
+ * be on a system on which those names resolve.
+ */
+#define	PT_LIBPROC_RESOLVE(P) \
+	(!(mdb.m_flags & MDB_FL_LMRAW) && Pstate(P) != PS_DEAD)
+
+/*
  * The Perror_printf() function interposes on the default, empty libproc
  * definition.  It will be called to report additional information on complex
  * errors, such as a corrupt core file.  We just pass the args to vwarn.
@@ -2805,7 +2815,7 @@
 	 * Once we get the closest symbol, we perform the EXACT match or
 	 * smart-mode or absolute distance check ourself:
 	 */
-	if ((mdb.m_flags & MDB_FL_LMRAW) == 0) {
+	if (PT_LIBPROC_RESOLVE(P)) {
 		rv = Pxlookup_by_addr_resolved(P, addr, buf, nbytes,
 		    symp, &si);
 	} else {
@@ -2850,7 +2860,7 @@
 		const char *prefix = pmp->pr_mapname;
 		Lmid_t lmid;
 
-		if ((mdb.m_flags & MDB_FL_LMRAW) == 0) {
+		if (PT_LIBPROC_RESOLVE(P)) {
 			if (Pobjname_resolved(P, addr, pt->p_objname,
 			    MDB_TGT_MAPSZ))
 				prefix = pt->p_objname;
@@ -2952,7 +2962,7 @@
 			    which, type, pt_symbol_iter_cb, &ps);
 			return (0);
 		} else if (Prd_agent(t->t_pshandle) != NULL) {
-			if ((mdb.m_flags & MDB_FL_LMRAW) == 0) {
+			if (PT_LIBPROC_RESOLVE(t->t_pshandle)) {
 				(void) Pobject_iter_resolved(t->t_pshandle,
 				    pt_objsym_iter, &ps);
 			} else {
@@ -2991,7 +3001,7 @@
 	char *rv, name[MAXPATHLEN];
 	Lmid_t lmid;
 
-	if ((mdb.m_flags & MDB_FL_LMRAW) == 0) {
+	if (PT_LIBPROC_RESOLVE(P)) {
 		rv = Pobjname_resolved(P, prp->pr_vaddr, name, sizeof (name));
 	} else {
 		rv = Pobjname(P, prp->pr_vaddr, name, sizeof (name));
@@ -3057,7 +3067,7 @@
 		pm.pmap_func = func;
 		pm.pmap_private = private;
 
-		if ((mdb.m_flags & MDB_FL_LMRAW) == 0) {
+		if (PT_LIBPROC_RESOLVE(t->t_pshandle)) {
 			(void) Pmapping_iter_resolved(t->t_pshandle,
 			    pt_map_apply, &pm);
 		} else {
@@ -3086,7 +3096,7 @@
 		pm.pmap_func = func;
 		pm.pmap_private = private;
 
-		if ((mdb.m_flags & MDB_FL_LMRAW) == 0) {
+		if (PT_LIBPROC_RESOLVE(t->t_pshandle)) {
 			(void) Pobject_iter_resolved(t->t_pshandle,
 			    pt_map_apply, &pm);
 		} else {
--- a/usr/src/cmd/ptools/pargs/pargs.c	Wed Jul 10 10:58:11 2013 -0400
+++ b/usr/src/cmd/ptools/pargs/pargs.c	Thu Feb 28 07:21:34 2013 +0000
@@ -23,7 +23,7 @@
  * Use is subject to license terms.
  */
 /*
- * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
  */
 
 /*
@@ -1201,7 +1201,7 @@
 	 * an error message and bail.
 	 */
 	for (i = 0; i < datap->pd_argc; i++) {
-		if (datap->pd_argv[i] == NULL ||
+		if (datap->pd_argv == NULL || datap->pd_argv[i] == NULL ||
 		    datap->pd_argv_strs[i] == NULL) {
 			(void) fprintf(stderr, "%s: target has corrupted "
 			    "argument list\n", command);
--- a/usr/src/cmd/ptools/pmap/pmap_common.c	Wed Jul 10 10:58:11 2013 -0400
+++ b/usr/src/cmd/ptools/pmap/pmap_common.c	Thu Feb 28 07:21:34 2013 +0000
@@ -23,6 +23,9 @@
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
+ */
 
 #include <fcntl.h>
 #include <libproc.h>
@@ -68,7 +71,7 @@
 	char			path[PATH_MAX];
 	int			len;
 
-	if (lflag) {
+	if (lflag || Pstate(Pr) == PS_DEAD) {
 		if (Pobjname(Pr, addr, buf, bufsz) != NULL)
 			return (buf);
 	} else {
--- a/usr/src/lib/libproc/common/Psymtab.c	Wed Jul 10 10:58:11 2013 -0400
+++ b/usr/src/lib/libproc/common/Psymtab.c	Thu Feb 28 07:21:34 2013 +0000
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #include <assert.h>
@@ -1733,6 +1734,21 @@
 			(void) elf_end(elf);
 			elf = newelf;
 			dprintf("switched to faked up ELF file\n");
+
+			/*
+			 * Check to see if the file that we just discovered
+			 * to be an imposter matches the execname that was
+			 * determined by Pfindexec().  If it does, we (clearly)
+			 * don't have the right binary, and we zero out
+			 * execname before anyone gets hurt.
+			 */
+			if (fptr->file_rname != NULL && P->execname != NULL &&
+			    strcmp(fptr->file_rname, P->execname) == 0) {
+				dprintf("file/in-core image mismatch was "
+				    "on P->execname; discarding\n");
+				free(P->execname);
+				P->execname = NULL;
+			}
 		}
 	}
 
--- a/usr/src/lib/libproc/common/Pzone.c	Wed Jul 10 10:58:11 2013 -0400
+++ b/usr/src/lib/libproc/common/Pzone.c	Thu Feb 28 07:21:34 2013 +0000
@@ -23,6 +23,9 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
 
 #include <assert.h>
 #include <dlfcn.h>
@@ -792,9 +795,10 @@
 	    (strcmp(mptr->map_pmap.pr_mapname, "a.out") == 0) ||
 	    ((fptr != NULL) && (fptr->file_lname != NULL) &&
 	    (strcmp(fptr->file_lname, "a.out") == 0))) {
-		(void) Pexecname(P, buf, sizeof (buf));
-		(void) strlcpy(s, buf, n);
-		return (s);
+		if (Pexecname(P, buf, sizeof (buf)) != NULL) {
+			(void) strlcpy(s, buf, n);
+			return (s);
+		}
 	}
 
 	/* Try /proc first to get the real object name */