MFp4: Bugfixes for truss(1):

- Fix logic handling execve().  We will not be able to
   obtain information otherwise.
 - truss coredump [1].
 - truss does not work against itself [2].

PR:		bin/58970 [1], bin/45193 [2]
Submitted by:	Howard Su
Approved by:	re (kensmith)
This commit is contained in:
Xin LI 2007-06-26 22:42:37 +00:00
parent 266d3a7a09
commit ef29ac7f76
10 changed files with 75 additions and 91 deletions

View File

@ -229,13 +229,6 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
@ -256,8 +249,6 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -279,6 +270,9 @@ amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
@ -319,6 +313,11 @@ amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
}
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
/*
* It would probably be a good idea to merge the error handling,
* but that complicates things considerably.

View File

@ -222,13 +222,6 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
@ -249,8 +242,6 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) {
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -272,6 +263,8 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
@ -326,6 +319,11 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
retval = 0;
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
/*
* It would probably be a good idea to merge the error handling,
* but that complicates things considerably.

View File

@ -202,15 +202,8 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
(!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
/* XXX
* This could be done in a more general
@ -228,9 +221,6 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fsc.s_args[2] = NULL;
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -260,6 +250,9 @@ i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
{
@ -309,6 +302,12 @@ i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
if (retval == bsd_to_linux_errno[i])
break;
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
errorp ? i : retval);
clear_fsc();

View File

@ -222,13 +222,6 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
@ -249,8 +242,6 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) {
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -272,6 +263,8 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
@ -326,6 +319,11 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
retval = 0;
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
/*
* It would probably be a good idea to merge the error handling,
* but that complicates things considerably.

View File

@ -202,15 +202,8 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
(!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
/* XXX
* This could be done in a more general
@ -228,9 +221,6 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fsc.s_args[2] = NULL;
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -260,6 +250,9 @@ i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
{
@ -309,6 +302,12 @@ i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
if (retval == bsd_to_linux_errno[i])
break;
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
errorp ? i : retval);
clear_fsc();

View File

@ -204,13 +204,6 @@ ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
@ -230,9 +223,6 @@ ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fsc.s_args[2] = NULL;
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -254,6 +244,8 @@ ia64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
@ -293,6 +285,10 @@ ia64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
}
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
/*
* It would probably be a good idea to merge the error handling,
* but that complicates things considerably.

View File

@ -162,12 +162,11 @@ main(int ac, char **av)
int i;
char **command;
struct ex_types *funcs;
int sigexit, initial_open;
int initial_open;
char *fname;
struct trussinfo *trussinfo;
char *signame;
sigexit = 0;
fname = NULL;
initial_open = 1;
@ -186,6 +185,11 @@ main(int ac, char **av)
switch (c) {
case 'p': /* specified pid */
trussinfo->pid = atoi(optarg);
/* make sure i don't trace me */
if(trussinfo->pid == getpid()) {
fprintf(stderr, "attempt to grab self.\n");
exit(2);
}
break;
case 'f': /* Follow fork()'s */
trussinfo->flags |= FOLLOWFORKS;
@ -352,15 +356,6 @@ main(int ac, char **av)
}
} while (trussinfo->pr_why != S_EXIT);
fflush(trussinfo->outfile);
if (sigexit) {
struct rlimit rlp;
rlp.rlim_cur = 0;
rlp.rlim_max = 0;
setrlimit(RLIMIT_CORE, &rlp);
(void) signal(sigexit, SIG_DFL);
(void) kill(getpid(), sigexit);
}
return (0);
}

View File

@ -228,13 +228,6 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
/* XXX
@ -253,9 +246,6 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fsc.s_args[2] = NULL;
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -277,6 +267,9 @@ powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
@ -324,6 +317,12 @@ powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
}
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
/*
* It would probably be a good idea to merge the error handling,
* but that complicates things considerably.

View File

@ -197,7 +197,7 @@ waitevent(struct trussinfo *info)
info->pr_data = WEXITSTATUS(waitval);
return;
}
if (WIFSTOPPED(waitval) || (WIFSIGNALED(waitval))) {
if (WIFSTOPPED(waitval)) {
struct ptrace_lwpinfo lwpinfo;
ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo, sizeof(lwpinfo));
find_thread(info, lwpinfo.pl_lwpid);
@ -213,4 +213,9 @@ waitevent(struct trussinfo *info)
break;
}
}
if (WIFSIGNALED(waitval)) {
info->pr_why = S_EXIT;
info->pr_why = 0;
return;
}
}

View File

@ -247,13 +247,6 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "\n");
#endif
/*
* Some system calls should be printed out before they are done --
* execve() and exit(), for example, never return. Possibly change
* this to work for any system call that doesn't have an OUT
* parameter?
*/
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
@ -273,9 +266,6 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fsc.s_args[2] = NULL;
}
}
print_syscall(trussinfo, fsc.name, fsc.nargs, fsc.s_args);
fprintf(trussinfo->outfile, "\n");
}
return;
@ -296,6 +286,8 @@ sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) {
int errorp;
struct syscall *sc;
if (fsc.name == NULL)
return (-1);
cpid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
@ -335,6 +327,10 @@ sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) {
}
}
if (fsc.name != NULL &&
(!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
trussinfo->curthread->in_syscall = 1;
}
/*
* It would probably be a good idea to merge the error handling,
* but that complicates things considerably.