Remove tpfmt(1). Its code was merged into tprof(8).

This commit is contained in:
maxv 2018-07-13 11:14:14 +00:00
parent 1b11df59cf
commit 5ae6235d0e
11 changed files with 11 additions and 636 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1178 2018/06/29 12:34:14 roy Exp $
# $NetBSD: mi,v 1.1179 2018/07/13 11:14:14 maxv Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -974,7 +974,7 @@
./usr/bin/tn3270 base-obsolete obsolete
./usr/bin/top base-util-bin
./usr/bin/touch base-util-bin
./usr/bin/tpfmt base-util-bin
./usr/bin/tpfmt base-obsolete obsolete
./usr/bin/tpm_sealdata base-tpm-bin tpm
./usr/bin/tpm_unsealdata base-tpm-bin tpm
./usr/bin/tpm_version base-tpm-bin tpm

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.256 2018/06/29 12:34:14 roy Exp $
# $NetBSD: mi,v 1.257 2018/07/13 11:14:14 maxv Exp $
./etc/mtree/set.debug comp-sys-root
./usr/lib comp-sys-usr compatdir
./usr/lib/i18n/libBIG5_g.a comp-c-debuglib debuglib,compatfile
@ -803,7 +803,7 @@
./usr/libdata/debug/usr/bin/tn3270.debug comp-obsolete obsolete
./usr/libdata/debug/usr/bin/top.debug comp-util-debug debug
./usr/libdata/debug/usr/bin/touch.debug comp-util-debug debug
./usr/libdata/debug/usr/bin/tpfmt.debug comp-util-debug debug
./usr/libdata/debug/usr/bin/tpfmt.debug comp-obsolete obsolete
./usr/libdata/debug/usr/bin/tpm_sealdata.debug comp-tpm-debug tpm,debug
./usr/libdata/debug/usr/bin/tpm_unsealdata.debug comp-tpm-debug tpm,debug
./usr/libdata/debug/usr/bin/tpm_version.debug comp-tpm-debug tpm,debug

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1597 2018/07/13 09:15:56 maxv Exp $
# $NetBSD: mi,v 1.1598 2018/07/13 11:14:14 maxv Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -573,7 +573,7 @@
./usr/share/man/cat1/tn3270.0 man-obsolete obsolete
./usr/share/man/cat1/top.0 man-util-catman .cat
./usr/share/man/cat1/touch.0 man-util-catman .cat
./usr/share/man/cat1/tpfmt.0 man-util-catman .cat
./usr/share/man/cat1/tpfmt.0 man-obsolete obsolete
./usr/share/man/cat1/tpm_sealdata.0 man-tpm-catman tpm,.cat
./usr/share/man/cat1/tpm_version.0 man-tpm-catman tpm,.cat
./usr/share/man/cat1/tput.0 man-util-catman .cat
@ -3777,7 +3777,7 @@
./usr/share/man/html1/tn3270.html man-obsolete obsolete
./usr/share/man/html1/top.html man-util-htmlman html
./usr/share/man/html1/touch.html man-util-htmlman html
./usr/share/man/html1/tpfmt.html man-util-htmlman html
./usr/share/man/html1/tpfmt.html man-obsolete obsolete
./usr/share/man/html1/tpm_sealdata.html man-tpm-htmlman tpm,html
./usr/share/man/html1/tpm_version.html man-tpm-htmlman tpm,html
./usr/share/man/html1/tput.html man-util-htmlman html
@ -6635,7 +6635,7 @@
./usr/share/man/man1/tn3270.1 man-obsolete obsolete
./usr/share/man/man1/top.1 man-util-man .man
./usr/share/man/man1/touch.1 man-util-man .man
./usr/share/man/man1/tpfmt.1 man-util-man .man
./usr/share/man/man1/tpfmt.1 man-obsolete obsolete
./usr/share/man/man1/tpm_sealdata.1 man-tpm-man tpm,.man
./usr/share/man/man1/tpm_version.1 man-tpm-man tpm,.man
./usr/share/man/man1/tput.1 man-util-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.230 2018/07/13 11:13:10 mrg Exp $
# $NetBSD: Makefile,v 1.231 2018/07/13 11:14:14 maxv Exp $
# from: @(#)Makefile 8.3 (Berkeley) 1/7/94
.include <bsd.own.mk>
@ -28,7 +28,7 @@ SUBDIR= apply asa at audio audiocfg \
showmount shuffle sockstat sort sortinfo \
spell split stat su sys_info systat \
tabs tail talk tcopy tee telnet tftp tic time timeout tip touch \
tpfmt tput \
tput \
tr true tset tsort tty ul uname unexpand unifdef \
uniq units unvis unzip usbhidaction usbhidctl users utoppya \
uudecode uuencode uuidgen vacation vgrind videoctl vis \

View File

@ -1,14 +0,0 @@
# $NetBSD: Makefile,v 1.4 2011/11/26 16:15:09 yamt Exp $
PROG= tpfmt
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/
SRCS= tpfmt.c sym.c
LDADD+= -lelf
LDADD+= -lutil
DPADD+= ${LIBELF}
DPADD+= ${LIBUTIL}
.include <bsd.own.mk>
.include <bsd.prog.mk>

View File

@ -1,3 +0,0 @@
$Id: README,v 1.1 2010/11/23 20:48:40 yamt Exp $
it's a C-version of tpfmt.sh. see usr.sbin/tprof/README for the usage.

View File

@ -1,185 +0,0 @@
/* $NetBSD: sym.c,v 1.4 2012/02/03 05:06:08 yamt Exp $ */
/*-
* Copyright (c) 2010,2011,2012 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: sym.c,v 1.4 2012/02/03 05:06:08 yamt Exp $");
#endif /* not lint */
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <gelf.h>
#include <inttypes.h>
#include <libelf.h>
#include <stdlib.h>
#include <string.h>
#include <util.h>
#include "sym.h"
struct sym {
char *name;
uint64_t value;
uint64_t size;
};
static struct sym **syms = NULL;
static size_t nsyms = 0;
static int
compare_value(const void *p1, const void *p2)
{
const struct sym *s1 = *(const struct sym * const *)p1;
const struct sym *s2 = *(const struct sym * const *)p2;
if (s1->value > s2->value) {
return -1;
} else if (s1->value < s2->value) {
return 1;
}
/*
* to produce a stable result, it's better not to return 0
* even for __strong_alias.
*/
if (s1->size > s2->size) {
return -1;
} else if (s1->size < s2->size) {
return 1;
}
return strcmp(s1->name, s2->name);
}
void
ksymload(const char *ksyms)
{
Elf *e;
Elf_Scn *s;
GElf_Shdr sh_store;
GElf_Shdr *sh;
Elf_Data *d;
int fd;
size_t size, i;
fd = open(ksyms, O_RDONLY);
if (fd == -1) {
err(EXIT_FAILURE, "open");
}
if (elf_version(EV_CURRENT) == EV_NONE) {
goto elffail;
}
e = elf_begin(fd, ELF_C_READ, NULL);
if (e == NULL) {
goto elffail;
}
for (s = elf_nextscn(e, NULL); s != NULL; s = elf_nextscn(e, s)) {
sh = gelf_getshdr(s, &sh_store);
if (sh == NULL) {
goto elffail;
}
if (sh->sh_type == SHT_SYMTAB) {
break;
}
}
if (s == NULL) {
errx(EXIT_FAILURE, "no symtab");
}
d = elf_getdata(s, NULL);
if (d == NULL) {
goto elffail;
}
assert(sh->sh_size == d->d_size);
size = sh->sh_size / sh->sh_entsize;
for (i = 1; i < size; i++) {
GElf_Sym st_store;
GElf_Sym *st;
struct sym *sym;
st = gelf_getsym(d, (int)i, &st_store);
if (st == NULL) {
goto elffail;
}
if (ELF_ST_TYPE(st->st_info) != STT_FUNC) {
continue;
}
sym = emalloc(sizeof(*sym));
sym->name = estrdup(elf_strptr(e, sh->sh_link, st->st_name));
sym->value = (uint64_t)st->st_value;
sym->size = st->st_size;
nsyms++;
syms = erealloc(syms, sizeof(*syms) * nsyms);
syms[nsyms - 1] = sym;
}
qsort(syms, nsyms, sizeof(*syms), compare_value);
return;
elffail:
errx(EXIT_FAILURE, "libelf: %s", elf_errmsg(elf_errno()));
}
const char *
ksymlookup(uint64_t value, uint64_t *offset)
{
size_t hi;
size_t lo;
size_t i;
/*
* try to find the smallest i for which syms[i]->value <= value.
* syms[] is ordered by syms[]->value in the descending order.
*/
hi = nsyms - 1;
lo = 0;
while (lo < hi) {
const size_t mid = (lo + hi) / 2;
const struct sym *sym = syms[mid];
assert(syms[lo]->value >= sym->value);
assert(sym->value >= syms[hi]->value);
if (sym->value <= value) {
hi = mid;
continue;
}
lo = mid + 1;
}
assert(lo == nsyms - 1 || syms[lo]->value <= value);
assert(lo == 0 || syms[lo - 1]->value > value);
for (i = lo; i < nsyms; i++) {
const struct sym *sym = syms[i];
if (sym->value <= value &&
(sym->size == 0 || value - sym->value <= sym->size )) {
*offset = value - sym->value;
return sym->name;
}
if (sym->size != 0 && sym->value + sym->size < value) {
break;
}
}
return NULL;
}

View File

@ -1,30 +0,0 @@
/* $NetBSD: sym.h,v 1.2 2010/11/24 13:17:56 christos Exp $ */
/*-
* Copyright (c) 2010 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
void ksymload(const char *);
const char *ksymlookup(uint64_t, uint64_t *);

View File

@ -1,94 +0,0 @@
.\" $NetBSD: tpfmt.1,v 1.3 2011/12/09 15:24:39 yamt Exp $
.\"
.\" Copyright (c)2011 YAMAMOTO Takashi,
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" ------------------------------------------------------------
.Dd November 27, 2011
.Dt TPFMT 1
.Os
.\" ------------------------------------------------------------
.Sh NAME
.Nm tpfmt
.Nd format tprof samples
.\" ------------------------------------------------------------
.Sh SYNOPSIS
.Nm
.Op Fl CkLPs
.Op Fl p Ar pid
.\" ------------------------------------------------------------
.Sh DESCRIPTION
The
.Nm
utility creates and outputs a plain text representation
for a given profiling result recorded by
.Xr tprof 8 .
.\" XXX should explain the output.
.Pp
The
.Nm
utility accepts the following options.
.Bl -tag -width hogehoge
.It Fl C
Don't distinguish CPUs.
All samples are treated as its CPU number is 0.
.It Fl k
Kernel only.
Ignore samples for userland code.
.It Fl L
Don't distinguish LWPs.
All samples are treated as its LWP ID is 0.
.It Fl P
Don't distinguish processes.
All samples are treated as its PID is 0.
.It Fl p Ar pid
Process only samples for the process with PID
.Ar pid
and ignore the rest.
.It Fl s
Per symbol.
Try to aggregate samples by functions rather than instructions.
It's currently useful only for in-kernel samples.
.El
.\" ------------------------------------------------------------
.Sh EXAMPLES
See
.Xr tprof 8
for an example.
.\" ------------------------------------------------------------
.\".Sh HISTORY
.\"The
.\".Nm
.\"utility first appeared in
.\".Nx XXX .
.\" ------------------------------------------------------------
.Sh SEE ALSO
.Xr tprof 4 ,
.Xr tprof 8
.\" ------------------------------------------------------------
.Sh AUTHORS
The
.Nm
utility is written by
.An YAMAMOTO Takashi .

View File

@ -1,298 +0,0 @@
/* $NetBSD: tpfmt.c,v 1.5 2011/07/26 12:24:16 yamt Exp $ */
/*-
* Copyright (c) 2010,2011 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: tpfmt.c,v 1.5 2011/07/26 12:24:16 yamt Exp $");
#endif /* not lint */
#include <sys/rbtree.h>
#include <dev/tprof/tprof_types.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include "sym.h"
static const char ksyms[] = "/dev/ksyms";
static bool filter_by_pid;
static pid_t target_pid;
static bool per_symbol;
struct addr {
struct rb_node node;
uint64_t addr; /* address */
uint32_t pid; /* process id */
uint32_t lwpid; /* lwp id */
uint32_t cpuid; /* cpu id */
bool in_kernel; /* if addr is in the kernel address space */
unsigned int nsamples; /* number of samples taken for the address */
};
static rb_tree_t addrtree;
static signed int
/*ARGSUSED1*/
addrtree_compare_key(void *ctx, const void *n1, const void *keyp)
{
const struct addr *a1 = n1;
const struct addr *a2 = (const struct addr *)keyp;
if (a1->addr > a2->addr) {
return 1;
} else if (a1->addr < a2->addr) {
return -1;
}
if (a1->pid > a2->pid) {
return -1;
} else if (a1->pid < a2->pid) {
return 1;
}
if (a1->lwpid > a2->lwpid) {
return -1;
} else if (a1->lwpid < a2->lwpid) {
return 1;
}
if (a1->cpuid > a2->cpuid) {
return -1;
} else if (a1->cpuid < a2->cpuid) {
return 1;
}
if (a1->in_kernel > a2->in_kernel) {
return -1;
} else if (a1->in_kernel < a2->in_kernel) {
return 1;
}
return 0;
}
static signed int
addrtree_compare_nodes(void *ctx, const void *n1, const void *n2)
{
const struct addr *a2 = n2;
return addrtree_compare_key(ctx, n1, a2);
}
static const rb_tree_ops_t addrtree_ops = {
.rbto_compare_nodes = addrtree_compare_nodes,
.rbto_compare_key = addrtree_compare_key,
};
static int
compare_nsamples(const void *p1, const void *p2)
{
const struct addr *a1 = *(const struct addr * const *)p1;
const struct addr *a2 = *(const struct addr * const *)p2;
if (a1->nsamples > a2->nsamples) {
return -1;
} else if (a1->nsamples < a2->nsamples) {
return 1;
}
return 0;
}
int
/*ARGSUSED*/
main(int argc, char *argv[])
{
struct addr *a;
struct addr **l;
struct addr **p;
size_t naddrs, i;
int ch;
bool distinguish_processes = true;
bool distinguish_cpus = true;
bool distinguish_lwps = true;
bool kernel_only = false;
extern char *optarg;
extern int optind;
while ((ch = getopt(argc, argv, "CkLPp:s")) != -1) {
uintmax_t val;
char *ep;
switch (ch) {
case 'C': /* don't distinguish cpus */
distinguish_cpus = false;
break;
case 'k': /* kernel only */
kernel_only = true;
break;
case 'L': /* don't distinguish lwps */
distinguish_lwps = false;
break;
case 'p': /* only for the process for the given pid */
errno = 0;
val = strtoumax(optarg, &ep, 10);
if (optarg[0] == 0 || *ep != 0 ||
val > INT32_MAX) {
errx(EXIT_FAILURE, "invalid p option");
}
target_pid = val;
filter_by_pid = true;
break;
case 'P': /* don't distinguish processes */
distinguish_processes = false;
break;
case 's': /* per symbol */
per_symbol = true;
break;
default:
exit(EXIT_FAILURE);
}
}
argc -= optind;
argv += optind;
ksymload(ksyms);
rb_tree_init(&addrtree, &addrtree_ops);
/*
* read and count samples.
*/
naddrs = 0;
while (/*CONSTCOND*/true) {
struct addr *o;
tprof_sample_t sample;
size_t n = fread(&sample, sizeof(sample), 1, stdin);
bool in_kernel;
if (n == 0) {
if (feof(stdin)) {
break;
}
if (ferror(stdin)) {
err(EXIT_FAILURE, "fread");
}
}
if (filter_by_pid && (pid_t)sample.s_pid != target_pid) {
continue;
}
in_kernel = (sample.s_flags & TPROF_SAMPLE_INKERNEL) != 0;
if (kernel_only && !in_kernel) {
continue;
}
a = emalloc(sizeof(*a));
a->addr = (uint64_t)sample.s_pc;
if (distinguish_processes) {
a->pid = sample.s_pid;
} else {
a->pid = 0;
}
if (distinguish_lwps) {
a->lwpid = sample.s_lwpid;
} else {
a->lwpid = 0;
}
if (distinguish_cpus) {
a->cpuid = sample.s_cpuid;
} else {
a->cpuid = 0;
}
a->in_kernel = in_kernel;
if (per_symbol) {
const char *name;
uint64_t offset;
name = ksymlookup(a->addr, &offset);
if (name != NULL) {
a->addr -= offset;
}
}
a->nsamples = 1;
o = rb_tree_insert_node(&addrtree, a);
if (o != a) {
assert(a->addr == o->addr);
assert(a->pid == o->pid);
assert(a->lwpid == o->lwpid);
assert(a->cpuid == o->cpuid);
assert(a->in_kernel == o->in_kernel);
free(a);
o->nsamples++;
} else {
naddrs++;
}
}
/*
* sort samples by addresses.
*/
l = emalloc(naddrs * sizeof(*l));
p = l;
RB_TREE_FOREACH(a, &addrtree) {
*p++ = a;
}
assert(l + naddrs == p);
qsort(l, naddrs, sizeof(*l), compare_nsamples);
/*
* print addresses and number of samples, preferably with
* resolved symbol names.
*/
for (i = 0; i < naddrs; i++) {
const char *name;
char buf[100];
uint64_t offset;
a = l[i];
if (a->in_kernel) {
name = ksymlookup(a->addr, &offset);
} else {
name = NULL;
}
if (name == NULL) {
(void)snprintf(buf, sizeof(buf), "<%016" PRIx64 ">",
a->addr);
name = buf;
} else if (offset != 0) {
(void)snprintf(buf, sizeof(buf), "%s+0x%" PRIx64, name,
offset);
name = buf;
}
printf("%8u %6" PRIu32 " %4" PRIu32 " %2" PRIu32 " %u %016"
PRIx64 " %s\n",
a->nsamples, a->pid, a->lwpid, a->cpuid, a->in_kernel,
a->addr, name);
}
return EXIT_SUCCESS;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: tprof.8,v 1.6 2018/07/13 11:03:36 maxv Exp $
.\" $NetBSD: tprof.8,v 1.7 2018/07/13 11:14:14 maxv Exp $
.\"
.\" Copyright (c)2011 YAMAMOTO Takashi,
.\" All rights reserved.
@ -144,7 +144,6 @@ The number of samples dropped because the buffers containing the samples
were dropped.
.El
.Sh SEE ALSO
.Xr tpfmt 1 ,
.Xr tprof 4
.Sh AUTHORS
The