2013-07-23 11:11:35 +04:00
/*
* Copyright ( c ) 2013 Luca Clementi < luca . clementi @ gmail . com >
2018-02-14 01:00:00 +03:00
* Copyright ( c ) 2013 - 2018 The strace developers .
2013-07-23 11:11:35 +04:00
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "defs.h"
2018-02-27 02:22:24 +03:00
# include "mmap_cache.h"
2013-07-23 11:11:35 +04:00
# include <libunwind-ptrace.h>
2017-12-18 07:24:55 +03:00
# ifdef USE_DEMANGLE
2018-01-09 22:23:01 +03:00
# if defined HAVE_DEMANGLE_H
# include <demangle.h>
# elif defined HAVE_LIBIBERTY_DEMANGLE_H
# include <libiberty / demangle.h>
# endif
2017-12-18 07:24:55 +03:00
# endif
2014-04-16 10:33:04 +04:00
/*
* Type used in stacktrace walker
*/
typedef void ( * call_action_fn ) ( void * data ,
2014-06-06 02:37:09 +04:00
const char * binary_filename ,
const char * symbol_name ,
2014-06-06 01:44:40 +04:00
unw_word_t function_offset ,
2014-04-16 10:33:04 +04:00
unsigned long true_offset ) ;
typedef void ( * error_action_fn ) ( void * data ,
const char * error ,
unsigned long true_offset ) ;
2014-04-16 10:33:06 +04:00
/*
* Type used in stacktrace capturing
*/
struct call_t {
2017-06-18 01:23:09 +03:00
struct call_t * next ;
char * output_line ;
2014-04-16 10:33:06 +04:00
} ;
struct queue_t {
2017-06-18 01:23:09 +03:00
struct call_t * tail ;
struct call_t * head ;
2014-04-16 10:33:06 +04:00
} ;
2014-04-16 10:33:07 +04:00
2014-04-16 10:33:06 +04:00
static void queue_print ( struct queue_t * queue ) ;
2014-04-16 10:33:04 +04:00
2013-07-23 11:11:35 +04:00
static unw_addr_space_t libunwind_as ;
2017-08-04 09:43:16 +03:00
static const char asprintf_error_str [ ] = " ??? " ;
2013-07-23 11:11:35 +04:00
void
2014-04-16 10:33:02 +04:00
unwind_init ( void )
2013-07-23 11:11:35 +04:00
{
libunwind_as = unw_create_addr_space ( & _UPT_accessors , 0 ) ;
if ( ! libunwind_as )
error_msg_and_die ( " failed to create address space for stack tracing " ) ;
2014-04-16 10:33:10 +04:00
unw_set_caching_policy ( libunwind_as , UNW_CACHE_GLOBAL ) ;
2018-02-16 22:37:13 +03:00
mmap_cache_enable ( ) ;
2013-07-23 11:11:35 +04:00
}
void
2014-04-16 10:33:02 +04:00
unwind_tcb_init ( struct tcb * tcp )
2013-07-23 11:11:35 +04:00
{
2016-12-08 22:54:24 +03:00
if ( tcp - > libunwind_ui )
return ;
2013-07-23 11:11:35 +04:00
tcp - > libunwind_ui = _UPT_create ( tcp - > pid ) ;
if ( ! tcp - > libunwind_ui )
2017-06-27 01:41:28 +03:00
perror_msg_and_die ( " _UPT_create " ) ;
2014-04-16 10:33:06 +04:00
Introduce memory allocation wrappers
Introduce wrappers to the following functions that do memory allocation:
malloc, calloc, realloc, strdup.
This commit is a follow-up to the related discussions in strace-devel ML:
http://sourceforge.net/p/strace/mailman/message/33618180/
http://sourceforge.net/p/strace/mailman/message/33733470/
* defs.h (xmalloc, xcalloc, xreallocarray, xstrdup): New prototypes.
* xmalloc.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* count.c (count_syscall, call_summary_pers): Use xcalloc.
* desc.c (decode_select): Use xmalloc.
* dirent.c (sys_getdents, sys_getdents64): Likewise.
* net.c (sys_recvmmsg): Use xstrdup.
* pathtrace.c (storepath): Use xreallocarray.
(pathtrace_match): Use xmalloc.
* strace.c (die_out_of_memory): Move to xmalloc.c.
(expand_tcbtab): Use xcalloc and xreallocarray.
(startup_child): Use xstrdup.
(init): Use xmalloc, xcalloc, and xstrdup.
* syscall.c (reallocate_qual): Use xreallocarray.
(qualify): Use xstrdup.
* unwind.c (unwind_tcb_init): Use xmalloc.
(build_mmap_cache): Use xcalloc, xreallocarray, and xstrdup.
(get_symbol_name): Use xreallocarray.
(stacktrace_walk, queue_put): Use xmalloc.
* util.c (printstr): Use xmalloc.
* vsprintf.c (strace_vfprintf): Likewise.
2015-05-25 23:41:02 +03:00
tcp - > queue = xmalloc ( sizeof ( * tcp - > queue ) ) ;
2014-04-16 10:33:06 +04:00
tcp - > queue - > head = NULL ;
tcp - > queue - > tail = NULL ;
2013-07-23 11:11:35 +04:00
}
void
2014-04-16 10:33:02 +04:00
unwind_tcb_fin ( struct tcb * tcp )
2013-07-23 11:11:35 +04:00
{
2014-04-16 10:33:06 +04:00
queue_print ( tcp - > queue ) ;
free ( tcp - > queue ) ;
tcp - > queue = NULL ;
2013-07-23 11:11:35 +04:00
_UPT_destroy ( tcp - > libunwind_ui ) ;
tcp - > libunwind_ui = NULL ;
}
2014-06-06 02:28:57 +04:00
static void
get_symbol_name ( unw_cursor_t * cursor , char * * name ,
size_t * size , unw_word_t * offset )
{
for ( ; ; ) {
int rc = unw_get_proc_name ( cursor , * name , * size , offset ) ;
if ( rc = = 0 )
break ;
if ( rc ! = - UNW_ENOMEM ) {
* * name = ' \0 ' ;
* offset = 0 ;
break ;
}
2017-12-14 03:05:04 +03:00
* name = xgrowarray ( * name , size , 1 ) ;
2014-06-06 02:28:57 +04:00
}
}
static int
print_stack_frame ( struct tcb * tcp ,
call_action_fn call_action ,
error_action_fn error_action ,
void * data ,
unw_cursor_t * cursor ,
char * * symbol_name ,
size_t * symbol_name_size )
{
unw_word_t ip ;
2018-02-16 22:37:10 +03:00
struct mmap_cache_t * cur_mmap_cache ;
2014-06-06 02:28:57 +04:00
if ( unw_get_reg ( cursor , UNW_REG_IP , & ip ) < 0 ) {
perror_msg ( " Can't walk the stack of process %d " , tcp - > pid ) ;
return - 1 ;
}
2018-02-16 22:37:10 +03:00
cur_mmap_cache = mmap_cache_search ( tcp , ip ) ;
2018-02-16 22:37:11 +03:00
if ( cur_mmap_cache
/* ignore mappings that have no PROT_EXEC bit set */
& & ( cur_mmap_cache - > protections & MMAP_CACHE_PROT_EXECUTABLE ) ) {
2018-02-16 22:37:10 +03:00
unsigned long true_offset ;
unw_word_t function_offset ;
2017-12-18 07:24:55 +03:00
2018-02-16 22:37:10 +03:00
get_symbol_name ( cursor , symbol_name , symbol_name_size ,
& function_offset ) ;
true_offset = ip - cur_mmap_cache - > start_addr +
cur_mmap_cache - > mmap_offset ;
2017-12-18 07:24:55 +03:00
# ifdef USE_DEMANGLE
2018-02-16 22:37:10 +03:00
char * demangled_name =
cplus_demangle ( * symbol_name ,
DMGL_AUTO | DMGL_PARAMS ) ;
2017-12-18 07:24:55 +03:00
# endif
2018-02-16 22:37:10 +03:00
call_action ( data ,
cur_mmap_cache - > binary_filename ,
2017-12-18 07:24:55 +03:00
# ifdef USE_DEMANGLE
2018-02-16 22:37:10 +03:00
demangled_name ? demangled_name :
2017-12-18 07:24:55 +03:00
# endif
2018-02-16 22:37:10 +03:00
* symbol_name ,
function_offset ,
true_offset ) ;
2017-12-18 07:24:55 +03:00
# ifdef USE_DEMANGLE
2018-02-16 22:37:10 +03:00
free ( demangled_name ) ;
2017-12-18 07:24:55 +03:00
# endif
2018-02-16 22:37:10 +03:00
return 0 ;
2014-06-06 02:28:57 +04:00
}
/*
* there is a bug in libunwind > = 1.0
* after a set_tid_address syscall
* unw_get_reg returns IP = = 0
*/
2017-06-18 01:23:09 +03:00
if ( ip )
2014-06-06 02:28:57 +04:00
error_action ( data , " unexpected_backtracing_error " , ip ) ;
return - 1 ;
}
2014-04-16 10:33:04 +04:00
/*
* walking the stack
*/
static void
stacktrace_walk ( struct tcb * tcp ,
call_action_fn call_action ,
error_action_fn error_action ,
void * data )
2013-07-23 11:11:35 +04:00
{
2014-06-06 02:28:57 +04:00
char * symbol_name ;
2013-07-23 11:11:35 +04:00
size_t symbol_name_size = 40 ;
2014-06-06 02:28:57 +04:00
unw_cursor_t cursor ;
int stack_depth ;
2013-07-23 11:11:35 +04:00
if ( ! tcp - > mmap_cache )
2014-04-16 10:33:07 +04:00
error_msg_and_die ( " bug: mmap_cache is NULL " ) ;
if ( tcp - > mmap_cache_size = = 0 )
error_msg_and_die ( " bug: mmap_cache is empty " ) ;
2013-07-23 11:11:35 +04:00
Introduce memory allocation wrappers
Introduce wrappers to the following functions that do memory allocation:
malloc, calloc, realloc, strdup.
This commit is a follow-up to the related discussions in strace-devel ML:
http://sourceforge.net/p/strace/mailman/message/33618180/
http://sourceforge.net/p/strace/mailman/message/33733470/
* defs.h (xmalloc, xcalloc, xreallocarray, xstrdup): New prototypes.
* xmalloc.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* count.c (count_syscall, call_summary_pers): Use xcalloc.
* desc.c (decode_select): Use xmalloc.
* dirent.c (sys_getdents, sys_getdents64): Likewise.
* net.c (sys_recvmmsg): Use xstrdup.
* pathtrace.c (storepath): Use xreallocarray.
(pathtrace_match): Use xmalloc.
* strace.c (die_out_of_memory): Move to xmalloc.c.
(expand_tcbtab): Use xcalloc and xreallocarray.
(startup_child): Use xstrdup.
(init): Use xmalloc, xcalloc, and xstrdup.
* syscall.c (reallocate_qual): Use xreallocarray.
(qualify): Use xstrdup.
* unwind.c (unwind_tcb_init): Use xmalloc.
(build_mmap_cache): Use xcalloc, xreallocarray, and xstrdup.
(get_symbol_name): Use xreallocarray.
(stacktrace_walk, queue_put): Use xmalloc.
* util.c (printstr): Use xmalloc.
* vsprintf.c (strace_vfprintf): Likewise.
2015-05-25 23:41:02 +03:00
symbol_name = xmalloc ( symbol_name_size ) ;
2013-07-23 11:11:35 +04:00
if ( unw_init_remote ( & cursor , libunwind_as , tcp - > libunwind_ui ) < 0 )
perror_msg_and_die ( " Can't initiate libunwind " ) ;
2014-06-06 02:28:57 +04:00
for ( stack_depth = 0 ; stack_depth < 256 ; + + stack_depth ) {
if ( print_stack_frame ( tcp , call_action , error_action , data ,
& cursor , & symbol_name , & symbol_name_size ) < 0 )
2013-07-23 11:11:35 +04:00
break ;
2014-06-06 02:28:57 +04:00
if ( unw_step ( & cursor ) < = 0 )
2013-07-23 11:11:35 +04:00
break ;
2014-06-06 02:28:57 +04:00
}
if ( stack_depth > = 256 )
error_action ( data , " too many stack frames " , 0 ) ;
2013-07-23 11:11:35 +04:00
free ( symbol_name ) ;
}
2014-04-16 10:33:04 +04:00
/*
2014-04-16 10:33:06 +04:00
* printing an entry in stack to stream or buffer
2014-04-16 10:33:04 +04:00
*/
/*
* we want to keep the format used by backtrace_symbols from the glibc
*
* . / a . out ( ) [ 0x40063d ]
* . / a . out ( ) [ 0x4006bb ]
* . / a . out ( ) [ 0x4006c6 ]
* / lib64 / libc . so .6 ( __libc_start_main + 0xed ) [ 0x7fa2f8a5976d ]
* . / a . out ( ) [ 0x400569 ]
*/
# define STACK_ENTRY_SYMBOL_FMT \
" > %s(%s+0x%lx) [0x%lx] \n " , \
binary_filename , \
symbol_name , \
2014-06-06 01:44:40 +04:00
( unsigned long ) function_offset , \
2014-04-16 10:33:04 +04:00
true_offset
# define STACK_ENTRY_NOSYMBOL_FMT \
" > %s() [0x%lx] \n " , \
binary_filename , true_offset
# define STACK_ENTRY_BUG_FMT \
" > BUG IN %s \n "
# define STACK_ENTRY_ERROR_WITH_OFFSET_FMT \
" > %s [0x%lx] \n " , error , true_offset
# define STACK_ENTRY_ERROR_FMT \
" > %s \n " , error
static void
print_call_cb ( void * dummy ,
2014-06-06 02:37:09 +04:00
const char * binary_filename ,
const char * symbol_name ,
2014-06-06 01:44:40 +04:00
unw_word_t function_offset ,
2014-04-16 10:33:04 +04:00
unsigned long true_offset )
{
stack trace support: fix check on symbol name presence
The output format of the stack trace is supposed to be different
depending on whether symbol names are available in the build.
However, the check only verified the validity of the pointer, not of the
string pointed to (which could be empty).
This commit fixes the check so that the original output:
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x5e000
> /lib/libc-2.10.1.so(_IO_file_doallocate+0x8c) [0x68a38]
> /lib/libc-2.10.1.so(_IO_doallocbuf+0x6c) [0x78574]
> /lib/libc-2.10.1.so(_IO_file_overflow+0x184) [0x7763c]
> /lib/libc-2.10.1.so(_IO_file_xsputn+0x88) [0x76aac]
> /lib/libc-2.10.1.so(_IO_puts+0xc8) [0x6b64c]
> /bin/busybox(+0x0) [0x62c60]
> /bin/busybox(+0x0) [0x4940]
> /bin/busybox(+0x0) [0x499c]
> /bin/busybox(+0x0) [0x4e08]
> /lib/libc-2.10.1.so(__libc_init_first+0x30c) [0x1f84c]
> /lib/libc-2.10.1.so(__libc_start_main+0xd8) [0x1f9f8]
becomes:
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x5e000
> /lib/libc-2.10.1.so(_IO_file_doallocate+0x8c) [0x68a38]
> /lib/libc-2.10.1.so(_IO_doallocbuf+0x6c) [0x78574]
> /lib/libc-2.10.1.so(_IO_file_overflow+0x184) [0x7763c]
> /lib/libc-2.10.1.so(_IO_file_xsputn+0x88) [0x76aac]
> /lib/libc-2.10.1.so(_IO_puts+0xc8) [0x6b64c]
> /bin/busybox() [0x62c60]
> /bin/busybox() [0x4940]
> /bin/busybox() [0x499c]
> /bin/busybox() [0x4e08]
> /lib/libc-2.10.1.so(__libc_init_first+0x30c) [0x1f84c]
> /lib/libc-2.10.1.so(__libc_start_main+0xd8) [0x1f9f8]
Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
Acked-by: Masatake YAMATO <yamato@redhat.com>
2014-11-06 15:59:04 +03:00
if ( symbol_name & & ( symbol_name [ 0 ] ! = ' \0 ' ) )
2014-04-16 10:33:04 +04:00
tprintf ( STACK_ENTRY_SYMBOL_FMT ) ;
else if ( binary_filename )
tprintf ( STACK_ENTRY_NOSYMBOL_FMT ) ;
else
2017-06-17 23:39:26 +03:00
tprintf ( STACK_ENTRY_BUG_FMT , __func__ ) ;
2014-04-16 10:33:04 +04:00
line_ended ( ) ;
}
static void
print_error_cb ( void * dummy ,
const char * error ,
unsigned long true_offset )
{
if ( true_offset )
tprintf ( STACK_ENTRY_ERROR_WITH_OFFSET_FMT ) ;
else
tprintf ( STACK_ENTRY_ERROR_FMT ) ;
line_ended ( ) ;
}
2014-04-16 10:33:06 +04:00
static char *
2014-06-06 02:37:09 +04:00
sprint_call_or_error ( const char * binary_filename ,
const char * symbol_name ,
2014-06-06 01:44:40 +04:00
unw_word_t function_offset ,
2014-04-16 10:33:06 +04:00
unsigned long true_offset ,
const char * error )
{
2017-06-18 01:23:09 +03:00
char * output_line = NULL ;
int n ;
if ( symbol_name )
n = asprintf ( & output_line , STACK_ENTRY_SYMBOL_FMT ) ;
else if ( binary_filename )
n = asprintf ( & output_line , STACK_ENTRY_NOSYMBOL_FMT ) ;
else if ( error )
n = true_offset
? asprintf ( & output_line , STACK_ENTRY_ERROR_WITH_OFFSET_FMT )
: asprintf ( & output_line , STACK_ENTRY_ERROR_FMT ) ;
else
n = asprintf ( & output_line , STACK_ENTRY_BUG_FMT , __func__ ) ;
2017-08-04 09:43:16 +03:00
if ( n < 0 ) {
perror_func_msg ( " asprintf " ) ;
output_line = ( char * ) asprintf_error_str ;
}
2017-06-18 01:23:09 +03:00
return output_line ;
2014-04-16 10:33:06 +04:00
}
/*
* queue manipulators
*/
static void
queue_put ( struct queue_t * queue ,
2014-06-06 02:37:09 +04:00
const char * binary_filename ,
const char * symbol_name ,
2014-06-06 01:44:40 +04:00
unw_word_t function_offset ,
2014-04-16 10:33:06 +04:00
unsigned long true_offset ,
const char * error )
{
struct call_t * call ;
Introduce memory allocation wrappers
Introduce wrappers to the following functions that do memory allocation:
malloc, calloc, realloc, strdup.
This commit is a follow-up to the related discussions in strace-devel ML:
http://sourceforge.net/p/strace/mailman/message/33618180/
http://sourceforge.net/p/strace/mailman/message/33733470/
* defs.h (xmalloc, xcalloc, xreallocarray, xstrdup): New prototypes.
* xmalloc.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* count.c (count_syscall, call_summary_pers): Use xcalloc.
* desc.c (decode_select): Use xmalloc.
* dirent.c (sys_getdents, sys_getdents64): Likewise.
* net.c (sys_recvmmsg): Use xstrdup.
* pathtrace.c (storepath): Use xreallocarray.
(pathtrace_match): Use xmalloc.
* strace.c (die_out_of_memory): Move to xmalloc.c.
(expand_tcbtab): Use xcalloc and xreallocarray.
(startup_child): Use xstrdup.
(init): Use xmalloc, xcalloc, and xstrdup.
* syscall.c (reallocate_qual): Use xreallocarray.
(qualify): Use xstrdup.
* unwind.c (unwind_tcb_init): Use xmalloc.
(build_mmap_cache): Use xcalloc, xreallocarray, and xstrdup.
(get_symbol_name): Use xreallocarray.
(stacktrace_walk, queue_put): Use xmalloc.
* util.c (printstr): Use xmalloc.
* vsprintf.c (strace_vfprintf): Likewise.
2015-05-25 23:41:02 +03:00
call = xmalloc ( sizeof ( * call ) ) ;
2014-04-16 10:33:06 +04:00
call - > output_line = sprint_call_or_error ( binary_filename ,
symbol_name ,
2014-06-06 01:44:40 +04:00
function_offset ,
2014-04-16 10:33:06 +04:00
true_offset ,
error ) ;
call - > next = NULL ;
if ( ! queue - > head ) {
queue - > head = call ;
queue - > tail = call ;
} else {
queue - > tail - > next = call ;
queue - > tail = call ;
}
}
static void
queue_put_call ( void * queue ,
2014-06-06 02:37:09 +04:00
const char * binary_filename ,
const char * symbol_name ,
2014-06-06 01:44:40 +04:00
unw_word_t function_offset ,
2014-04-16 10:33:06 +04:00
unsigned long true_offset )
{
queue_put ( queue ,
binary_filename ,
symbol_name ,
2014-06-06 01:44:40 +04:00
function_offset ,
2014-04-16 10:33:06 +04:00
true_offset ,
NULL ) ;
}
static void
queue_put_error ( void * queue ,
const char * error ,
2014-06-05 18:37:04 +04:00
unsigned long ip )
2014-04-16 10:33:06 +04:00
{
queue_put ( queue , NULL , NULL , 0 , ip , error ) ;
}
static void
queue_print ( struct queue_t * queue )
{
struct call_t * call , * tmp ;
queue - > tail = NULL ;
call = queue - > head ;
queue - > head = NULL ;
while ( call ) {
tmp = call ;
call = call - > next ;
tprints ( tmp - > output_line ) ;
line_ended ( ) ;
2017-08-04 09:43:16 +03:00
if ( tmp - > output_line ! = asprintf_error_str )
free ( tmp - > output_line ) ;
2014-04-16 10:33:06 +04:00
tmp - > output_line = NULL ;
tmp - > next = NULL ;
free ( tmp ) ;
}
}
2014-04-16 10:33:04 +04:00
/*
* printing stack
*/
void
2017-06-18 01:23:09 +03:00
unwind_print_stacktrace ( struct tcb * tcp )
2014-04-16 10:33:04 +04:00
{
2014-06-10 09:05:38 +04:00
# if SUPPORTED_PERSONALITIES > 1
if ( tcp - > currpers ! = DEFAULT_PERSONALITY ) {
2017-08-04 09:36:22 +03:00
/* disable stack trace */
2014-06-10 09:05:38 +04:00
return ;
}
# endif
2017-06-18 01:23:09 +03:00
if ( tcp - > queue - > head ) {
2017-08-04 09:41:49 +03:00
debug_func_msg ( " head: tcp=%p, queue=%p " , tcp , tcp - > queue - > head ) ;
2017-06-18 01:23:09 +03:00
queue_print ( tcp - > queue ) ;
2018-02-16 22:37:09 +03:00
} else switch ( mmap_cache_rebuild_if_invalid ( tcp , __func__ ) ) {
2018-02-16 22:37:08 +03:00
case MMAP_CACHE_REBUILD_RENEWED :
unw_flush_cache ( libunwind_as , 0 , 0 ) ;
2018-03-07 02:52:08 +03:00
ATTRIBUTE_FALLTHROUGH ;
2018-02-16 22:37:08 +03:00
case MMAP_CACHE_REBUILD_READY :
debug_func_msg ( " walk: tcp=%p, queue=%p " , tcp , tcp - > queue - > head ) ;
stacktrace_walk ( tcp , print_call_cb , print_error_cb , NULL ) ;
break ;
default :
/* Do nothing */
;
2017-06-18 01:23:09 +03:00
}
2014-04-16 10:33:06 +04:00
}
/*
* capturing stack
*/
void
unwind_capture_stacktrace ( struct tcb * tcp )
{
2014-06-10 09:05:38 +04:00
# if SUPPORTED_PERSONALITIES > 1
if ( tcp - > currpers ! = DEFAULT_PERSONALITY ) {
2017-08-04 09:36:22 +03:00
/* disable stack trace */
2014-06-10 09:05:38 +04:00
return ;
}
# endif
2014-04-16 10:33:06 +04:00
if ( tcp - > queue - > head )
error_msg_and_die ( " bug: unprinted entries in queue " ) ;
2018-02-16 22:37:09 +03:00
switch ( mmap_cache_rebuild_if_invalid ( tcp , __func__ ) ) {
2018-02-16 22:37:08 +03:00
case MMAP_CACHE_REBUILD_RENEWED :
unw_flush_cache ( libunwind_as , 0 , 0 ) ;
2018-03-07 02:52:08 +03:00
ATTRIBUTE_FALLTHROUGH ;
2018-02-16 22:37:08 +03:00
case MMAP_CACHE_REBUILD_READY :
2014-04-16 10:33:07 +04:00
stacktrace_walk ( tcp , queue_put_call , queue_put_error ,
tcp - > queue ) ;
2017-08-04 09:41:49 +03:00
debug_func_msg ( " tcp=%p, queue=%p " , tcp , tcp - > queue - > head ) ;
2018-02-16 22:37:08 +03:00
break ;
default :
/* Do nothing */
;
2014-04-16 10:33:07 +04:00
}
2014-04-16 10:33:04 +04:00
}