Merge ^/head r288831 through r288835.
This commit is contained in:
commit
926b24f309
@ -18,7 +18,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 20, 2015
|
||||
.Dd October 5, 2015
|
||||
.Dt GETADDRINFO 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -243,15 +243,14 @@ The list can be traversed by following the
|
||||
pointer in each
|
||||
.Li addrinfo
|
||||
structure until a null pointer is encountered.
|
||||
The three members
|
||||
Each returned
|
||||
.Li addrinfo
|
||||
structure contains three members that are suitable for a call to
|
||||
.Xr socket 2 :
|
||||
.Fa ai_family ,
|
||||
.Fa ai_socktype ,
|
||||
and
|
||||
.Fa ai_protocol
|
||||
in each returned
|
||||
.Li addrinfo
|
||||
structure are suitable for a call to
|
||||
.Xr socket 2 .
|
||||
.Fa ai_protocol .
|
||||
For each
|
||||
.Li addrinfo
|
||||
structure in the list, the
|
||||
|
@ -94,6 +94,7 @@ main(int ac, char **av)
|
||||
trussinfo->strsize = 32;
|
||||
trussinfo->curthread = NULL;
|
||||
LIST_INIT(&trussinfo->proclist);
|
||||
init_syscalls();
|
||||
while ((c = getopt(ac, av, "p:o:facedDs:S")) != -1) {
|
||||
switch (c) {
|
||||
case 'p': /* specified pid */
|
||||
|
@ -341,17 +341,9 @@ enter_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl)
|
||||
fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n",
|
||||
t->proc->abi->type, t->cs.number);
|
||||
|
||||
sc = get_syscall(t->cs.name);
|
||||
if (sc) {
|
||||
t->cs.nargs = sc->nargs;
|
||||
assert(sc->nargs <= nitems(t->cs.s_args));
|
||||
} else {
|
||||
#if DEBUG
|
||||
fprintf(stderr, "unknown syscall %s -- setting "
|
||||
"args to %d\n", t->cs.name, t->cs.nargs);
|
||||
#endif
|
||||
t->cs.nargs = narg;
|
||||
}
|
||||
sc = get_syscall(t->cs.name, narg);
|
||||
t->cs.nargs = sc->nargs;
|
||||
assert(sc->nargs <= nitems(t->cs.s_args));
|
||||
|
||||
t->cs.sc = sc;
|
||||
|
||||
@ -372,7 +364,7 @@ enter_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl)
|
||||
t->cs.args[sc->args[i].offset] : t->cs.args[i],
|
||||
i < (t->cs.nargs - 1) ? "," : "");
|
||||
#endif
|
||||
if (sc && !(sc->args[i].type & OUT)) {
|
||||
if (!(sc->args[i].type & OUT)) {
|
||||
t->cs.s_args[i] = print_arg(&sc->args[i],
|
||||
t->cs.args, 0, info);
|
||||
}
|
||||
@ -407,31 +399,26 @@ exit_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl)
|
||||
}
|
||||
|
||||
sc = t->cs.sc;
|
||||
if (sc == NULL) {
|
||||
for (i = 0; i < t->cs.nargs; i++)
|
||||
asprintf(&t->cs.s_args[i], "0x%lx", t->cs.args[i]);
|
||||
} else {
|
||||
/*
|
||||
* 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++) {
|
||||
char *temp;
|
||||
/*
|
||||
* 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++) {
|
||||
char *temp;
|
||||
|
||||
if (sc->args[i].type & OUT) {
|
||||
/*
|
||||
* If an error occurred, then don't bother
|
||||
* getting the data; it may not be valid.
|
||||
*/
|
||||
if (errorp) {
|
||||
asprintf(&temp, "0x%lx",
|
||||
t->cs.args[sc->args[i].offset]);
|
||||
} else {
|
||||
temp = print_arg(&sc->args[i],
|
||||
t->cs.args, retval, info);
|
||||
}
|
||||
t->cs.s_args[i] = temp;
|
||||
if (sc->args[i].type & OUT) {
|
||||
/*
|
||||
* If an error occurred, then don't bother
|
||||
* getting the data; it may not be valid.
|
||||
*/
|
||||
if (errorp) {
|
||||
asprintf(&temp, "0x%lx",
|
||||
t->cs.args[sc->args[i].offset]);
|
||||
} else {
|
||||
temp = print_arg(&sc->args[i],
|
||||
t->cs.args, retval, info);
|
||||
}
|
||||
t->cs.s_args[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@ struct syscall_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 */
|
||||
@ -65,7 +66,7 @@ struct syscall {
|
||||
int nerror; /* Number of calls that returned with error */
|
||||
};
|
||||
|
||||
struct syscall *get_syscall(const char*);
|
||||
struct syscall *get_syscall(const char *, int nargs);
|
||||
char *print_arg(struct syscall_args *, unsigned long*, long *, struct trussinfo *);
|
||||
|
||||
/*
|
||||
@ -108,6 +109,7 @@ struct linux_socketcall_args {
|
||||
char args_l_[PADL_(l_ulong)]; l_ulong args; char args_r_[PADR_(l_ulong)];
|
||||
};
|
||||
|
||||
void init_syscalls(void);
|
||||
void print_syscall(struct trussinfo *, const char *, int, char **);
|
||||
void print_syscall_ret(struct trussinfo *, const char *, int, char **, int,
|
||||
long *, struct syscall *);
|
||||
|
@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
|
||||
/*
|
||||
* This should probably be in its own file, sorted alphabetically.
|
||||
*/
|
||||
static struct syscall syscalls[] = {
|
||||
static struct syscall decoded_syscalls[] = {
|
||||
{ .name = "fcntl", .ret_type = 1, .nargs = 3,
|
||||
.args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } },
|
||||
{ .name = "rfork", .ret_type = 1, .nargs = 1,
|
||||
@ -253,6 +253,8 @@ static struct syscall syscalls[] = {
|
||||
.args = { { Int, 0 }, { Ptr, 1 } } },
|
||||
{ .name = "kldfirstmod", .ret_type = 1, .nargs = 1,
|
||||
.args = { { Int, 0 } } },
|
||||
{ .name = "modfind", .ret_type = 1, .nargs = 1,
|
||||
.args = { { Name | IN, 0 } } },
|
||||
{ .name = "nanosleep", .ret_type = 1, .nargs = 1,
|
||||
.args = { { Timespec, 0 } } },
|
||||
{ .name = "select", .ret_type = 1, .nargs = 5,
|
||||
@ -370,6 +372,7 @@ static struct syscall syscalls[] = {
|
||||
.args = { { Ptr, 0 } } },
|
||||
{ .name = 0 },
|
||||
};
|
||||
static STAILQ_HEAD(, syscall) syscalls;
|
||||
|
||||
/* Xlat idea taken from strace */
|
||||
struct xlat {
|
||||
@ -659,24 +662,49 @@ xlookup_bits(struct xlat *xlat, int val)
|
||||
return (str);
|
||||
}
|
||||
|
||||
void
|
||||
init_syscalls(void)
|
||||
{
|
||||
struct syscall *sc;
|
||||
|
||||
STAILQ_INIT(&syscalls);
|
||||
for (sc = decoded_syscalls; sc->name != NULL; sc++)
|
||||
STAILQ_INSERT_HEAD(&syscalls, sc, entries);
|
||||
}
|
||||
/*
|
||||
* If/when the list gets big, it might be desirable to do it
|
||||
* as a hash table or binary search.
|
||||
*/
|
||||
struct syscall *
|
||||
get_syscall(const char *name)
|
||||
get_syscall(const char *name, int nargs)
|
||||
{
|
||||
struct syscall *sc;
|
||||
int i;
|
||||
|
||||
sc = syscalls;
|
||||
if (name == NULL)
|
||||
return (NULL);
|
||||
while (sc->name) {
|
||||
STAILQ_FOREACH(sc, &syscalls, entries)
|
||||
if (strcmp(name, sc->name) == 0)
|
||||
return (sc);
|
||||
sc++;
|
||||
|
||||
/* It is unknown. Add it into the list. */
|
||||
#if DEBUG
|
||||
fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
|
||||
nargs);
|
||||
#endif
|
||||
|
||||
sc = calloc(1, sizeof(struct syscall));
|
||||
sc->name = strdup(name);
|
||||
sc->ret_type = 1;
|
||||
sc->nargs = nargs;
|
||||
for (i = 0; i < nargs; i++) {
|
||||
sc->args[i].offset = i;
|
||||
/* Treat all unknown arguments as LongHex. */
|
||||
sc->args[i].type = LongHex;
|
||||
}
|
||||
return (NULL);
|
||||
STAILQ_INSERT_HEAD(&syscalls, sc, entries);
|
||||
|
||||
return (sc);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1632,8 +1660,6 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs,
|
||||
struct timespec timediff;
|
||||
|
||||
if (trussinfo->flags & COUNTONLY) {
|
||||
if (!sc)
|
||||
return;
|
||||
clock_gettime(CLOCK_REALTIME, &trussinfo->curthread->after);
|
||||
timespecsubt(&trussinfo->curthread->after,
|
||||
&trussinfo->curthread->before, &timediff);
|
||||
@ -1650,7 +1676,7 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs,
|
||||
fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0],
|
||||
strerror(retval[0]));
|
||||
#ifndef __LP64__
|
||||
else if (sc != NULL && sc->ret_type == 2) {
|
||||
else if (sc->ret_type == 2) {
|
||||
off_t off;
|
||||
|
||||
#if _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
@ -1677,7 +1703,7 @@ print_summary(struct trussinfo *trussinfo)
|
||||
fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
|
||||
"syscall", "seconds", "calls", "errors");
|
||||
ncall = nerror = 0;
|
||||
for (sc = syscalls; sc->name != NULL; sc++)
|
||||
STAILQ_FOREACH(sc, &syscalls, entries)
|
||||
if (sc->ncalls) {
|
||||
fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
|
||||
sc->name, (intmax_t)sc->time.tv_sec,
|
||||
|
Loading…
Reference in New Issue
Block a user