Dump stack trace option

David Wilder wilder at us.ibm.com
Fri Jan 28 15:56:17 UTC 2005





Hi,  Please comment on this request for an enhancement to strace.
I am not on this llist so please cc me on your responses.

The following patch adds the -I option to strace this option will print a
basic
stack trace for each system call.  This allows you to tell what lib or user
module made the call.  You can match the address printed to the entries in
/proc/pid/maps to find the binary.

I have only implemented for s390 and s390x (Linux).  Other arch(s) need to
be done.

Here is an example of the output:
write(2, ......) = 47
Call Trace:
[ 40056328 ]
[ 40122e76 ]
[ 40122e0c ]
[ 401233f0 ]
[ 401180f4 ]
[ 400409e2 ]
[ 40030f9c ]
[ 40031546 ]
[ 40030e62 ]
[ 00413b24 ]
[ 00413a40 ]
[ 0041467c ]
[ 0041550c ]
[ 00414d1e ]
[ 004138ee ]
[ 00412918 ]
[ 004129dc ]
[ 00412638 ]
[ 004106a6 ]
[ 400cd7bc ]
[ 0040fd20 ]
[ 7fffffff ]

------------------patch--------------------
--- util.c.orig          2003-06-03 16:28:59.000000000 -0700
+++ util.c         2005-01-20 17:27:51.000000000 -0800
@@ -1007,6 +1007,56 @@
 #endif /* FREEBSD */
 }

+#ifdef LINUX
+
+#ifdef S390
+#define PSW_ADDR_INSN           0x7FFFFFFFUL
+#define RET_ADDR                56
+#endif /* S390 */
+
+#ifdef S390X
+#define PSW_ADDR_INSN           0xFFFFFFFFFFFFFFFFUL
+#define RET_ADDR                112
+#endif /* S390X */
+
+void print_trace(tcp)
+struct tcb *tcp;
+{
+
+#ifdef I386
+            tprintf("[stack trace not implemented]");
+
+
+#elif  defined(S390) || defined(S390X)
+
+            unsigned long backchain, ret_addr;
+            unsigned long * stack;
+
+            if(upeek(tcp->pid,PT_GPR15,(long *)&stack) < 0) {
+                        tprintf("[Can't print stack]\n ");
+                        return;
+            }
+            tprintf("Call Trace:\n");
+            backchain = ((unsigned long) stack) & PSW_ADDR_INSN;
+            while( backchain < PSW_ADDR_INSN){
+                        ret_addr = ptrace(PTRACE_PEEKDATA,tcp->pid,(char
*)(backchain+RET_ADDR),0)& PSW_ADDR_INSN;
+                        if ( ret_addr == -1 ){
+                                    tprintf("[Can't print stack, bad
return address]\n ");
+                                    return;
+                        }
+                        tprintf("[ %08lx ]\n", ret_addr);
+                        backchain = ptrace(PTRACE_PEEKDATA,tcp->pid,(char
*)backchain,0) & PSW_ADDR_INSN;
+                        if ( backchain == -1 ){
+                                    tprintf("[Can't print stack, bad
backchain]\n ");
+                                    return;
+                        }
+
+            }
+            tprintf("\n");
+#endif /* Arch */
+}
+#endif /* Linux */
+
 void
 printcall(tcp)
 struct tcb *tcp;
--- defs.h.orig          2005-01-20 16:47:22.000000000 -0800
+++ defs.h         2005-01-20 16:54:46.000000000 -0800
@@ -445,6 +445,7 @@
 extern int setbpt P((struct tcb *));
 extern int sigishandled P((struct tcb *, int));
 extern void printcall P((struct tcb *));
+extern void print_trace P((struct tcb *));
 extern char *signame P((int));
 extern void printsignal P((int));
 extern void printleader P((struct tcb *));
--- strace.c.orig        2005-01-20 16:43:45.000000000 -0800
+++ strace.c             2005-01-20 16:58:10.000000000 -0800
@@ -64,7 +64,7 @@

 int debug = 0, followfork = 0, followvfork = 0, interactive = 0;
 int rflag = 0, tflag = 0, dtime = 0, cflag = 0;
-int iflag = 0, xflag = 0, qflag = 0;
+int iflag = 0, xflag = 0, qflag = 0, Iflag = 0;
 int pflag_seen = 0;

 /* Sometimes we want to print only succeeding syscalls. */
@@ -205,7 +205,7 @@
             set_sortby(DEFAULT_SORTBY);
             set_personality(DEFAULT_PERSONALITY);
             while ((c = getopt(argc, argv,
-                        "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) {
+                        "+cdfFhiIqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) {
                         switch (c) {
                         case 'c':
                                     cflag++;
@@ -226,6 +226,9 @@
                         case 'i':
                                     iflag++;
                                     break;
+                        case 'I':
+                                    Iflag++;
+                                    break;
                         case 'q':
                                     qflag++;
                                     break;
@@ -2277,6 +2280,8 @@
 {
             tprintf("\n");
             tcp_last = NULL;
+            if (Iflag)
+                print_trace(tcp);
 }

 #ifdef HAVE_MP_PROCFS


David  Wilder
   IBM Global Services, Linux Change Team
   wilder at us.ibm.com
   (503) 578-3789  T/L 775-3789
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20050128/20aed0fb/attachment.html>


More information about the Strace-devel mailing list