[PATCH v10 09/16] Add stacktrace filter action

Nikolay Marchuk marchuk.nikolay.a at gmail.com
Mon Aug 28 08:54:46 UTC 2017


* 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.
---
 defs.h          | 8 +++++++-
 filter.h        | 1 +
 filter_action.c | 9 +++++++++
 strace.c        | 4 ++--
 syscall.c       | 6 +++---
 unwind.c        | 6 ++++++
 6 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/defs.h b/defs.h
index 7789e293..a59fe716 100644
--- a/defs.h
+++ b/defs.h
@@ -256,6 +256,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)
 
@@ -269,6 +272,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)
 
@@ -376,7 +382,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 249a2a93..45ad379a 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 fea3e877..8c282b39 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 08cdb2f6..d95e2f2f 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
 
@@ -1693,7 +1693,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 96726497..98801a26 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 919b63c3..caab4143 100644
--- a/unwind.c
+++ b/unwind.c
@@ -589,3 +589,9 @@ unwind_capture_stacktrace(struct tcb *tcp)
 		DPRINTF("tcp=%p, queue=%p", "captured", tcp, tcp->queue->head);
 	}
 }
+
+void
+apply_stacktrace(struct tcb *tcp, void *_priv_data)
+{
+	tcp->qual_flg |= QUAL_STACKTRACE;
+}
-- 
2.11.0





More information about the Strace-devel mailing list