svn commit: r363928 - in head: lib/libpmcstat usr.sbin/pmcstat

Mateusz Guzik mjg at FreeBSD.org
Wed Aug 5 19:05:50 UTC 2020


Author: mjg
Date: Wed Aug  5 19:05:49 2020
New Revision: 363928
URL: https://svnweb.freebsd.org/changeset/base/363928

Log:
  pmcstat: implement showing offsets into symbols in top mode
  
  The -I option (and hotkey) is reused for this. Skipping symbol resolution is
  moved to the new -A option (and hotkey).
  
  While arguably this violates POLA I think it's a change for the better.
  ALso note the -I option was added in head.
  
  Differential Revision:	https://reviews.freebsd.org/D21658

Modified:
  head/lib/libpmcstat/libpmcstat.h
  head/usr.sbin/pmcstat/pmcpl_callgraph.c
  head/usr.sbin/pmcstat/pmcstat.8
  head/usr.sbin/pmcstat/pmcstat.c
  head/usr.sbin/pmcstat/pmcstat_log.c

Modified: head/lib/libpmcstat/libpmcstat.h
==============================================================================
--- head/lib/libpmcstat/libpmcstat.h	Wed Aug  5 18:22:24 2020	(r363927)
+++ head/lib/libpmcstat/libpmcstat.h	Wed Aug  5 19:05:49 2020	(r363928)
@@ -107,8 +107,9 @@ struct pmcstat_args {
 #define	FLAGS_HAS_CPUMASK		0x00040000	/* -c */
 #define	FLAG_HAS_DURATION		0x00080000	/* -l secs */
 #define	FLAG_DO_WIDE_GPROF_HC		0x00100000	/* -e */
-#define	FLAG_SKIP_TOP_FN_RES		0x00200000	/* -I */
+#define	FLAG_SKIP_TOP_FN_RES		0x00200000	/* -A */
 #define	FLAG_FILTER_THREAD_ID		0x00400000	/* -L */
+#define	FLAG_SHOW_OFFSET		0x00800000	/* -I */
 
 	int	pa_required;		/* required features */
 	int	pa_pplugin;		/* pre-processing plugin */

Modified: head/usr.sbin/pmcstat/pmcpl_callgraph.c
==============================================================================
--- head/usr.sbin/pmcstat/pmcpl_callgraph.c	Wed Aug  5 18:22:24 2020	(r363927)
+++ head/usr.sbin/pmcstat/pmcpl_callgraph.c	Wed Aug  5 19:05:49 2020	(r363928)
@@ -152,10 +152,12 @@ pmcstat_cgnode_hash_lookup_pc(struct pmcstat_process *
 	 * Try determine the function at this offset.  If we can't
 	 * find a function round leave the `pc' value alone.
 	 */
-	if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
-		pc = sym->ps_start;
-	else
-		pmcstat_stats.ps_samples_unknown_function++;
+	if (!(args.pa_flags & (FLAG_SKIP_TOP_FN_RES | FLAG_SHOW_OFFSET))) {
+		if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
+			pc = sym->ps_start;
+		else
+			pmcstat_stats.ps_samples_unknown_function++;
+	}
 
 	for (hash = i = 0; i < sizeof(uintfptr_t); i++)
 		hash += (pc >> i) & 0xFF;
@@ -485,22 +487,35 @@ pmcstat_cgnode_topprint(struct pmcstat_cgnode *cg,
 	v = PMCPL_CG_COUNTP(cg);
 	snprintf(vs, sizeof(vs), "%.1f", v);
 	v_attrs = PMCSTAT_ATTRPERCENT(v);
-	sym = NULL;
 
 	/* Format name. */
-	if (!(args.pa_flags & FLAG_SKIP_TOP_FN_RES))
-		sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
-	if (sym != NULL) {
-		snprintf(ns, sizeof(ns), "%s",
-		    pmcstat_string_unintern(sym->ps_name));
-	} else
+	sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
+	if (sym == NULL) {
 		snprintf(ns, sizeof(ns), "%p",
 		    (void *)(cg->pcg_image->pi_vaddr + cg->pcg_func));
+	} else {
+		switch (args.pa_flags & (FLAG_SKIP_TOP_FN_RES | FLAG_SHOW_OFFSET)) {
+		case FLAG_SKIP_TOP_FN_RES | FLAG_SHOW_OFFSET:
+		case FLAG_SKIP_TOP_FN_RES:
+			snprintf(ns, sizeof(ns), "%p",
+			    (void *)(cg->pcg_image->pi_vaddr + cg->pcg_func));
+			break;
+		case FLAG_SHOW_OFFSET:
+			snprintf(ns, sizeof(ns), "%s+%#0lx",
+			    pmcstat_string_unintern(sym->ps_name),
+			    cg->pcg_func - sym->ps_start);
+			break;
+		default:
+			snprintf(ns, sizeof(ns), "%s",
+			    pmcstat_string_unintern(sym->ps_name));
+			break;
+		}
+	}
 
 	PMCSTAT_ATTRON(v_attrs);
 	PMCSTAT_PRINTW("%5.5s", vs);
 	PMCSTAT_ATTROFF(v_attrs);
-	PMCSTAT_PRINTW(" %-10.10s %-20.20s",
+	PMCSTAT_PRINTW(" %-10.10s %-30.30s",
 	    pmcstat_string_unintern(cg->pcg_image->pi_name),
 	    ns);
 
@@ -624,7 +639,7 @@ pmcpl_cg_topdisplay(void)
 	qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
 	    pmcstat_cgnode_compare);
 
-	PMCSTAT_PRINTW("%5.5s %-10.10s %-20.20s %s\n",
+	PMCSTAT_PRINTW("%5.5s %-10.10s %-30.30s %s\n",
 	    "%SAMP", "IMAGE", "FUNCTION", "CALLERS");
 
 	nentries = min(pmcstat_displayheight - 2, nentries);

Modified: head/usr.sbin/pmcstat/pmcstat.8
==============================================================================
--- head/usr.sbin/pmcstat/pmcstat.8	Wed Aug  5 18:22:24 2020	(r363927)
+++ head/usr.sbin/pmcstat/pmcstat.8	Wed Aug  5 19:05:49 2020	(r363928)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 25, 2018
+.Dd August 5, 2020
 .Dt PMCSTAT 8
 .Os
 .Sh NAME
@@ -33,6 +33,7 @@
 .Nd "performance measurement with performance monitoring hardware"
 .Sh SYNOPSIS
 .Nm
+.Op Fl A
 .Op Fl C
 .Op Fl D Ar pathname
 .Op Fl E
@@ -123,6 +124,8 @@ process' current and future children.
 .Sh OPTIONS
 The following options are available:
 .Bl -tag -width indent
+.It Fl A
+Skip symbol lookup and display address instead.
 .It Fl C
 Toggle between showing cumulative or incremental counts for
 subsequent counting mode PMCs specified on the command line.
@@ -161,7 +164,7 @@ this information is sent to the output file specified 
 .Fl o
 option.
 .It Fl I
-Skip symbol lookup and display address instead.
+Show the offset of the instruction pointer into the symbol.
 .It Fl L
 List all event names.
 .It Fl M Ar mapfilename
@@ -222,10 +225,10 @@ specified in
 .Ar event-spec .
 .It Fl T
 Use a top like mode for sampling PMCs. The following hotkeys
-can be used: 'c+a' switch to accumulative mode, 'c+d' switch
-to delta mode, 'm' merge PMCs, 'n' change view, 'p' show next
-PMC, ' ' pause, 'q' quit. calltree only: 'f' cost under threshold
-is seen as a dot.
+can be used: 'A' toggle symbol resolution, 'c+a' switch to accumulative mode, 'c+d'
+switch to delta mode, 'I' toggle showing offsets into symbols, 'm' merge PMCs, 'n'
+change view, 'p' show next PMC, ' ' pause, 'q' quit. calltree only: 'f' cost under
+threshold is seen as a dot.
 .It Fl U
 Toggle capturing user-space call traces while in kernel mode.
 The default is for sampling PMCs to capture user-space callchain information

Modified: head/usr.sbin/pmcstat/pmcstat.c
==============================================================================
--- head/usr.sbin/pmcstat/pmcstat.c	Wed Aug  5 18:22:24 2020	(r363927)
+++ head/usr.sbin/pmcstat/pmcstat.c	Wed Aug  5 19:05:49 2020	(r363928)
@@ -511,8 +511,12 @@ main(int argc, char **argv)
 	CPU_COPY(&rootmask, &cpumask);
 
 	while ((option = getopt(argc, argv,
-	    "CD:EF:G:ILM:NO:P:R:S:TUWZa:c:def:gi:k:l:m:n:o:p:qr:s:t:u:vw:z:")) != -1)
+	    "ACD:EF:G:ILM:NO:P:R:S:TUWZa:c:def:gi:k:l:m:n:o:p:qr:s:t:u:vw:z:")) != -1)
 		switch (option) {
+		case 'A':
+			args.pa_flags |= FLAG_SKIP_TOP_FN_RES;
+			break;
+
 		case 'a':	/* Annotate + callgraph */
 			args.pa_flags |= FLAG_DO_ANNOTATE;
 			args.pa_plugin = PMCSTAT_PL_ANNOTATE_CG;
@@ -586,12 +590,13 @@ main(int argc, char **argv)
 			args.pa_plugin	= PMCSTAT_PL_GPROF;
 			break;
 
-		case 'I':
-			args.pa_flags |= FLAG_SKIP_TOP_FN_RES;
-			break;
 		case 'i':
 			args.pa_flags |= FLAG_FILTER_THREAD_ID;
 			args.pa_tid = strtol(optarg, &end, 0);
+			break;
+
+		case 'I':
+			args.pa_flags |= FLAG_SHOW_OFFSET;
 			break;
 
 		case 'k':	/* pathname to the kernel */

Modified: head/usr.sbin/pmcstat/pmcstat_log.c
==============================================================================
--- head/usr.sbin/pmcstat/pmcstat_log.c	Wed Aug  5 18:22:24 2020	(r363927)
+++ head/usr.sbin/pmcstat/pmcstat_log.c	Wed Aug  5 19:05:49 2020	(r363928)
@@ -612,6 +612,12 @@ pmcstat_keypress_log(void)
 	c = wgetch(w);
 	wprintw(w, "Key: %c => ", c);
 	switch (c) {
+	case 'A':
+		if (args.pa_flags & FLAG_SKIP_TOP_FN_RES)
+			args.pa_flags &= ~FLAG_SKIP_TOP_FN_RES;
+		else
+			args.pa_flags |= FLAG_SKIP_TOP_FN_RES;
+		break;
 	case 'c':
 		wprintw(w, "enter mode 'd' or 'a' => ");
 		c = wgetch(w);
@@ -622,6 +628,12 @@ pmcstat_keypress_log(void)
 			args.pa_topmode = PMCSTAT_TOP_ACCUM;
 			wprintw(w, "switching to accumulation mode");
 		}
+		break;
+	case 'I':
+		if (args.pa_flags & FLAG_SHOW_OFFSET)
+			args.pa_flags &= ~FLAG_SHOW_OFFSET;
+		else
+			args.pa_flags |= FLAG_SHOW_OFFSET;
 		break;
 	case 'm':
 		pmcstat_mergepmc = !pmcstat_mergepmc;


More information about the svn-src-head mailing list