I've added support for displaying the call stack that
leads up to each system
call. I'm hoping this is close to what the TODO file
means by "consider
adding backtrace support". Once the attached patch is
applied and strace is
built from CVS using an option I added that enables it:
./configure --enable-stack-trace
a call stack leading up to each system call is
displayed. For example, when
the following program:
------------------------------------------------------------------------
#include<stdlib.h>
#include<stdio.h>
a_func(int a, int b)
{
printf("First call to printf\n");
printf("Second call to printf\n");
malloc(0x1234);
}
int main(int argc, char *argv[], char *envp[])
{
a_func(0x44332211, 0x88775544);
return 0;
}
------------------------------------------------------------------------
is compiled with
gcc -static -g strace_k_test.c -o strace_k_test
and then traced with
strace -k ./strace_k_test
the output contains:
------------------------------------------------------------------------
main(01 00 00 00 84 f5 ff bf) - 8048234
a_func(11 22 33 44 44 55 77 88) - 80481f3
_IO_printf(a8 db 08 08 00 00 00 00) - 80486d0
vfprintf(80 18 0a 08 a8 db 08 08) - 8053cd8
_IO_new_file_xsputn(80 18 0a 08 a8 db 08 08) -
806f6ff
_IO_new_file_overfl(80 18 0a 08 ff ff ff ff)
- 806f19d
_IO_doallocbuf(80 18 0a 08 00 00 00 00) -
805db8a
_IO_file_doallocate(80 18 0a 08 00 00 00
00) - 8073d89
_IO_file_stat(80 18 0a 08 70 ec ff bf)
- 806fa3e
___fxstat64(03 00 00 00 01 00 00 00)
- 804cc31
fstat64(1, {st_mode=S_IFCHR|0620,
st_rdev=makedev(136, 1), ...}) = 0
__mmap(80 18 0a 08 00 00 00 00) - 804cf7d
old_mmap(NULL, 4096,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x40000000
_IO_new_file_xsputn(80 18 0a 08 a8 db 08 08) -
806f7cb
_IO_default_xsputn(80 18 0a 08 a8 db 08 08)
- 805d3c0
_IO_new_file_overfl(80 18 0a 08 0a 00 00
00) - 806f09d
new_do_write(80 18 0a 08 00 00 00 40) -
806fd1b
__libc_write(80 18 0a 08 00 00 00 40)
- 805f684
write(1, "First call to printf\n",
21First call to printf
) = 21
a_func(11 22 33 44 44 55 77 88) - 8048203
_IO_printf(be db 08 08 00 00 00 00) - 80486d0
vfprintf(80 18 0a 08 be db 08 08) - 8053cd8
_IO_new_file_xsputn(80 18 0a 08 be db 08 08) -
806f6ff
_IO_new_file_overfl(80 18 0a 08 ff ff ff ff)
- 806f125
new_do_write(80 18 0a 08 00 00 00 40) -
806fd1b
__libc_write(80 18 0a 08 00 00 00 40) -
805f684
write(1, "Second call to printf\n",
22Second call to printf
) = 22
a_func(11 22 33 44 44 55 77 88) - 8048213
__libc_malloc(34 12 00 00 00 00 00 00) - 8048f1d
chunk_alloc(80 18 0a 08 be db 08 08) - 80495ee
__default_morecore(00 20 00 00 00 28 6e 6f) -
804ca8e
__sbrk(00 20 00 00 00 00 00 00) - 804cf34
__brk(00 70 0a 08 69 36 38 36) - 805f805
brk(0x80a7000) = 0x80a7000
_start(?? ?? ?? ?? ?? ?? ?? ??) - 8048101
exit(00 00 00 00 01 00 00 00) - 8048576
_IO_cleanup(00 00 00 00 01 00 00 00) - 805e245
_IO_new_file_setbuf(80 18 0a 08 00 00 00 00) -
806fc56
__munmap(80 18 0a 08 00 00 00 00) - 804cfa1
munmap(0x40000000, 4096) = 0
_exit(?? ?? ?? ?? ?? ?? ?? ??) - 804caed
_exit(0) = ?
------------------------------------------------------------------------
There are various limitations with the attached patch:
1) It only works for Linux/Intel. I don't think it
would be difficult to port
the register reading portion of it to other OSs; but
reading symbols might
be a bit trickier. I don't have the means of
porting it to other OSs.
2) It gets confused when it encounters code that has
been optimized such that
there are no frame pointers (gcc's
-fomit-frame-pointer). This is a common
problem with debuggers.
3) It uses questionable means to guess when all of the
symbols have been
loaded.
4) It uses questionable means to guess when highest
stack frame (main(), for
example) has been reached.
5) It requires libbfd.so
Please send me any feedback you might have. Hopefully
this is something that
will be beneficial for strace.
Add call stack support (-k switch)
Logged In: YES
user_id=77630
It is unfortunate that Sourceforge strips the leading
whitespace from each
line in comments. Here is a bit of what a posted with
leading spaces replaced
with ".":
main(01 00 00 00 84 f5 ff bf) - 8048234
..a_func(11 22 33 44 44 55 77 88) - 80481f3
...._IO_printf(a8 db 08 08 00 00 00 00) - 80486d0
......vfprintf(80 18 0a 08 a8 db 08 08) - 8053cd8
........_IO_new_file_xsputn(80 18 0a 08 a8 db 08 08) - 806f6ff
.........._IO_new_file_overfl(80 18 0a 08 ff ff ff ff) -
806f19d
............_IO_doallocbuf(80 18 0a 08 00 00 00 00) - 805db8a
.............._IO_file_doallocate(80 18 0a 08 00 00 00 00)
- 8073d89
................_IO_file_stat(80 18 0a 08 70 ec ff bf) -
806fa3e
..................___fxstat64(03 00 00 00 01 00 00 00) -
804cc31
....................fstat64(1, {st_mode=S_IFCHR|0620,
st_rdev=makedev(136, 1), ...}) = 0
..............__mmap(80 18 0a 08 00 00 00 00) - 804cf7d
................old_mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40000000
........_IO_new_file_xsputn(80 18 0a 08 a8 db 08 08) - 806f7cb
.........._IO_default_xsputn(80 18 0a 08 a8 db 08 08) - 805d3c0
............_IO_new_file_overfl(80 18 0a 08 0a 00 00 00) -
806f09d
..............new_do_write(80 18 0a 08 00 00 00 40) - 806fd1b
................__libc_write(80 18 0a 08 00 00 00 40) - 805f684
..................write(1, "First call to printf\n", 21First
call to printf
) = 21
..a_func(11 22 33 44 44 55 77 88) - 8048203
...._IO_printf(be db 08 08 00 00 00 00) - 80486d0
......vfprintf(80 18 0a 08 be db 08 08) - 8053cd8
........_IO_new_file_xsputn(80 18 0a 08 be db 08 08) - 806f6ff
.........._IO_new_file_overfl(80 18 0a 08 ff ff ff ff) -
806f125
............new_do_write(80 18 0a 08 00 00 00 40) - 806fd1b
..............__libc_write(80 18 0a 08 00 00 00 40) - 805f684
................write(1, "Second call to printf\n", 22Second
call to printf
Stack unwinding is supported since strace 4.9.