<html><body>
<p>Hi,  Please comment on this request for an enhancement to strace.<br>
I am not on this llist so please cc me on your responses.<br>
<br>
<font face="Arial">The following patch adds the -I option to strace this option will print a basic<br>
stack trace for each system call.  This allows you to tell what lib or user<br>
module made the call.  You can match the address printed to the entries in<br>
/proc/pid/maps to find the binary.</font><br>
<font face="Arial"><br>
I have only implemented for s390 and s390x (Linux).  Other arch(s) need to be done.<br>
<br>
Here is an example of the output:<br>
write(2, ......) = 47<br>
Call Trace:<br>
[ 40056328 ]<br>
[ 40122e76 ]<br>
[ 40122e0c ]<br>
[ 401233f0 ]<br>
[ 401180f4 ]<br>
[ 400409e2 ]<br>
[ 40030f9c ]<br>
[ 40031546 ]<br>
[ 40030e62 ]<br>
[ 00413b24 ]<br>
[ 00413a40 ]<br>
[ 0041467c ]<br>
[ 0041550c ]<br>
[ 00414d1e ]<br>
[ 004138ee ]<br>
[ 00412918 ]<br>
[ 004129dc ]<br>
[ 00412638 ]<br>
[ 004106a6 ]<br>
[ 400cd7bc ]<br>
[ 0040fd20 ]<br>
[ 7fffffff ]<br>
</font><br>
------------------patch--------------------<br>
<tt><font size="4">--- util.c.orig                 2003-06-03 16:28:59.000000000 -0700<br>
+++ util.c               2005-01-20 17:27:51.000000000 -0800<br>
@@ -1007,6 +1007,56 @@<br>
 #endif /* FREEBSD */<br>
 }<br>
 <br>
+#ifdef LINUX<br>
+<br>
+#ifdef S390<br>
+#define PSW_ADDR_INSN           0x7FFFFFFFUL<br>
+#define RET_ADDR                56<br>
+#endif /* S390 */<br>
+<br>
+#ifdef S390X<br>
+#define PSW_ADDR_INSN           0xFFFFFFFFFFFFFFFFUL<br>
+#define RET_ADDR                112<br>
+#endif /* S390X */<br>
+<br>
+void print_trace(tcp)<br>
+struct tcb *tcp;<br>
+{<br>
+<br>
+#ifdef I386<br>
+                tprintf("[stack trace not implemented]");<br>
+                <br>
+<br>
+#elif  defined(S390) || defined(S390X)<br>
+<br>
+                unsigned long backchain, ret_addr;<br>
+                unsigned long * stack;<br>
+<br>
+                if(upeek(tcp->pid,PT_GPR15,(long *)&stack) < 0) {<br>
+                                tprintf("[Can't print stack]\n ");<br>
+                                return;<br>
+                }<br>
+                tprintf("Call Trace:\n");<br>
+                backchain = ((unsigned long) stack) & PSW_ADDR_INSN;<br>
+                while( backchain < PSW_ADDR_INSN){<br>
+                                ret_addr = ptrace(PTRACE_PEEKDATA,tcp->pid,(char *)(backchain+RET_ADDR),0)& PSW_ADDR_INSN;<br>
+                                if ( ret_addr == -1 ){<br>
+                                                tprintf("[Can't print stack, bad return address]\n ");<br>
+                                                return;<br>
+                                }<br>
+                                tprintf("[ %08lx ]\n", ret_addr);<br>
+                                backchain = ptrace(PTRACE_PEEKDATA,tcp->pid,(char *)backchain,0) & PSW_ADDR_INSN;<br>
+                                if ( backchain == -1 ){<br>
+                                                tprintf("[Can't print stack, bad backchain]\n ");<br>
+                                                return;<br>
+                                }<br>
+<br>
+                }<br>
+                tprintf("\n");<br>
+#endif /* Arch */<br>
+}<br>
+#endif /* Linux */<br>
+<br>
 void<br>
 printcall(tcp)<br>
 struct tcb *tcp;<br>
--- defs.h.orig          2005-01-20 16:47:22.000000000 -0800<br>
+++ defs.h               2005-01-20 16:54:46.000000000 -0800<br>
@@ -445,6 +445,7 @@<br>
 extern int setbpt P((struct tcb *));<br>
 extern int sigishandled P((struct tcb *, int));<br>
 extern void printcall P((struct tcb *));<br>
+extern void print_trace P((struct tcb *));<br>
 extern char *signame P((int));<br>
 extern void printsignal P((int));<br>
 extern void printleader P((struct tcb *));<br>
--- strace.c.orig                2005-01-20 16:43:45.000000000 -0800<br>
+++ strace.c             2005-01-20 16:58:10.000000000 -0800<br>
@@ -64,7 +64,7 @@<br>
 <br>
 int debug = 0, followfork = 0, followvfork = 0, interactive = 0;<br>
 int rflag = 0, tflag = 0, dtime = 0, cflag = 0;<br>
-int iflag = 0, xflag = 0, qflag = 0;<br>
+int iflag = 0, xflag = 0, qflag = 0, Iflag = 0;<br>
 int pflag_seen = 0;<br>
 <br>
 /* Sometimes we want to print only succeeding syscalls. */<br>
@@ -205,7 +205,7 @@<br>
                 set_sortby(DEFAULT_SORTBY);<br>
                 set_personality(DEFAULT_PERSONALITY);<br>
                 while ((c = getopt(argc, argv,<br>
-                                "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) {<br>
+                                "+cdfFhiIqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) {<br>
                                 switch (c) {<br>
                                 case 'c':<br>
                                                 cflag++;<br>
@@ -226,6 +226,9 @@<br>
                                 case 'i':<br>
                                                 iflag++;<br>
                                                 break;<br>
+                                case 'I':<br>
+                                                Iflag++;<br>
+                                                break;<br>
                                 case 'q':<br>
                                                 qflag++;<br>
                                                 break;<br>
@@ -2277,6 +2280,8 @@<br>
 {<br>
                 tprintf("\n");<br>
                 tcp_last = NULL;<br>
+                if (Iflag)<br>
+                print_trace(tcp);<br>
 }<br>
 <br>
 #ifdef HAVE_MP_PROCFS<br>
</font></tt><br>
<br>
David  Wilder<br>
   IBM Global Services, Linux Change Team<br>
   wilder@us.ibm.com<br>
   (503) 578-3789  T/L 775-3789</body></html>