Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115836210
D27636.id80775.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D27636.id80775.diff
View Options
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 */
@@ -201,7 +200,7 @@
eventloop(trussinfo);
if (trussinfo->flags & COUNTONLY)
- print_summary(trussinfo);
+ print_summary(trussinfo, /*free_sc=*/true);
fflush(trussinfo->outfile);
Index: usr.bin/truss/setup.c
===================================================================
--- usr.bin/truss/setup.c
+++ usr.bin/truss/setup.c
@@ -459,12 +459,12 @@
}
sc = get_syscall(t, t->cs.number, narg);
- if (sc->unknown)
+ if (sc->info.unknown)
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->info.nargs;
+ assert(sc->info.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->kernel_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->info.args[i].type & OUT)) {
+ t->cs.s_args[i] = print_arg(&sc->info.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->info.nargs; i++) {
char *temp;
- if (sc->args[i].type & OUT) {
+ if (sc->info.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->info.args[i].offset]);
} else {
- temp = print_arg(&sc->args[i],
+ temp = print_arg(&sc->info.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,26 +216,31 @@
_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_cconv {
+ 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 */
+ /* Hopefully, no syscalls with > 10 args */
+ struct syscall_arg args[10];
+ bool unknown; /* Unknown system call */
+};
+
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 *kernel_name;
+ struct syscall_cconv info;
struct timespec time; /* Time spent for this call */
int ncalls; /* Number of calls */
int nerror; /* Number of calls that returned with error */
- bool unknown; /* Unknown system call */
};
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 +283,6 @@
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 print_summary(struct trussinfo *trussinfo, bool free_sc);
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_cconv 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_cconv *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)
{
@@ -1031,11 +1020,16 @@
return (NULL);
}
-static void
+static struct syscall *
add_syscall(struct procabi *abi, u_int number, struct syscall *sc)
{
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,9 @@
es->number = number;
STAILQ_INSERT_TAIL(&abi->extra_syscalls, es, entries);
}
+
+ STAILQ_INSERT_HEAD(&seen_syscalls, sc, entries);
+ return (sc);
}
/*
@@ -1058,6 +1055,7 @@
const char *name;
char *new_name;
u_int i;
+ bool unknown_name = false;
sc = find_syscall(t->proc->abi, number);
if (sc != NULL)
@@ -1066,14 +1064,17 @@
name = sysdecode_syscallname(t->proc->abi->abi, number);
if (name == NULL) {
asprintf(&new_name, "#%d", number);
- name = new_name;
+ unknown_name = true;
} else
- new_name = NULL;
- STAILQ_FOREACH(sc, &syscalls, entries) {
- if (strcmp(name, sc->name) == 0) {
- add_syscall(t->proc->abi, number, sc);
- free(new_name);
- return (sc);
+ new_name = strdup(name);
+
+ sc = calloc(1, sizeof(*sc));
+ sc->kernel_name = new_name;
+
+ for (i = 0; i < nitems(decoded_syscalls); i++) {
+ if (strcmp(new_name, decoded_syscalls[i].name) == 0) {
+ sc->info = decoded_syscalls[i];
+ return (add_syscall(t->proc->abi, number, sc));
}
}
@@ -1082,22 +1083,20 @@
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;
+ /*
+ * Note: info.name is either a constant or points to sc->kernel_name
+ * which be free'd toger with sc on exit.
+ */
+ sc->info.name = new_name;
+ sc->info.unknown = unknown_name;
+ sc->info.ret_type = 1; /* Assume 1 return value. */
+ sc->info.nargs = nargs;
for (i = 0; i < nargs; i++) {
- sc->args[i].offset = i;
+ sc->info.args[i].offset = i;
/* Treat all unknown arguments as LongHex. */
- sc->args[i].type = LongHex;
+ sc->info.args[i].type = LongHex;
}
- STAILQ_INSERT_HEAD(&syscalls, sc, entries);
- add_syscall(t->proc->abi, number, sc);
-
- return (sc);
+ return (add_syscall(t->proc->abi, number, sc));
}
/*
@@ -1713,7 +1712,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 +2908,7 @@
t = trussinfo->curthread;
- name = t->cs.sc->name;
+ name = t->cs.sc->kernel_name;
nargs = t->cs.nargs;
s_args = t->cs.s_args;
@@ -2988,24 +2987,31 @@
}
void
-print_summary(struct trussinfo *trussinfo)
+print_summary(struct trussinfo *trussinfo, bool free_sc)
{
struct timespec total = {0, 0};
struct syscall *sc;
+ struct syscall *sc_temp;
int ncall, nerror;
fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
"syscall", "seconds", "calls", "errors");
ncall = nerror = 0;
- STAILQ_FOREACH(sc, &syscalls, entries)
+ STAILQ_FOREACH_SAFE(sc, &seen_syscalls, entries, sc_temp) {
if (sc->ncalls) {
fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
- sc->name, (intmax_t)sc->time.tv_sec,
+ sc->kernel_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;
}
+ if (free_sc) {
+ STAILQ_REMOVE(&seen_syscalls, sc, syscall, entries);
+ free(sc->kernel_name);
+ free(sc);
+ }
+ }
fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n",
"", "-------------", "-------", "-------");
fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 30, 8:55 AM (13 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17854470
Default Alt Text
D27636.id80775.diff (10 KB)
Attached To
Mode
D27636: truss: split counting of syscalls and syscall calling convention
Attached
Detach File
Event Timeline
Log In to Comment