summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolay Marchuk <marchuk.nikolay.a@gmail.com>2017-08-28 15:09:07 +0700
committerDmitry V. Levin <ldv@altlinux.org>2017-12-21 13:12:36 +0000
commit302f2d16d05cdb39d21c342707a85b48547f5acc (patch)
tree24fcfa578a0cd0fc28eb26abae24d9bdc45c76aa
parent2de045936fb1b6c3069a8d17d45ec6fcb6e7a9ba (diff)
downloadstrace-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.h8
-rw-r--r--filter.h1
-rw-r--r--filter_action.c9
-rw-r--r--strace.c4
-rw-r--r--syscall.c6
-rw-r--r--unwind.c6
6 files changed, 28 insertions, 6 deletions
diff --git a/defs.h b/defs.h
index b54303367..a4447ca05 100644
--- a/defs.h
+++ b/defs.h
@@ -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;
diff --git a/filter.h b/filter.h
index 249a2a93c..45ad379ad 100644
--- a/filter.h
+++ b/filter.h
@@ -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];
diff --git a/strace.c b/strace.c
index 7a262aa96..54c6e5bfb 100644
--- a/strace.c
+++ b/strace.c
@@ -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':
diff --git a/syscall.c b/syscall.c
index 5b33cc1d8..67587eb2e 100644
--- a/syscall.c
+++ b/syscall.c
@@ -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;
diff --git a/unwind.c b/unwind.c
index d37f01695..ec1106050 100644
--- a/unwind.c
+++ b/unwind.c
@@ -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;
+}