Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Dec 2016 04:20:32 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r309595 - in head: cddl/lib/libdtrace lib/libproc lib/libproc/tests
Message-ID:  <201612060420.uB64KWWS063884@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Tue Dec  6 04:20:32 2016
New Revision: 309595
URL: https://svnweb.freebsd.org/changeset/base/309595

Log:
  libproc: Match prefixes when looking up mapped object by name.
  
  When looking up an object by name, allow prefix matches if no direct match
  is found. This allows one to, for example, match libc entry probes with:
  
   # dtrace -n 'pid$target:libc.so::entry' -c ./foo
  
  instead of requiring "libc.so.7" or a glob.
  
  Also remove proc_obj2map() as it currently just duplicates the
  functionality of proc_name2map(). It's supposed to take a Solaris
  link-map ID as a paramter, but support for this isn't implemented and
  isn't required to support DTrace's pid provider.

Modified:
  head/cddl/lib/libdtrace/libproc_compat.h
  head/lib/libproc/libproc.h
  head/lib/libproc/proc_sym.c
  head/lib/libproc/tests/proc_test.c

Modified: head/cddl/lib/libdtrace/libproc_compat.h
==============================================================================
--- head/cddl/lib/libdtrace/libproc_compat.h	Tue Dec  6 04:19:08 2016	(r309594)
+++ head/cddl/lib/libdtrace/libproc_compat.h	Tue Dec  6 04:20:32 2016	(r309595)
@@ -44,7 +44,7 @@
 #define	Pdelbkpt proc_bkptdel
 #define	Pgrab_error strerror
 #define	Plmid(p, a, l) (-1)
-#define	Plmid_to_map(p, l, o) proc_obj2map((p), (o))
+#define	Plmid_to_map(p, l, o) proc_name2map(p, o)
 #define	Plookup_by_addr proc_addr2sym
 #define	Pname_to_ctf(p, obj) (ctf_file_t *)proc_name2ctf(p, obj)
 #define	Pname_to_map proc_name2map

Modified: head/lib/libproc/libproc.h
==============================================================================
--- head/lib/libproc/libproc.h	Tue Dec  6 04:19:08 2016	(r309594)
+++ head/lib/libproc/libproc.h	Tue Dec  6 04:20:32 2016	(r309595)
@@ -128,7 +128,6 @@ __BEGIN_DECLS
 prmap_t *proc_addr2map(struct proc_handle *, uintptr_t);
 prmap_t *proc_name2map(struct proc_handle *, const char *);
 char	*proc_objname(struct proc_handle *, uintptr_t, char *, size_t);
-prmap_t *proc_obj2map(struct proc_handle *, const char *);
 int	proc_iter_objs(struct proc_handle *, proc_map_f *, void *);
 int	proc_iter_symbyaddr(struct proc_handle *, const char *, int,
 	    int, proc_sym_f *, void *);

Modified: head/lib/libproc/proc_sym.c
==============================================================================
--- head/lib/libproc/proc_sym.c	Tue Dec  6 04:19:08 2016	(r309594)
+++ head/lib/libproc/proc_sym.c	Tue Dec  6 04:20:32 2016	(r309595)
@@ -274,31 +274,6 @@ proc_objname(struct proc_handle *p, uint
 	return (NULL);
 }
 
-/*
- * Currently just returns the first mapping of the named object, effectively
- * what Plmid_to_map(p, PR_LMID_EVERY, objname) does in illumos libproc.
- */
-prmap_t *
-proc_obj2map(struct proc_handle *p, const char *objname)
-{
-	char path[PATH_MAX], *base;
-	prmap_t *map;
-	size_t i;
-
-	map = NULL;
-	for (i = 0; i < p->nmappings; i++) {
-		strlcpy(path, p->mappings[i].map.pr_mapname, sizeof(path));
-		base = basename(path);
-		if (strcmp(base, objname) == 0) {
-			map = &p->mappings[i].map;
-			break;
-		}
-	}
-	if (map == NULL && strcmp(objname, "a.out") == 0 && p->exec_map != NULL)
-		map = p->exec_map;
-	return (map);
-}
-
 int
 proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd)
 {
@@ -468,9 +443,10 @@ _proc_name2map(struct proc_handle *p, co
 {
 	char path[MAXPATHLEN], *base;
 	struct map_info *mapping;
-	size_t i;
+	size_t i, len;
 
-	mapping = NULL;
+	if ((len = strlen(name)) == 0)
+		return (NULL);
 	if (p->nmappings == 0)
 		if (proc_rdagent(p) == NULL)
 			return (NULL);
@@ -479,13 +455,18 @@ _proc_name2map(struct proc_handle *p, co
 		(void)strlcpy(path, mapping->map.pr_mapname, sizeof(path));
 		base = basename(path);
 		if (strcmp(base, name) == 0)
-			break;
+			return (mapping);
+	}
+	/* If we didn't find a match, try matching prefixes of the basename. */
+	for (i = 0; i < p->nmappings; i++) {
+		strlcpy(path, p->mappings[i].map.pr_mapname, sizeof(path));
+		base = basename(path);
+		if (strncmp(base, name, len) == 0)
+			return (&p->mappings[i]);
 	}
-	if (i == p->nmappings)
-		mapping = NULL;
-	if (mapping == NULL && strcmp(name, "a.out") == 0)
-		mapping = _proc_addr2map(p, p->exec_map->pr_vaddr);
-	return (mapping);
+	if (strcmp(name, "a.out") == 0)
+		return (_proc_addr2map(p, p->exec_map->pr_vaddr));
+	return (NULL);
 }
 
 prmap_t *

Modified: head/lib/libproc/tests/proc_test.c
==============================================================================
--- head/lib/libproc/tests/proc_test.c	Tue Dec  6 04:19:08 2016	(r309594)
+++ head/lib/libproc/tests/proc_test.c	Tue Dec  6 04:20:32 2016	(r309595)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2014, 2015 Mark Johnston <markj@FreeBSD.org>
+ * Copyright (c) 2014-2016 Mark Johnston <markj@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -152,15 +152,15 @@ verify_bkpt(struct proc_handle *phdl, GE
 	    "expected map name '%s' doesn't match '%s'", mapname, mapbname);
 }
 
-ATF_TC(map_alias_obj2map);
-ATF_TC_HEAD(map_alias_obj2map, tc)
+ATF_TC(map_alias_name2map);
+ATF_TC_HEAD(map_alias_name2map, tc)
 {
 	atf_tc_set_md_var(tc, "descr",
 	    "Callers are supposed to be able to use \"a.out\" as an alias for "
-	    "the program executable. Make sure that proc_obj2map() handles "
+	    "the program executable. Make sure that proc_name2map() handles "
 	    "this properly.");
 }
-ATF_TC_BODY(map_alias_obj2map, tc)
+ATF_TC_BODY(map_alias_name2map, tc)
 {
 	struct proc_handle *phdl;
 	prmap_t *map1, *map2;
@@ -171,10 +171,10 @@ ATF_TC_BODY(map_alias_obj2map, tc)
 	(void)proc_rdagent(phdl);
 
 	/* Ensure that "target_prog" and "a.out" return the same map. */
-	map1 = proc_obj2map(phdl, target_prog_file);
+	map1 = proc_name2map(phdl, target_prog_file);
 	ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'",
 	    target_prog_file);
-	map2 = proc_obj2map(phdl, aout_object);
+	map2 = proc_name2map(phdl, aout_object);
 	ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'",
 	    aout_object);
 	ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);
@@ -184,15 +184,14 @@ ATF_TC_BODY(map_alias_obj2map, tc)
 	proc_free(phdl);
 }
 
-ATF_TC(map_alias_name2map);
-ATF_TC_HEAD(map_alias_name2map, tc)
+ATF_TC(map_prefix_name2map);
+ATF_TC_HEAD(map_prefix_name2map, tc)
 {
 	atf_tc_set_md_var(tc, "descr",
-	    "Callers are supposed to be able to use \"a.out\" as an alias for "
-	    "the program executable. Make sure that proc_name2map() handles "
-	    "this properly.");
+	    "Verify that proc_name2map() returns prefix matches of the "
+	    "basename of loaded objects if no full matches are found.");
 }
-ATF_TC_BODY(map_alias_name2map, tc)
+ATF_TC_BODY(map_prefix_name2map, tc)
 {
 	struct proc_handle *phdl;
 	prmap_t *map1, *map2;
@@ -202,13 +201,11 @@ ATF_TC_BODY(map_alias_name2map, tc)
 	/* Initialize the rtld_db handle. */
 	(void)proc_rdagent(phdl);
 
-	/* Ensure that "target_prog" and "a.out" return the same map. */
-	map1 = proc_name2map(phdl, target_prog_file);
-	ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'",
-	    target_prog_file);
-	map2 = proc_name2map(phdl, aout_object);
-	ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'",
-	    aout_object);
+	/* Make sure that "ld-elf" and "ld-elf.so" return the same map. */
+	map1 = proc_name2map(phdl, "ld-elf");
+	ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for 'ld-elf'");
+	map2 = proc_name2map(phdl, "ld-elf.so");
+	ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for 'ld-elf.so'");
 	ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);
 
 	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
@@ -315,7 +312,7 @@ ATF_TC_BODY(symbol_lookup_fail, tc)
 	/* Initialize the rtld_db handle. */
 	(void)proc_rdagent(phdl);
 
-	map = proc_obj2map(phdl, target_prog_file);
+	map = proc_name2map(phdl, target_prog_file);
 	ATF_REQUIRE_MSG(map != NULL, "failed to look up map for '%s'",
 	    target_prog_file);
 
@@ -376,8 +373,8 @@ ATF_TC_BODY(signal_forward, tc)
 ATF_TP_ADD_TCS(tp)
 {
 
-	ATF_TP_ADD_TC(tp, map_alias_obj2map);
 	ATF_TP_ADD_TC(tp, map_alias_name2map);
+	ATF_TP_ADD_TC(tp, map_prefix_name2map);
 	ATF_TP_ADD_TC(tp, map_alias_name2sym);
 	ATF_TP_ADD_TC(tp, symbol_lookup);
 	ATF_TP_ADD_TC(tp, symbol_lookup_fail);



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