[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