trussinfo
extern void x86_64_syscall_entry(struct trussinfo *, int);
extern int x86_64_syscall_exit(struct trussinfo *, int);
asprintf(&etype, "%s/%d/etype", procfs_path, trussinfo->pid);
struct trussinfo *trussinfo;
trussinfo = (struct trussinfo *)calloc(1, sizeof(struct trussinfo));
if (trussinfo == NULL)
trussinfo->outfile = stderr;
trussinfo->pid = atoi(optarg);
if (trussinfo->pid == getpid()) {
errx(2, "truss: attempt to self trace: %d\n", trussinfo->pid);
trussinfo->flags |= NOSIGS;
if ((trussinfo->pid == 0 && ac == 0) || (trussinfo->pid != 0 && ac != 0))
if ((trussinfo->outfile = fopen(fname, "w")) == NULL)
if (trussinfo->pid == 0) { /* Start a command ourselves */
trussinfo->pid = setup_and_wait(command);
trussinfo->pid, S_EXEC | S_SCE | S_SCX | S_CORE | S_EXIT |
((trussinfo->flags & NOSIGS) ? 0 : S_SIG));
funcs = set_etype(trussinfo);
funcs->enter_syscall(trussinfo, pfs.val);
funcs->exit_syscall(trussinfo, pfs.val);
fprintf(trussinfo->outfile, "SIGNAL %lu\n", pfs.val);
fprintf (trussinfo->outfile, "process exit, rval = %lu\n", pfs.val);
funcs = set_etype(trussinfo);
fprintf (trussinfo->outfile, "Process stopped because of: %d\n", i);
if (kill(trussinfo->pid, 0) == -1 && errno == ESRCH)
fflush(trussinfo->outfile);
void (*enter_syscall)(struct trussinfo *, int);
int (*exit_syscall)(struct trussinfo *, int);
set_etype(struct trussinfo *trussinfo) {
void print_syscall(struct trussinfo *, const char *, int, char **);
void print_syscall_ret(struct trussinfo *, const char *, int, char **, int, int);
print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s_args) {
len += fprintf(trussinfo->outfile, "%s(", name);
len += fprintf(trussinfo->outfile, "%s", s_args[i]);
len += fprintf(trussinfo->outfile, "<missing argument>");
len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ? "," : "");
len += fprintf(trussinfo->outfile, ")");
fprintf(trussinfo->outfile, "\t");
print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, char **s_args, int errorp, int retval) {
print_syscall(trussinfo, name, nargs, s_args);
fprintf(trussinfo->outfile, " ERR#%d '%s'\n", retval, strerror(retval));
fprintf(trussinfo->outfile, " = %d (0x%x)\n", retval, retval);
x86_64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
if (fd == -1 || trussinfo->pid != cpid) {
asprintf(&buf, "%s/%d/regs", procfs_path, trussinfo->pid);
fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
cpid = trussinfo->pid;
fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
fprintf(trussinfo->outfile, "\n");
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
x86_64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) {
if (fd == -1 || trussinfo->pid != cpid) {
asprintf(&buf, "%s/%d/regs", procfs_path, trussinfo->pid);
fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
cpid = trussinfo->pid;
fprintf(trussinfo->outfile, "\n");
print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval);