diff options
author | Nikolay Marchuk <marchuk.nikolay.a@gmail.com> | 2017-08-28 15:09:07 +0700 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2017-12-21 13:12:36 +0000 |
commit | 302f2d16d05cdb39d21c342707a85b48547f5acc (patch) | |
tree | 24fcfa578a0cd0fc28eb26abae24d9bdc45c76aa | |
parent | 2de045936fb1b6c3069a8d17d45ec6fcb6e7a9ba (diff) | |
download | strace-302f2d16d05cdb39d21c342707a85b48547f5acc.tar.gz |
Add stacktrace filter action
* defs.h (QUAL_STACKTRACE): Add new qual flag.
(stacktrace): Add macro for checking QUAL_STACKTRACE.
(stack_trace_enabled): Change description.
* filter.h (DECL_FILTER_ACTION): Declare stacktrace filter action type.
* filter_action.c (action_types): Add stacktrace filter action type.
(add_action): Update stack_trace_enabled.
* strace.c (stack_trace_enabled): Change description.
(init): Use filtering_parse for -k option.
* syscall.c (syscall_entering_trace, syscall_exiting_decode,
syscall_exiting_trace): Use stacktrace macro instead of
stack_trace_enabled.
* unwind.c (apply_stacktrace): Add filter action function.
-rw-r--r-- | defs.h | 8 | ||||
-rw-r--r-- | filter.h | 1 | ||||
-rw-r--r-- | filter_action.c | 9 | ||||
-rw-r--r-- | strace.c | 4 | ||||
-rw-r--r-- | syscall.c | 6 | ||||
-rw-r--r-- | unwind.c | 6 |
6 files changed, 28 insertions, 6 deletions
@@ -253,6 +253,9 @@ struct tcb { #define QUAL_INJECT 0x010 /* tamper with this system call on purpose */ #define QUAL_READ 0x020 /* dump data read in this syscall */ #define QUAL_WRITE 0x040 /* dump data written in this syscall */ +#ifdef USE_LIBUNWIND +# define QUAL_STACKTRACE 0x080 /* do the stack trace */ +#endif #define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE) @@ -266,6 +269,9 @@ struct tcb { #define dump_write(tcp) ((tcp)->qual_flg & QUAL_WRITE) #define raw(tcp) ((tcp)->qual_flg & QUAL_RAW) #define inject(tcp) ((tcp)->qual_flg & QUAL_INJECT) +#ifdef USE_LIBUNWIND +# define stacktrace(tcp) ((tcp)->qual_flg & QUAL_STACKTRACE) +#endif #define filtered(tcp) ((tcp)->flags & TCB_FILTERED) #define hide_log(tcp) ((tcp)->flags & TCB_HIDE_LOG) @@ -375,7 +381,7 @@ extern struct path_set { extern unsigned xflag; extern unsigned followfork; #ifdef USE_LIBUNWIND -/* if this is true do the stack trace for every system call */ +/* if this is true do the initialization of stack tracing mechanism */ extern bool stack_trace_enabled; #endif extern unsigned ptrace_setoptions; @@ -106,6 +106,7 @@ DECL_FILTER_ACTION(inject); DECL_FILTER_ACTION(fault); DECL_FILTER_ACTION(read); DECL_FILTER_ACTION(write); +DECL_FILTER_ACTION(stacktrace); #undef DECL_FILTER_ACTION #define DECL_FILTER_ACTION_PARSER(name) \ diff --git a/filter_action.c b/filter_action.c index fea3e8775..8c282b39c 100644 --- a/filter_action.c +++ b/filter_action.c @@ -49,6 +49,9 @@ static const struct filter_action_type { FILTER_ACTION_TYPE(verbose, 2, QUAL_VERBOSE, null, is_traced), FILTER_ACTION_TYPE(read, 2, QUAL_READ, null, is_traced), FILTER_ACTION_TYPE(write, 2, QUAL_WRITE, null, is_traced), +# ifdef USE_LIBUNWIND + FILTER_ACTION_TYPE(stacktrace, 2, QUAL_STACKTRACE, null, is_traced), +# endif }; #undef FILTER_ACTION_TYPE @@ -146,6 +149,12 @@ add_action(const struct filter_action_type *type) if (default_flags & type->qual_flg) default_flags &= ~type->qual_flg; + /* Enable stack tracing. */ +#ifdef USE_LIBUNWIND + if (type->qual_flg & QUAL_STACKTRACE) + stack_trace_enabled = true; +#endif + filter_actions = xreallocarray(filter_actions, ++nfilter_actions, sizeof(struct filter_action)); action = &filter_actions[nfilter_actions - 1]; @@ -57,7 +57,7 @@ extern int optind; extern char *optarg; #ifdef USE_LIBUNWIND -/* if this is true do the stack trace for every system call */ +/* if this is true do the initialization of stack tracing mechanism */ bool stack_trace_enabled; #endif @@ -1684,7 +1684,7 @@ init(int argc, char *argv[]) break; #ifdef USE_LIBUNWIND case 'k': - stack_trace_enabled = true; + filtering_parse("stacktrace(syscall all)"); break; #endif case 'E': @@ -683,7 +683,7 @@ syscall_entering_trace(struct tcb *tcp, unsigned int *sig) } #ifdef USE_LIBUNWIND - if (stack_trace_enabled) { + if (stacktrace(tcp)) { if (tcp->s_ent->sys_flags & STACKTRACE_CAPTURE_ON_ENTER) unwind_capture_stacktrace(tcp); } @@ -728,7 +728,7 @@ syscall_exiting_decode(struct tcb *tcp, struct timeval *ptv) gettimeofday(ptv, NULL); #ifdef USE_LIBUNWIND - if (stack_trace_enabled) { + if (stacktrace(tcp)) { if (tcp->s_ent->sys_flags & STACKTRACE_INVALIDATE_CACHE) unwind_cache_invalidate(tcp); } @@ -948,7 +948,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timeval tv, int res) line_ended(); #ifdef USE_LIBUNWIND - if (stack_trace_enabled) + if (stacktrace(tcp)) unwind_print_stacktrace(tcp); #endif return 0; @@ -581,3 +581,9 @@ unwind_capture_stacktrace(struct tcb *tcp) debug_func_msg("tcp=%p, queue=%p", tcp, tcp->queue->head); } } + +void +apply_stacktrace(struct tcb *tcp, void *_priv_data) +{ + tcp->qual_flg |= QUAL_STACKTRACE; +} |