summaryrefslogtreecommitdiffstats
path: root/runtime/task_finder.c
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-09-01 13:46:27 -0400
committerFrank Ch. Eigler <fche@elastic.org>2008-09-01 13:46:27 -0400
commitaa3c05113d831a4e5d58287f9f2f9d605bf8693e (patch)
tree850b215d67d0621fbfb575dc34aca3bf3bc1fa0a /runtime/task_finder.c
parent6f4c12753354d3e0f6b18d6290e1bf89c5084c5c (diff)
parent5e314609f46deb737967305f59356243cb65c310 (diff)
downloadsystemtap-steved-aa3c05113d831a4e5d58287f9f2f9d605bf8693e.tar.gz
systemtap-steved-aa3c05113d831a4e5d58287f9f2f9d605bf8693e.tar.xz
systemtap-steved-aa3c05113d831a4e5d58287f9f2f9d605bf8693e.zip
Merge commit 'origin/master' into pr4225
* commit 'origin/master': Fix memory access error in nfs.proc.read_setup, nfs.proc.write_setup and nfs.proc.commit_setup Update NEWS regarding the systemtap client/server. New man page for the systemtap client/server and related utilities. Repopulate symbol/type info. Pushed quiesce logic down into the task_finder layer. Added bug 6841 fix utrace syscall test. PR6731: improve listing mode to list variables
Diffstat (limited to 'runtime/task_finder.c')
-rw-r--r--runtime/task_finder.c120
1 files changed, 74 insertions, 46 deletions
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index b8a0ae7f..9c0dd55b 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -351,23 +351,41 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
return rc;
}
+/*
+ * All user threads get an engine with __STP_TASK_FINDER_EVENTS events
+ * attached to it so the task_finder layer can monitor new thread
+ * creation/death.
+ */
#define __STP_TASK_FINDER_EVENTS (UTRACE_EVENT(CLONE) \
| UTRACE_EVENT(EXEC) \
| UTRACE_EVENT(DEATH))
-#define __STP_ATTACHED_TASK_BASE_EVENTS (UTRACE_EVENT(DEATH))
-
-#define __STP_ATTACHED_TASK_VM_BASE_EVENTS (__STP_ATTACHED_TASK_BASE_EVENTS \
- | UTRACE_EVENT(SYSCALL_ENTRY) \
- | UTRACE_EVENT(SYSCALL_EXIT))
-
-#define __STP_ATTACHED_TASK_VM_EVENTS (__STP_ATTACHED_TASK_BASE_EVENTS \
- | UTRACE_STOP \
- | UTRACE_EVENT(QUIESCE))
-
-#define __STP_ATTACHED_TASK_EVENTS(tgt) \
- ((((tgt)->vm_callback) == NULL) ? __STP_ATTACHED_TASK_BASE_EVENTS \
- : __STP_ATTACHED_TASK_VM_EVENTS)
+/*
+ * __STP_TASK_BASE_EVENTS: base events for stap_task_finder_target's
+ * without a vm_callback
+ *
+ * __STP_TASK_VM_BASE_EVENTS: base events for
+ * stap_task_finder_target's with a vm_callback
+ */
+#define __STP_TASK_BASE_EVENTS (UTRACE_EVENT(DEATH))
+
+#define __STP_TASK_VM_BASE_EVENTS (__STP_TASK_BASE_EVENTS \
+ | UTRACE_EVENT(SYSCALL_ENTRY)\
+ | UTRACE_EVENT(SYSCALL_EXIT))
+
+/*
+ * All "interesting" threads get an engine with
+ * __STP_ATTACHED_TASK_EVENTS events attached to it. After the thread
+ * quiesces, we reset the events to __STP_ATTACHED_TASK_BASE_EVENTS
+ * events.
+ */
+#define __STP_ATTACHED_TASK_EVENTS (__STP_TASK_BASE_EVENTS \
+ | UTRACE_STOP \
+ | UTRACE_EVENT(QUIESCE))
+
+#define __STP_ATTACHED_TASK_BASE_EVENTS(tgt) \
+ ((((tgt)->vm_callback) == NULL) ? __STP_TASK_BASE_EVENTS \
+ : __STP_TASK_VM_BASE_EVENTS)
static int
stap_utrace_attach(struct task_struct *tsk,
@@ -454,31 +472,40 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk,
if (cb_tgt == NULL)
continue;
- if (cb_tgt->callback != NULL) {
- int rc = cb_tgt->callback(cb_tgt, tsk,
- register_p,
- process_p);
- if (rc != 0) {
- _stp_error("callback for %d failed: %d",
- (int)tsk->pid, rc);
- break;
- }
- }
-
// Set up events we need for attached tasks.
+ // When register_p is set, we won't actually
+ // call the callback here - we'll call it when
+ // the thread gets quiesced. When register_p
+ // isn't set, we can go ahead and call the
+ // callback.
if (register_p) {
rc = stap_utrace_attach(tsk, &cb_tgt->ops,
cb_tgt,
- __STP_ATTACHED_TASK_EVENTS(cb_tgt));
+ __STP_ATTACHED_TASK_EVENTS);
if (rc != 0 && rc != EPERM)
break;
cb_tgt->engine_attached = 1;
}
else {
+ if (cb_tgt->callback != NULL) {
+ rc = cb_tgt->callback(cb_tgt, tsk,
+ register_p,
+ process_p);
+ if (rc != 0) {
+ _stp_error("callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ break;
+ }
+ }
+
rc = stap_utrace_detach(tsk, &cb_tgt->ops);
if (rc != 0)
break;
- cb_tgt->engine_attached = 0;
+
+ // Note that we don't want to set
+ // engine_attached to 0 here - only
+ // when *all* threads using this
+ // engine have been detached.
}
}
}
@@ -695,18 +722,32 @@ __stp_utrace_task_finder_target_quiesce(enum utrace_resume_action action,
struct stap_task_finder_target *tgt = engine->data;
int rc;
- // Turn off quiesce handling (and turn on syscall handling).
- rc = utrace_set_events(tsk, engine, __STP_ATTACHED_TASK_VM_BASE_EVENTS);
+ if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
+ debug_task_finder_detach();
+ return UTRACE_DETACH;
+ }
+
+ if (tgt == NULL)
+ return UTRACE_DETACH;
+
+ // Turn off quiesce handling
+ rc = utrace_set_events(tsk, engine,
+ __STP_ATTACHED_TASK_BASE_EVENTS(tgt));
if (rc != 0)
_stp_error("utrace_set_events returned error %d on pid %d",
rc, (int)tsk->pid);
- if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
- debug_task_finder_detach();
- return UTRACE_DETACH;
+ if (tgt->callback != NULL) {
+ /* Call the callback. Assume that if the thread is a
+ * thread group leader, it is a process. */
+ rc = tgt->callback(tgt, tsk, 1, (tsk->pid == tsk->tgid));
+ if (rc != 0) {
+ _stp_error("callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ }
}
- if (tgt != NULL && tgt->vm_callback != NULL) {
+ if (tgt->vm_callback != NULL) {
struct mm_struct *mm;
char *mmpath_buf;
char *mmpath;
@@ -1159,24 +1200,11 @@ stap_start_task_finder(void)
callback_list);
if (cb_tgt == NULL)
continue;
-
- // Call the callback. Assume that if
- // the thread is a thread group
- // leader, it is a process.
- if (cb_tgt->callback != NULL) {
- rc = cb_tgt->callback(cb_tgt, tsk, 1,
- (tsk->pid == tsk->tgid));
- if (rc != 0) {
- _stp_error("attach callback for %d failed: %d",
- (int)tsk->pid, rc);
- goto stf_err;
- }
- }
// Set up events we need for attached tasks.
rc = stap_utrace_attach(tsk, &cb_tgt->ops,
cb_tgt,
- __STP_ATTACHED_TASK_EVENTS(cb_tgt));
+ __STP_ATTACHED_TASK_EVENTS);
if (rc != 0 && rc != EPERM)
goto stf_err;
cb_tgt->engine_attached = 1;