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