summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Machek <pavel@ucw.cz>2000-02-01 17:58:41 +0000
committerPavel Machek <pavel@ucw.cz>2000-02-01 17:58:41 +0000
commit4dc3b141be2e109170fb515b98723545474ac701 (patch)
tree8ff60d158a909ac40f91a9da16e01d752358c5aa
parentd8ae7e332a15c12a488efa40136fa07f7dafa34b (diff)
downloadstrace-4dc3b141be2e109170fb515b98723545474ac701.tar.gz
strace-4dc3b141be2e109170fb515b98723545474ac701.tar.bz2
strace-4dc3b141be2e109170fb515b98723545474ac701.tar.xz
Split trace_syscall into few functions to make code readable.
-rw-r--r--ChangeLog6
-rw-r--r--syscall.c377
2 files changed, 217 insertions, 166 deletions
diff --git a/ChangeLog b/ChangeLog
index dddaf64..817f91d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2000-01-02 Pavel Machek <pavel@ucw.cz>
+
+ * probe if sys/poll.h exists in configure + minor cleanups
+
+ * syscall.c: split trace_syscall into few pieces to make code readable
+
2000-01-21 Wichert Akkerman <wakkerma@debian.org>
* Release version 4.2 to get the current updates out and so
diff --git a/syscall.c b/syscall.c
index 008981b..6407224 100644
--- a/syscall.c
+++ b/syscall.c
@@ -567,42 +567,12 @@ struct tcb *tcp;
}
int
-trace_syscall(tcp)
+get_scno(tcp)
struct tcb *tcp;
{
- int sys_res;
- struct timeval tv;
long scno = 0;
-#ifdef LINUX
-#if defined (I386)
- long eax;
-#elif defined (POWERPC)
- long result,flags;
-#elif defined (M68K)
- int d0;
-#elif defined (ARM)
- int r0;
-#elif defined (ALPHA)
- long r0;
- long a3;
-#elif defined(MIPS)
- long r2,a3;
-#elif defined (SPARC)
- struct regs regs;
- unsigned long trap;
-#elif defined(S390)
- long gpr2;
- long pc;
-#endif
-#endif /* LINUX */
-
-#ifndef SVR4
int pid = tcp->pid;
-#endif /* !SVR4 */
- /* Measure the exit time as early as possible to avoid errors. */
- if (dtime && (tcp->flags & TCB_INSYSCALL))
- gettimeofday(&tv, NULL);
#ifdef LINUX
#if defined(S390)
if (upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
@@ -754,6 +724,39 @@ struct tcb *tcp;
#else /* !HAVE_PR_SYSCALL */
scno = tcp->status.PR_WHAT;
#endif /* !HAVE_PR_SYSCALL */
+#endif
+ tcp->scno = scno;
+ return 1;
+}
+
+#ifdef LINUX
+#if defined (I386)
+ static long eax;
+#elif defined (POWERPC)
+ static long result,flags;
+#elif defined (M68K)
+ static int d0;
+#elif defined (ARM)
+ static int r0;
+#elif defined (ALPHA)
+ static long r0;
+ static long a3;
+#elif defined (SPARC)
+ static struct pt_regs regs;
+ static unsigned long trap;
+#elif defined(S390)
+ static long gpr2;
+ static long pc;
+#endif
+#endif /* LINUX */
+
+int
+syscall_fixup(tcp)
+struct tcb *tcp;
+{
+ int pid = tcp->pid;
+
+#ifdef SVR4
if (!(tcp->flags & TCB_INSYSCALL)) {
if (tcp->status.PR_WHY != PR_SYSENTRY) {
if (
@@ -837,10 +840,14 @@ struct tcb *tcp;
#else
#endif
#endif /* LINUX */
+ return 1;
+}
- if (tcp->flags & TCB_INSYSCALL) {
- long u_error;
-
+int
+get_error(tcp)
+struct tcb *tcp;
+{
+ int u_error = 0;
#ifdef LINUX
#ifdef I386
if (eax < 0 && -eax < nerrnos) {
@@ -962,139 +969,14 @@ struct tcb *tcp;
}
#endif /* MIPS */
#endif /* SVR4 */
- tcp->u_error = u_error;
-
- internal_syscall(tcp);
- if (!(qual_flags[tcp->scno] & QUAL_TRACE)) {
- tcp->flags &= ~TCB_INSYSCALL;
- return 0;
- }
-
- if (tcp->flags & TCB_REPRINT) {
- printleader(tcp);
- tprintf("<... ");
- if (tcp->scno >= nsyscalls)
- tprintf("syscall_%lu", tcp->scno);
- else
- tprintf("%s", sysent[tcp->scno].sys_name);
- tprintf(" resumed> ");
- }
-
- if (cflag) {
- call_count[tcp->scno]++;
- if (u_error)
- error_count[tcp->scno]++;
- tv_sub(&tv, &tv, &tcp->etime);
-#ifdef LINUX
- if (tv_cmp(&tv, &tcp->dtime) > 0) {
- static struct timeval one_tick =
- { 0, 1000000 / HZ };
-
- if (tv_nz(&tcp->dtime))
- tv = tcp->dtime;
- else if (tv_cmp(&tv, &one_tick) > 0) {
- if (tv_cmp(&shortest, &one_tick) < 0)
- tv = shortest;
- else
- tv = one_tick;
- }
- }
-#endif /* LINUX */
- if (tv_cmp(&tv, &shortest) < 0)
- shortest = tv;
- tv_add(&tv_count[tcp->scno],
- &tv_count[tcp->scno], &tv);
- tcp->flags &= ~TCB_INSYSCALL;
- return 0;
- }
-
- if (tcp->scno >= nsyscalls
- || (qual_flags[tcp->scno] & QUAL_RAW))
- sys_res = printargs(tcp);
- else
- sys_res = (*sysent[tcp->scno].sys_func)(tcp);
- u_error = tcp->u_error;
- tprintf(") ");
- tabto(acolumn);
- if (qual_flags[tcp->scno] & QUAL_RAW) {
- if (u_error)
- tprintf("= -1 (errno %ld)", u_error);
- else
- tprintf("= %#lx", tcp->u_rval);
- }
- else if (!(sys_res & RVAL_NONE) && u_error) {
-#ifdef LINUX
- switch (u_error) {
- case ERESTARTSYS:
- tprintf("= ? ERESTARTSYS (To be restarted)");
- break;
- case ERESTARTNOINTR:
- tprintf("= ? ERESTARTNOINTR (To be restarted)");
- break;
- case ERESTARTNOHAND:
- tprintf("= ? ERESTARTNOHAND (To be restarted)");
- break;
- default:
-#endif /* LINUX */
- tprintf("= -1 ");
- if (u_error < nerrnos && u_error < sys_nerr)
- tprintf("%s (%s)", errnoent[u_error],
- sys_errlist[u_error]);
- else if (u_error < nerrnos)
- tprintf("%s (errno %ld)",
- errnoent[u_error], u_error);
- else if (u_error < sys_nerr)
- tprintf("ERRNO_%ld (%s)", u_error,
- sys_errlist[u_error]);
- else
- tprintf("E??? (errno %ld)", u_error);
-#ifdef LINUX
- break;
- }
-#endif /* LINUX */
- }
- else {
- if (sys_res & RVAL_NONE)
- tprintf("= ?");
- else {
- switch (sys_res & RVAL_MASK) {
- case RVAL_HEX:
- tprintf("= %#lx", tcp->u_rval);
- break;
- case RVAL_OCTAL:
- tprintf("= %#lo", tcp->u_rval);
- break;
- case RVAL_UDECIMAL:
- tprintf("= %lu", tcp->u_rval);
- break;
- case RVAL_DECIMAL:
- tprintf("= %ld", tcp->u_rval);
- break;
- default:
- fprintf(stderr,
- "invalid rval format\n");
- break;
- }
- }
- if ((sys_res & RVAL_STR) && tcp->auxstr)
- tprintf(" (%s)", tcp->auxstr);
- }
- if (dtime) {
- tv_sub(&tv, &tv, &tcp->etime);
- tprintf(" <%ld.%06ld>",
- (long) tv.tv_sec, (long) tv.tv_usec);
- }
- printtrailer(tcp);
-
- dumpio(tcp);
- if (fflush(tcp->outf) == EOF)
- return -1;
- tcp->flags &= ~TCB_INSYSCALL;
- return 0;
- }
+ tcp->u_error = u_error;
+ return 1;
+}
- /* Entering system call */
- tcp->scno = scno;
+int syscall_enter(tcp)
+struct tcb *tcp;
+{
+ int pid = tcp->pid;
#ifdef LINUX
#if defined(S390)
{
@@ -1227,6 +1109,169 @@ struct tcb *tcp;
#endif /* !HAVE_PR_SYSCALL */
#endif /* !MIPS */
#endif /* SVR4 */
+ return 1;
+}
+
+int
+trace_syscall(tcp)
+struct tcb *tcp;
+{
+ int sys_res;
+ struct timeval tv;
+ int res;
+
+ /* Measure the exit time as early as possible to avoid errors. */
+ if (dtime && (tcp->flags & TCB_INSYSCALL))
+ gettimeofday(&tv, NULL);
+
+ res = get_scno(tcp);
+ if (res != 1)
+ return res;
+
+ res = syscall_fixup(tcp);
+ if (res != 1)
+ return res;
+
+ if (tcp->flags & TCB_INSYSCALL) {
+ long u_error;
+ res = get_error(tcp);
+ if (res != 1)
+ return res;
+ u_error = tcp->u_error;
+
+
+ internal_syscall(tcp);
+ if (!(qual_flags[tcp->scno] & QUAL_TRACE)) {
+ tcp->flags &= ~TCB_INSYSCALL;
+ return 0;
+ }
+
+ if (tcp->flags & TCB_REPRINT) {
+ printleader(tcp);
+ tprintf("<... ");
+ if (tcp->scno >= nsyscalls)
+ tprintf("syscall_%lu", tcp->scno);
+ else
+ tprintf("%s", sysent[tcp->scno].sys_name);
+ tprintf(" resumed> ");
+ }
+
+ if (cflag) {
+ call_count[tcp->scno]++;
+ if (tcp->u_error)
+ error_count[tcp->scno]++;
+ tv_sub(&tv, &tv, &tcp->etime);
+#ifdef LINUX
+ if (tv_cmp(&tv, &tcp->dtime) > 0) {
+ static struct timeval one_tick =
+ { 0, 1000000 / HZ };
+
+ if (tv_nz(&tcp->dtime))
+ tv = tcp->dtime;
+ else if (tv_cmp(&tv, &one_tick) > 0) {
+ if (tv_cmp(&shortest, &one_tick) < 0)
+ tv = shortest;
+ else
+ tv = one_tick;
+ }
+ }
+#endif /* LINUX */
+ if (tv_cmp(&tv, &shortest) < 0)
+ shortest = tv;
+ tv_add(&tv_count[tcp->scno],
+ &tv_count[tcp->scno], &tv);
+ tcp->flags &= ~TCB_INSYSCALL;
+ return 0;
+ }
+
+ if (tcp->scno >= nsyscalls
+ || (qual_flags[tcp->scno] & QUAL_RAW))
+ sys_res = printargs(tcp);
+ else
+ sys_res = (*sysent[tcp->scno].sys_func)(tcp);
+ u_error = tcp->u_error;
+ tprintf(") ");
+ tabto(acolumn);
+ if (qual_flags[tcp->scno] & QUAL_RAW) {
+ if (u_error)
+ tprintf("= -1 (errno %ld)", u_error);
+ else
+ tprintf("= %#lx", tcp->u_rval);
+ }
+ else if (!(sys_res & RVAL_NONE) && u_error) {
+ switch (u_error) {
+#ifdef LINUX
+ case ERESTARTSYS:
+ tprintf("= ? ERESTARTSYS (To be restarted)");
+ break;
+ case ERESTARTNOINTR:
+ tprintf("= ? ERESTARTNOINTR (To be restarted)");
+ break;
+ case ERESTARTNOHAND:
+ tprintf("= ? ERESTARTNOHAND (To be restarted)");
+ break;
+#endif /* LINUX */
+ default:
+ tprintf("= -1 ");
+ if (u_error < nerrnos && u_error < sys_nerr)
+ tprintf("%s (%s)", errnoent[u_error],
+ sys_errlist[u_error]);
+ else if (u_error < nerrnos)
+ tprintf("%s (errno %ld)",
+ errnoent[u_error], u_error);
+ else if (u_error < sys_nerr)
+ tprintf("ERRNO_%ld (%s)", u_error,
+ sys_errlist[u_error]);
+ else
+ tprintf("E??? (errno %ld)", u_error);
+ break;
+ }
+ }
+ else {
+ if (sys_res & RVAL_NONE)
+ tprintf("= ?");
+ else {
+ switch (sys_res & RVAL_MASK) {
+ case RVAL_HEX:
+ tprintf("= %#lx", tcp->u_rval);
+ break;
+ case RVAL_OCTAL:
+ tprintf("= %#lo", tcp->u_rval);
+ break;
+ case RVAL_UDECIMAL:
+ tprintf("= %lu", tcp->u_rval);
+ break;
+ case RVAL_DECIMAL:
+ tprintf("= %ld", tcp->u_rval);
+ break;
+ default:
+ fprintf(stderr,
+ "invalid rval format\n");
+ break;
+ }
+ }
+ if ((sys_res & RVAL_STR) && tcp->auxstr)
+ tprintf(" (%s)", tcp->auxstr);
+ }
+ if (dtime) {
+ tv_sub(&tv, &tv, &tcp->etime);
+ tprintf(" <%ld.%06ld>",
+ (long) tv.tv_sec, (long) tv.tv_usec);
+ }
+ printtrailer(tcp);
+
+ dumpio(tcp);
+ if (fflush(tcp->outf) == EOF)
+ return -1;
+ tcp->flags &= ~TCB_INSYSCALL;
+ return 0;
+ }
+
+ /* Entering system call */
+ res = syscall_enter(tcp);
+ if (res != 1)
+ return res;
+
switch (tcp->scno + NR_SYSCALL_BASE) {
#ifdef LINUX
#if !defined (ALPHA) && !defined(SPARC) && !defined(MIPS)