diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-09-01 13:46:27 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-09-01 13:46:27 -0400 |
commit | aa3c05113d831a4e5d58287f9f2f9d605bf8693e (patch) | |
tree | 850b215d67d0621fbfb575dc34aca3bf3bc1fa0a /runtime/task_finder.c | |
parent | 6f4c12753354d3e0f6b18d6290e1bf89c5084c5c (diff) | |
parent | 5e314609f46deb737967305f59356243cb65c310 (diff) | |
download | systemtap-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.c | 120 |
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; |