[PATCH v4 2/5] drm: Add private data field to trace control block

Patrik Jakobsson patrik.jakobsson at linux.intel.com
Mon Aug 24 12:42:47 UTC 2015


We need to be able to store private data in the tcb across it's
lifetime. To ensure proper destruction of the data a free_priv_data
callback must be provided if an allocation is stored in priv_data. The
callback is executed automatically when the life of the tcb ends.

* defs.h: Add extern declaration of free_tcb_priv_data.
 (struct tcb): Add priv_data and free_priv_data.
* strace.c (free_tcb_priv_data): New function
(drop_tcb): Execute free_tcb_priv_data callback
* syscall.c (trace_syscall_exiting): Execute free_tcb_priv_data callback

Signed-off-by: Patrik Jakobsson <patrik.jakobsson at linux.intel.com>
---
 defs.h    |  6 ++++++
 strace.c  | 14 ++++++++++++++
 syscall.c |  1 +
 3 files changed, 21 insertions(+)

diff --git a/defs.h b/defs.h
index 9059026..bc3bd83 100644
--- a/defs.h
+++ b/defs.h
@@ -266,6 +266,10 @@ struct tcb {
 	int u_error;		/* Error code */
 	long scno;		/* System call number */
 	long u_arg[MAX_ARGS];	/* System call arguments */
+
+	void *priv_data;	/* Private data for syscall decoding functions */
+	void (*free_priv_data)(void *); /* Callback for freeing priv_data */
+
 #if defined(LINUX_MIPSN32) || defined(X32)
 	long long ext_arg[MAX_ARGS];
 	long long u_lrval;	/* long long return value */
@@ -470,6 +474,8 @@ extern void get_regs(pid_t pid);
 extern int get_scno(struct tcb *tcp);
 extern const char *syscall_name(long scno);
 
+extern void free_tcb_priv_data(struct tcb *tcp);
+
 extern int umoven(struct tcb *, long, unsigned int, void *);
 #define umove(pid, addr, objp)	\
 	umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))
diff --git a/strace.c b/strace.c
index 9b93e79..7a71152 100644
--- a/strace.c
+++ b/strace.c
@@ -711,12 +711,26 @@ alloctcb(int pid)
 	error_msg_and_die("bug in alloctcb");
 }
 
+void
+free_tcb_priv_data(struct tcb *tcp)
+{
+	if (tcp->priv_data) {
+		if (tcp->free_priv_data) {
+			tcp->free_priv_data(tcp->priv_data);
+			tcp->free_priv_data = NULL;
+		}
+		tcp->priv_data = NULL;
+	}
+}
+
 static void
 droptcb(struct tcb *tcp)
 {
 	if (tcp->pid == 0)
 		return;
 
+	free_tcb_priv_data(tcp);
+
 #ifdef USE_LIBUNWIND
 	if (stack_trace_enabled) {
 		unwind_tcb_fin(tcp);
diff --git a/syscall.c b/syscall.c
index 396a7dd..39b973b 100644
--- a/syscall.c
+++ b/syscall.c
@@ -1099,6 +1099,7 @@ trace_syscall_exiting(struct tcb *tcp)
 #endif
 
  ret:
+	free_tcb_priv_data(tcp);
 	tcp->flags &= ~TCB_INSYSCALL;
 	tcp->sys_func_rval = 0;
 	return 0;
-- 
2.1.4





More information about the Strace-devel mailing list