[RFC] print stack trace after each syscall

Dmitry V. Levin ldv at altlinux.org
Wed Jun 26 08:30:46 UTC 2013


On Mon, Jun 24, 2013 at 12:18:58AM -0700, Luca Clementi wrote:
> This patch prints the stack trace of the traced process after
> each system call when using -k flag. It uses libunwind to
> unwind the stack and to obtain the function name pointed by
> the IP.
[...]
> --- a/defs.h
> +++ b/defs.h
> @@ -392,6 +392,29 @@ typedef struct ioctlent {
>  	unsigned long code;
>  } struct_ioctlent;
>  
> +
> +#ifdef LIB_UNWIND
> +#include <libunwind-ptrace.h>
> +#include <libunwind.h>

Please avoid including feature-specific header files in defs.h because the
latter is included by all translation units.  Just include these headers
where they are really needed.

> +/* keep a sorted array of cache entries, so that we can binary search
> + * through it
> + */
> +struct mmap_cache_t {
> +	// example entry:
> +	// 7fabbb09b000-7fabbb09f000 r--p 00179000 fc:00 1180246 /lib/libc-2.11.1.so
> +	//
> +	// start_addr  is 0x7fabbb09b000
> +	// end_addr    is 0x7fabbb09f000
> +	// mmap_offset is 0x179000
> +	// binary_filename is "/lib/libc-2.11.1.so"
> +	unsigned long start_addr;
> +	unsigned long end_addr;
> +	unsigned long mmap_offset;
> +	char* binary_filename;
> +};
> +#endif
> +
>  /* Trace Control Block */
>  struct tcb {
>  	int flags;		/* See below for TCB_ values */
> @@ -417,6 +440,13 @@ struct tcb {
>  	struct timeval etime;	/* Syscall entry time */
>  				/* Support for tracing forked processes: */
>  	long inst[2];		/* Saved clone args (badly named) */
> +
> +#ifdef LIB_UNWIND
> +	// keep a cache of /proc/<pid>/mmap contents to avoid unnecessary file reads
> +	struct mmap_cache_t* mmap_cache;
> +	int mmap_cache_size;
> +	struct UPT_info* libunwind_ui;
> +#endif
>  };

This can stay in defs.h without including libunwind header files,
just add a forward declaration for struct UPT_info.

>  /* TCB flags */
> @@ -710,6 +740,14 @@ extern void tv_sub(struct timeval *, struct timeval *, struct timeval *);
>  extern void tv_mul(struct timeval *, struct timeval *, int);
>  extern void tv_div(struct timeval *, struct timeval *, int);
>  
> +#ifdef LIB_UNWIND
> +/**
> + * print stack (-k flag) memory allocation and deallocation
> + */
> +extern void alloc_mmap_cache(struct tcb* tcp);
> +extern void delete_mmap_cache(struct tcb* tcp);
> +#endif

Please add here all declarations you need, avoid placing them in *.c files.

> +#ifdef LIB_UNWIND
> +	if (!entering(tcp))
> +		delete_mmap_cache(tcp);
> +#endif

In all such places, please use "exiting" instead of "!entering".

> +			if (use_libunwind) {
> +				tcp->libunwind_ui = _UPT_create(tcp->pid);
> +			}

If _UPT_create allocates memory, it can fail.
Please check return code of all functions that allocate memory.

> --- a/syscall.c
> +++ b/syscall.c
> @@ -1946,6 +1946,194 @@ get_syscall_args(struct tcb *tcp)
>  	return 1;
>  }
>  
> +#ifdef LIB_UNWIND
> +
> +extern unw_addr_space_t libunwind_as;
> +
> +/*
> + * caching of /proc/ID/maps for each process to speed up stack tracing
> + *
> + * The cache must be refreshed after some syscall: mmap, mprotect, munmap, execve 
> + */
> +void alloc_mmap_cache(struct tcb* tcp) {

The code you are working on is quite specific, so please create a new
translation unit (e.g. unwind.c) and place all new definitions there.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20130626/260414a9/attachment.bin>


More information about the Strace-devel mailing list