This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Probes don't hit in an already running process


Hi,

I've made the observation that probes sometimes don't hit when I start
staprun after the process (where the probes should hit) started.  After
some tests, I found out that only multi-thread processes were affected
under a certain condition.

The patch below fixes the issue for me. But I've no clue about possible
side effects. In my first attempt to fix the issue, I also included the
calls to __stp_call_callbacks() into the guarded area. My probes hit,
but calls to usymname(uaddr()) in the probe body only printed the
address instead of the symbol of the probed function.

Any advice of how I can improve the patch is appreciated.

Kind Regards,
Torsten

>From d1752f91227fecd66c2f550cfc4309b1509624e5 Mon Sep 17 00:00:00 2001
Message-Id: <d1752f91227fecd66c2f550cfc4309b1509624e5.1394230365.git.Torsten.Polle@gmx.de>
From: Torsten Polle <Torsten.Polle@gmx.de>
Date: Thu, 6 Mar 2014 21:42:19 +0100
Subject: [PATCH] Fix: uprobes don't hit in multi-threaded processes.

If a processes is started before probes are inserted, SystemTap waits
for the main thread of the process to wake-up. Then the hooks for
SystemTap are installed. If the main thread does not wake up, the
hooks are not installed and therefore uprobes don't fire.

Instead of waiting only for the main thread, the task finder waits for
any thread that wakes up. In order to avoid that hooks get installed
multiple times, a protection for mmap callbacks is also realised.

Signed-off-by: Torsten Polle <Torsten.Polle@gmx.de>
---
 runtime/linux/task_finder2.c |   36 +++++++++++++++++++-----------------
 1 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
index 119d04e..e259960 100644
--- a/runtime/linux/task_finder2.c
+++ b/runtime/linux/task_finder2.c
@@ -83,6 +83,8 @@ struct stap_task_finder_target {
 	unsigned mmap_events:1;
 	unsigned munmap_events:1;
 	unsigned mprotect_events:1;
+#define mmap_called  (0 << 0)               /* mmap callbacks called */
+	volatile unsigned long events;
 
 /* public: */
 	pid_t pid;
@@ -243,6 +245,7 @@ stap_register_task_finder_target(struct stap_task_finder_target *new_tgt)
 	new_tgt->mmap_events = 0;
 	new_tgt->munmap_events = 0;
 	new_tgt->mprotect_events = 0;
+	new_tgt->events = 0;
 	memset(&new_tgt->ops, 0, sizeof(new_tgt->ops));
 	new_tgt->ops.report_exec = &__stp_utrace_task_finder_target_exec;
 	new_tgt->ops.report_death = &__stp_utrace_task_finder_target_death;
@@ -1281,16 +1284,16 @@ __stp_tf_quiesce_worker(struct task_work *work)
 
 	__stp_tf_handler_start();
 
-	/* Call the callbacks.  Assume that if the thread is a
-	 * thread group leader, it is a process. */
-	__stp_call_callbacks(tgt, current, 1, (current->pid == current->tgid));
- 
-	/* If this is just a thread other than the thread group
-	 * leader, don't bother inform map callback clients about its
-	 * memory map, since they will simply duplicate each other. */
-	if (tgt->mmap_events == 1 && current->tgid == current->pid) {
+	/* Call the callbacks for each thread. */
+	__stp_call_callbacks(tgt, current, 1, 1);
+
+	/* Call the callbacks just once for each process. */
+	if (test_and_set_bit(mmap_called, &tgt->events))
+	{
+		if (tgt->mmap_events == 1) {
 	    __stp_call_mmap_callbacks_for_task(tgt, current);
 	}
+	}
 
 	__stp_tf_handler_end();
 
@@ -1368,16 +1371,15 @@ __stp_utrace_task_finder_target_quiesce(u32 action,
 		}
 	}
 	else {
-		/* Call the callbacks.  Assume that if the thread is a
-		 * thread group leader, it is a process. */
-		__stp_call_callbacks(tgt, tsk, 1, (tsk->pid == tsk->tgid));
- 
-		/* If this is just a thread other than the thread
-		   group leader, don't bother inform map callback
-		   clients about its memory map, since they will
-		   simply duplicate each other. */
-		if (tgt->mmap_events == 1 && tsk->tgid == tsk->pid) {
+		/* Call the callbacks for each thread. */
+		__stp_call_callbacks(tgt, tsk, 1, 1);
+
+		/* Call the callbacks just once for each process. */
+		if (test_and_set_bit(mmap_called, &tgt->events))
+		{
+			if (tgt->mmap_events == 1) {
 			__stp_call_mmap_callbacks_for_task(tgt, tsk);
+			}
 		}
 	}
 
-- 
1.7.4.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]