summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defs.h8
-rw-r--r--process.c4
-rw-r--r--strace.c83
-rw-r--r--syscall.c11
-rw-r--r--test/threaded_execve.c3
5 files changed, 50 insertions, 59 deletions
diff --git a/defs.h b/defs.h
index 59a8a09..108b532 100644
--- a/defs.h
+++ b/defs.h
@@ -584,7 +584,12 @@ extern unsigned int ptrace_setoptions;
extern int dtime, xflag, qflag;
extern cflag_t cflag;
extern int max_strlen;
-extern struct tcb *tcp_last;
+/*
+ * Which tcb has incomplete line being printed right now?
+ * NULL if last line has been completed ('\n'-terminated).
+ * printleader(tcp) sets it. Clearing is open-coded.
+ */
+extern struct tcb *printing_tcp;
enum bitness_t { BITNESS_CURRENT = 0, BITNESS_32 };
@@ -658,7 +663,6 @@ extern const char *signame(int);
extern void print_sigset(struct tcb *, long, int);
extern void printsignal(int);
extern void printleader(struct tcb *);
-extern void printtrailer(void);
extern void tabto(void);
extern void call_summary(FILE *);
extern void tprint_iov(struct tcb *, unsigned long, unsigned long, int decode_iov);
diff --git a/process.c b/process.c
index 33033a4..d93a190 100644
--- a/process.c
+++ b/process.c
@@ -430,8 +430,8 @@ sys_exit(struct tcb *tcp)
/* special case: we stop tracing this process, finish line now */
tprintf("%ld) ", tcp->u_arg[0]);
tabto();
- tprints("= ?");
- printtrailer();
+ tprints("= ?\n");
+ printing_tcp = NULL;
return 0;
}
diff --git a/strace.c b/strace.c
index 7cbcb0c..84b35c8 100644
--- a/strace.c
+++ b/strace.c
@@ -125,6 +125,7 @@ static int acolumn = DEFAULT_ACOLUMN;
static char *acolumn_spaces;
static char *outfname = NULL;
static FILE *outf;
+struct tcb *printing_tcp = NULL;
static int curcol;
static struct tcb **tcbtab;
static unsigned int nprocs, tcbtabsize;
@@ -1844,10 +1845,10 @@ cleanup(void)
if (debug)
fprintf(stderr,
"cleanup: looking at pid %u\n", tcp->pid);
- if (tcp_last &&
- (!outfname || followfork < 2 || tcp_last == tcp)) {
- tprints(" <unfinished ...>");
- printtrailer();
+ if (printing_tcp &&
+ (!outfname || followfork < 2 || printing_tcp == tcp)) {
+ tprints(" <unfinished ...>\n");
+ printing_tcp = NULL;
}
if (tcp->flags & TCB_ATTACHED)
detach(tcp);
@@ -2292,15 +2293,16 @@ trace(void)
if (cflag != CFLAG_ONLY_STATS
&& (qual_flags[what] & QUAL_SIGNAL)) {
printleader(tcp);
- tprintf("--- %s (%s) ---",
+ tprintf("--- %s (%s) ---\n",
signame(what), strsignal(what));
- printtrailer();
+ printing_tcp = NULL;
#ifdef PR_INFO
if (tcp->status.PR_INFO.si_signo == what) {
printleader(tcp);
tprints(" siginfo=");
printsiginfo(&tcp->status.PR_INFO, 1);
- printtrailer();
+ tprints("\n");
+ printing_tcp = NULL;
}
#endif
}
@@ -2309,8 +2311,8 @@ trace(void)
if (cflag != CFLAGS_ONLY_STATS
&& (qual_flags[what] & QUAL_FAULT)) {
printleader(tcp);
- tprintf("=== FAULT %d ===", what);
- printtrailer();
+ tprintf("=== FAULT %d ===\n", what);
+ printing_tcp = NULL;
}
break;
#ifdef FREEBSD
@@ -2483,15 +2485,11 @@ trace()
outf = tcp->outf;
curcol = tcp->curcol;
if (!cflag) {
- if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) == TCB_INSYSCALL) {
- /* We printed "syscall(some params"
- * but didn't print "\n" yet.
- */
+ if (printing_tcp)
tprints(" <unfinished ...>\n");
- }
printleader(tcp);
- tprintf("+++ superseded by execve in pid %lu +++", old_pid);
- printtrailer();
+ tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
+ printing_tcp = NULL;
fflush(outf);
}
if (execve_thread) {
@@ -2555,14 +2553,14 @@ trace()
&& (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
printleader(tcp);
#ifdef WCOREDUMP
- tprintf("+++ killed by %s %s+++",
+ tprintf("+++ killed by %s %s+++\n",
signame(WTERMSIG(status)),
WCOREDUMP(status) ? "(core dumped) " : "");
#else
- tprintf("+++ killed by %s +++",
+ tprintf("+++ killed by %s +++\n",
signame(WTERMSIG(status)));
#endif
- printtrailer();
+ printing_tcp = NULL;
}
fflush(tcp->outf);
droptcb(tcp);
@@ -2571,16 +2569,14 @@ trace()
if (WIFEXITED(status)) {
if (pid == strace_child)
exit_code = WEXITSTATUS(status);
- if (tcp == tcp_last) {
- if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) == TCB_INSYSCALL)
- tprintf(" <unfinished ... exit status %d>\n",
- WEXITSTATUS(status));
- tcp_last = NULL;
+ if (tcp == printing_tcp) {
+ tprints(" <unfinished ...>\n");
+ printing_tcp = NULL;
}
if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
printleader(tcp);
- tprintf("+++ exited with %d +++", WEXITSTATUS(status));
- printtrailer();
+ tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
+ printing_tcp = NULL;
}
fflush(tcp->outf);
droptcb(tcp);
@@ -2666,15 +2662,15 @@ trace()
if (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) == 0) {
tprints("--- ");
printsiginfo(&si, verbose(tcp));
- tprintf(" (%s)" PC_FORMAT_STR " ---",
+ tprintf(" (%s)" PC_FORMAT_STR " ---\n",
strsignal(sig)
PC_FORMAT_ARG);
} else
- tprintf("--- %s by %s" PC_FORMAT_STR " ---",
+ tprintf("--- %s by %s" PC_FORMAT_STR " ---\n",
strsignal(sig),
signame(sig)
PC_FORMAT_ARG);
- printtrailer();
+ printing_tcp = NULL;
fflush(tcp->outf);
}
goto restart_tracee;
@@ -2695,13 +2691,13 @@ trace()
* all processes in thread group.
*/
if (tcp->flags & TCB_ATTACHED) {
- if (tcp_last) {
+ if (printing_tcp) {
/* Do we have dangling line "syscall(param, param"?
* Finish the line then.
*/
- tcp_last->flags |= TCB_REPRINT;
- tprints(" <unfinished ...>");
- printtrailer();
+ printing_tcp->flags |= TCB_REPRINT;
+ tprints(" <unfinished ...>\n");
+ printing_tcp = NULL;
fflush(tcp->outf);
}
/* We assume that ptrace error was caused by process death.
@@ -2768,19 +2764,21 @@ tprints(const char *str)
void
printleader(struct tcb *tcp)
{
- if (tcp_last) {
- if (tcp_last->ptrace_errno) {
- if (tcp_last->flags & TCB_INSYSCALL) {
+ if (printing_tcp) {
+ if (printing_tcp->ptrace_errno) {
+ if (printing_tcp->flags & TCB_INSYSCALL) {
tprints(" <unavailable>) ");
tabto();
}
tprints("= ? <unavailable>\n");
- tcp_last->ptrace_errno = 0;
- } else if (!outfname || followfork < 2 || tcp_last == tcp) {
- tcp_last->flags |= TCB_REPRINT;
+ printing_tcp->ptrace_errno = 0;
+ } else if (!outfname || followfork < 2 || printing_tcp == tcp) {
+ printing_tcp->flags |= TCB_REPRINT;
tprints(" <unfinished ...>\n");
}
}
+
+ printing_tcp = tcp;
curcol = 0;
if ((followfork == 1 || pflag_seen > 1) && outfname)
tprintf("%-5d ", tcp->pid);
@@ -2824,13 +2822,6 @@ tabto(void)
tprints(acolumn_spaces + curcol);
}
-void
-printtrailer(void)
-{
- tprints("\n");
- tcp_last = NULL;
-}
-
#ifdef HAVE_MP_PROCFS
int
diff --git a/syscall.c b/syscall.c
index 9c04cf9..88c9766 100644
--- a/syscall.c
+++ b/syscall.c
@@ -731,8 +731,6 @@ is_restart_error(struct tcb *tcp)
return 0;
}
-struct tcb *tcp_last = NULL;
-
#ifdef LINUX
# if defined(I386)
struct pt_regs i386_regs;
@@ -1724,7 +1722,6 @@ trace_syscall_entering(struct tcb *tcp)
if (res != 1) {
printleader(tcp);
tcp->flags &= ~TCB_REPRINT;
- tcp_last = tcp;
if (scno_good != 1)
tprintf("????" /* anti-trigraph gap */ "(");
else if (!SCNO_IN_RANGE(tcp->scno))
@@ -1844,7 +1841,6 @@ trace_syscall_entering(struct tcb *tcp)
printleader(tcp);
tcp->flags &= ~TCB_REPRINT;
- tcp_last = tcp;
if (!SCNO_IN_RANGE(tcp->scno))
tprintf("syscall_%lu(", tcp->scno);
else
@@ -2382,8 +2378,8 @@ trace_syscall_exiting(struct tcb *tcp)
if (res != 1) {
tprints(") ");
tabto();
- tprints("= ? <unavailable>");
- printtrailer();
+ tprints("= ? <unavailable>\n");
+ printing_tcp = NULL;
tcp->flags &= ~TCB_INSYSCALL;
return res;
}
@@ -2530,7 +2526,8 @@ trace_syscall_exiting(struct tcb *tcp)
tprintf(" <%ld.%06ld>",
(long) tv.tv_sec, (long) tv.tv_usec);
}
- printtrailer();
+ tprints("\n");
+ printing_tcp = NULL;
dumpio(tcp);
if (fflush(tcp->outf) == EOF)
diff --git a/test/threaded_execve.c b/test/threaded_execve.c
index 51a4360..9cf3dae 100644
--- a/test/threaded_execve.c
+++ b/test/threaded_execve.c
@@ -11,7 +11,6 @@
* # Should not be confused by traced execve-ing thread
* # replacing traced leader:
* [LEADER_EXIT=1] strace -oLOG -f ./threaded_execve
- * ^^^ so far slightly bad output with LEADER_EXIT=1
*
* # Same, but different output mode. Output after execve
* # should go into leader's LOG.<pid> file, not into execve'ed
@@ -24,7 +23,7 @@
* ^^^^^^^^^^^^^^^^^^^^^
* In Linux 3.2, non-traced execve-ing thread does not
* become traced after execve, even though it has pid == leader's pid
- * after execve.
+ * after execve. And yet, strace's waitpid doesn't return ECHILD.
*
* # Run for NUM seconds, not just one second.
* # Watch top to check for memory leaks in strace: