Page MenuHomeFreeBSD

D27636.id80795.diff
No OneTemporary

D27636.id80795.diff

Index: usr.bin/truss/main.c
===================================================================
--- usr.bin/truss/main.c
+++ usr.bin/truss/main.c
@@ -87,7 +87,6 @@
trussinfo->strsize = 32;
trussinfo->curthread = NULL;
LIST_INIT(&trussinfo->proclist);
- init_syscalls();
while ((c = getopt(ac, av, "p:o:facedDs:SH")) != -1) {
switch (c) {
case 'p': /* specified pid */
@@ -204,6 +203,7 @@
print_summary(trussinfo);
fflush(trussinfo->outfile);
+ free_seen_syscalls();
return (0);
}
Index: usr.bin/truss/setup.c
===================================================================
--- usr.bin/truss/setup.c
+++ usr.bin/truss/setup.c
@@ -463,8 +463,8 @@
fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n",
t->proc->abi->type, t->cs.number);
- t->cs.nargs = sc->nargs;
- assert(sc->nargs <= nitems(t->cs.s_args));
+ t->cs.nargs = sc->decode.nargs;
+ assert(sc->decode.nargs <= nitems(t->cs.s_args));
t->cs.sc = sc;
@@ -476,15 +476,16 @@
* passed in *and* out, however.
*/
#if DEBUG
- fprintf(stderr, "syscall %s(", sc->name);
+ fprintf(stderr, "syscall %d %s(", t->cs.number, sc->display_name);
#endif
for (i = 0; i < t->cs.nargs; i++) {
#if DEBUG
- fprintf(stderr, "0x%lx%s", t->cs.args[sc->args[i].offset],
+ fprintf(stderr, "%p%s",
+ (void *)t->cs.args[sc->info.args[i].offset],
i < (t->cs.nargs - 1) ? "," : "");
#endif
- if (!(sc->args[i].type & OUT)) {
- t->cs.s_args[i] = print_arg(&sc->args[i],
+ if (!(sc->decode.args[i].type & OUT)) {
+ t->cs.s_args[i] = print_arg(&sc->decode.args[i],
t->cs.args, NULL, info);
}
}
@@ -542,19 +543,19 @@
* Here, we only look for arguments that have OUT masked in --
* otherwise, they were handled in enter_syscall().
*/
- for (i = 0; i < sc->nargs; i++) {
+ for (i = 0; i < sc->decode.nargs; i++) {
char *temp;
- if (sc->args[i].type & OUT) {
+ if (sc->decode.args[i].type & OUT) {
/*
* If an error occurred, then don't bother
* getting the data; it may not be valid.
*/
if (psr.sr_error != 0) {
asprintf(&temp, "0x%lx",
- t->cs.args[sc->args[i].offset]);
+ t->cs.args[sc->decode.args[i].offset]);
} else {
- temp = print_arg(&sc->args[i],
+ temp = print_arg(&sc->decode.args[i],
t->cs.args, psr.sr_retval, info);
}
t->cs.s_args[i] = temp;
Index: usr.bin/truss/syscall.h
===================================================================
--- usr.bin/truss/syscall.h
+++ usr.bin/truss/syscall.h
@@ -216,18 +216,22 @@
_Static_assert(ARG_MASK > MAX_ARG_TYPE,
"ARG_MASK overlaps with Argtype values");
-struct syscall_args {
+struct syscall_arg {
enum Argtype type;
int offset;
};
+struct syscall_decode {
+ const char *name; /* Name for lookup calling convention lookup */
+ u_int ret_type; /* 0, 1, or 2 return values */
+ u_int nargs; /* actual number of meaningful arguments */
+ struct syscall_arg args[10]; /* Hopefully no syscalls with > 10 args */
+};
+
struct syscall {
STAILQ_ENTRY(syscall) entries;
- const char *name;
- u_int ret_type; /* 0, 1, or 2 return values */
- u_int nargs; /* actual number of meaningful arguments */
- /* Hopefully, no syscalls with > 10 args */
- struct syscall_args args[10];
+ char *display_name; /* Name to be displayed, must be malloc()'d */
+ struct syscall_decode decode;
struct timespec time; /* Time spent for this call */
int ncalls; /* Number of calls */
int nerror; /* Number of calls that returned with error */
@@ -235,7 +239,7 @@
};
struct syscall *get_syscall(struct threadinfo *, u_int, u_int);
-char *print_arg(struct syscall_args *, unsigned long*, register_t *,
+char *print_arg(struct syscall_arg *, unsigned long *, register_t *,
struct trussinfo *);
/*
@@ -278,7 +282,7 @@
char args_l_[PADL_(l_ulong)]; l_ulong args; char args_r_[PADR_(l_ulong)];
};
-void init_syscalls(void);
void print_syscall(struct trussinfo *);
void print_syscall_ret(struct trussinfo *, int, register_t *);
void print_summary(struct trussinfo *trussinfo);
+void free_seen_syscalls(void);
Index: usr.bin/truss/syscalls.c
===================================================================
--- usr.bin/truss/syscalls.c
+++ usr.bin/truss/syscalls.c
@@ -47,8 +47,10 @@
#include <sys/ioccom.h>
#include <sys/mman.h>
#include <sys/mount.h>
+#include <sys/poll.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
+#include <sys/sched.h>
#include <sys/socket.h>
#define _WANT_FREEBSD11_STAT
#include <sys/stat.h>
@@ -66,8 +68,6 @@
#define _WANT_KERNEL_ERRNO
#include <errno.h>
#include <fcntl.h>
-#include <poll.h>
-#include <sched.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
@@ -85,8 +85,13 @@
/*
* This should probably be in its own file, sorted alphabetically.
+ *
+ * Note: We only scan this table on the initial syscall number to calling
+ * convention lookup, i.e. once each time a new syscall is encountered. This
+ * is unlikely to be a performance issue, but if it is we could sort this array
+ * and use a binary search instead.
*/
-static struct syscall decoded_syscalls[] = {
+static const struct syscall_decode decoded_syscalls[] = {
/* Native ABI */
{ .name = "__acl_aclcheck_fd", .ret_type = 1, .nargs = 3,
.args = { { Int, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
@@ -702,10 +707,8 @@
{ .name = "cloudabi_sys_thread_exit", .ret_type = 1, .nargs = 2,
.args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } },
{ .name = "cloudabi_sys_thread_yield", .ret_type = 1, .nargs = 0 },
-
- { .name = 0 },
};
-static STAILQ_HEAD(, syscall) syscalls;
+static STAILQ_HEAD(, syscall) seen_syscalls;
/* Xlat idea taken from strace */
struct xlat {
@@ -965,7 +968,7 @@
* decoding arguments.
*/
static void
-quad_fixup(struct syscall *sc)
+quad_fixup(struct syscall_decode *sc)
{
int offset, prev;
u_int i;
@@ -1003,20 +1006,6 @@
}
#endif
-void
-init_syscalls(void)
-{
- struct syscall *sc;
-
- STAILQ_INIT(&syscalls);
- for (sc = decoded_syscalls; sc->name != NULL; sc++) {
-#ifndef __LP64__
- quad_fixup(sc);
-#endif
- STAILQ_INSERT_HEAD(&syscalls, sc, entries);
- }
-}
-
static struct syscall *
find_syscall(struct procabi *abi, u_int number)
{
@@ -1036,6 +1025,11 @@
{
struct extra_syscall *es;
+#ifndef __LP64__
+ /* FIXME: should be based on sycall ABI not truss ABI */
+ quad_fixup(&sc->info);
+#endif
+
if (number < nitems(abi->syscalls)) {
assert(abi->syscalls[number] == NULL);
abi->syscalls[number] = sc;
@@ -1045,6 +1039,8 @@
es->number = number;
STAILQ_INSERT_TAIL(&abi->extra_syscalls, es, entries);
}
+
+ STAILQ_INSERT_HEAD(&seen_syscalls, sc, entries);
}
/*
@@ -1055,24 +1051,27 @@
get_syscall(struct threadinfo *t, u_int number, u_int nargs)
{
struct syscall *sc;
- const char *name;
- char *new_name;
+ const char *sysdecode_name;
+ char *name;
u_int i;
sc = find_syscall(t->proc->abi, number);
if (sc != NULL)
return (sc);
- name = sysdecode_syscallname(t->proc->abi->abi, number);
- if (name == NULL) {
- asprintf(&new_name, "#%d", number);
- name = new_name;
- } else
- new_name = NULL;
- STAILQ_FOREACH(sc, &syscalls, entries) {
- if (strcmp(name, sc->name) == 0) {
+ sysdecode_name = sysdecode_syscallname(t->proc->abi->abi, number);
+ if (sysdecode_name == NULL)
+ asprintf(&name, "#%d", number);
+ else
+ name = strdup(sysdecode_name);
+
+ sc = calloc(1, sizeof(*sc));
+ sc->display_name = name;
+
+ for (i = 0; i < nitems(decoded_syscalls); i++) {
+ if (strcmp(name, decoded_syscalls[i].name) == 0) {
+ sc->decode = decoded_syscalls[i];
add_syscall(t->proc->abi, number, sc);
- free(new_name);
return (sc);
}
}
@@ -1082,21 +1081,15 @@
fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
nargs);
#endif
-
- sc = calloc(1, sizeof(struct syscall));
- sc->name = name;
- if (new_name != NULL)
- sc->unknown = true;
- sc->ret_type = 1;
- sc->nargs = nargs;
+ sc->unknown = sysdecode_name == NULL;
+ sc->decode.ret_type = 1; /* Assume 1 return value. */
+ sc->decode.nargs = nargs;
for (i = 0; i < nargs; i++) {
- sc->args[i].offset = i;
+ sc->decode.args[i].offset = i;
/* Treat all unknown arguments as LongHex. */
- sc->args[i].type = LongHex;
+ sc->decode.args[i].type = LongHex;
}
- STAILQ_INSERT_HEAD(&syscalls, sc, entries);
add_syscall(t->proc->abi, number, sc);
-
return (sc);
}
@@ -1713,7 +1706,7 @@
* an array of all of the system call arguments.
*/
char *
-print_arg(struct syscall_args *sc, unsigned long *args, register_t *retval,
+print_arg(struct syscall_arg *sc, unsigned long *args, register_t *retval,
struct trussinfo *trussinfo)
{
FILE *fp;
@@ -2909,7 +2902,7 @@
t = trussinfo->curthread;
- name = t->cs.sc->name;
+ name = t->cs.sc->display_name;
nargs = t->cs.nargs;
s_args = t->cs.s_args;
@@ -2970,7 +2963,7 @@
strerror(error));
}
#ifndef __LP64__
- else if (sc->ret_type == 2) {
+ else if (sc->info.ret_type == 2) {
off_t off;
#if _BYTE_ORDER == _LITTLE_ENDIAN
@@ -2997,17 +2990,30 @@
fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
"syscall", "seconds", "calls", "errors");
ncall = nerror = 0;
- STAILQ_FOREACH(sc, &syscalls, entries)
+ STAILQ_FOREACH(sc, &seen_syscalls, entries) {
if (sc->ncalls) {
fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
- sc->name, (intmax_t)sc->time.tv_sec,
+ sc->display_name, (intmax_t)sc->time.tv_sec,
sc->time.tv_nsec, sc->ncalls, sc->nerror);
timespecadd(&total, &sc->time, &total);
ncall += sc->ncalls;
nerror += sc->nerror;
}
+ }
fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n",
"", "-------------", "-------", "-------");
fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
"", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror);
}
+
+void
+free_seen_syscalls(void)
+{
+ struct syscall *sc;
+ struct syscall *sc_temp;
+ STAILQ_FOREACH_SAFE (sc, &seen_syscalls, entries, sc_temp) {
+ STAILQ_REMOVE(&seen_syscalls, sc, syscall, entries);
+ free(sc->display_name);
+ free(sc);
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 12, 6:27 AM (21 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15757434
Default Alt Text
D27636.id80795.diff (9 KB)

Event Timeline