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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to