diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-08-11 17:34:47 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-08-11 17:34:47 -0400 |
commit | 42e740602dbb7960e11b0bbf9053e95e8a1cb1e5 (patch) | |
tree | aa32f56c7c5b1838e9d80bec2c15325c71742660 /runtime/task_finder.c | |
parent | 3213d0891c826f16ba727a3e863075e2922666a0 (diff) | |
parent | 79640c29c5bcf8de20f013dcc80e1a9c7a93811f (diff) | |
download | systemtap-steved-42e740602dbb7960e11b0bbf9053e95e8a1cb1e5.tar.gz systemtap-steved-42e740602dbb7960e11b0bbf9053e95e8a1cb1e5.tar.xz systemtap-steved-42e740602dbb7960e11b0bbf9053e95e8a1cb1e5.zip |
Merge commit 'origin/master' into pr4225
* commit 'origin/master': (34 commits)
PR5049: fix overbroad effects of naive "*" prefixing; instead use optional "*/" only.
stap-serverd was incorectly determining that the server could
stapprobes man page: clarify statement(NUM).absolute and process("path") searching
PR5049: prefix with "*" any filenames given in "fn@filename:line" probes
Indentation fix.
Redirect stderr gets redircted so warnings don't let example script run fail.
PR6835. io/io_submit.stp: Fix #! start. Convert to normal line-ending.
PR2895. Add proper #! /usr/bin/env stap line. Make example scripts executable.
Use INSTALL_PROGRAM, not INSTALL_DATA for executable .stp scripts.
example index: only warn if old, do not regenerate
Start/stop the systemtap server from systemtap.exp and not in the top level Makefile.
Lower statement wildcard test matching threshold.
Moved details of utrace detach to stap_utrace_detach().
Saves thread vma information.
Always generate examples indexes and install examples from srcdir.
Refer to srcdir spec file Makefile so make rpm works when builddir != srcdir.
Add index of subsystem and keywords at top of HTML indexes.
Don't output output, exits, status line in indexes (mentioned in descriptions).
Disable chmodding of samples/kmalloc-top in spec file since it isn't installed.
Make sure examples indexes are always generated in builddir.
...
Diffstat (limited to 'runtime/task_finder.c')
-rw-r--r-- | runtime/task_finder.c | 108 |
1 files changed, 77 insertions, 31 deletions
diff --git a/runtime/task_finder.c b/runtime/task_finder.c index a4e18578..541e5a04 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -57,6 +57,15 @@ int __stp_tf_vm_cb(struct task_struct *tsk, _stp_dbug(__FUNCTION__, __LINE__, "vm_cb: tsk %d:%d path %s, start 0x%08lx, end 0x%08lx, offset 0x%lx\n", tsk->pid, map_p, vm_path, vm_start, vm_end, vm_pgoff); + if (map_p) { + // FIXME: What should we do with vm_path? We can't save + // the vm_path pointer itself, but we don't have any + // storage space allocated to save it in... + stap_add_vma_map_info(tsk, vm_start, vm_end, vm_pgoff); + } + else { + stap_remove_vma_map_info(tsk, vm_start, vm_end, vm_pgoff); + } return 0; } #endif @@ -151,12 +160,72 @@ stap_register_task_finder_target(struct stap_task_finder_target *new_tgt) return 0; } +static int +stap_utrace_detach(struct task_struct *tsk, + const struct utrace_engine_ops *ops) +{ + struct utrace_attached_engine *engine; + struct mm_struct *mm; + int rc = 0; + + // Ignore init + if (tsk == NULL || tsk->pid <= 1) + return 0; + + // Notice we're not calling get_task_mm() here. Normally we + // avoid tasks with no mm, because those are kernel threads. + // So, why is this function different? When a thread is in + // the process of dying, its mm gets freed. Then, later the + // thread gets in the dying state and the thread's DEATH event + // handler gets called (if any). + // + // If a thread is in this "mortally wounded" state - no mm + // but not dead - and at that moment this function is called, + // we'd miss detaching from it if we were checking to see if + // it had an mm. + + engine = utrace_attach(tsk, UTRACE_ATTACH_MATCH_OPS, ops, 0); + if (IS_ERR(engine)) { + rc = -PTR_ERR(engine); + if (rc != ENOENT) { + _stp_error("utrace_attach returned error %d on pid %d", + rc, tsk->pid); + } + else { + rc = 0; + } + } + else if (unlikely(engine == NULL)) { + _stp_error("utrace_attach returned NULL on pid %d", + (int)tsk->pid); + rc = EFAULT; + } + else { + rc = utrace_detach(tsk, engine); + switch (rc) { + case 0: /* success */ + debug_task_finder_detach(); + break; + case -ESRCH: /* REAP callback already begun */ + case -EALREADY: /* DEATH callback already begun */ + rc = 0; /* ignore these errors*/ + break; + default: + rc = -rc; + _stp_error("utrace_detach returned error %d on pid %d", + rc, tsk->pid); + break; + } + } + return rc; +} + static void stap_utrace_detach_ops(struct utrace_engine_ops *ops) { struct task_struct *grp, *tsk; struct utrace_attached_engine *engine; - long error = 0; + int rc = 0; pid_t pid = 0; // Notice we're not calling get_task_mm() in this loop. In @@ -174,31 +243,12 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops) rcu_read_lock(); do_each_thread(grp, tsk) { - if (tsk == NULL || tsk->pid <= 1) - continue; - - engine = utrace_attach(tsk, UTRACE_ATTACH_MATCH_OPS, - ops, 0); - if (IS_ERR(engine)) { - error = -PTR_ERR(engine); - if (error != ENOENT) { - pid = tsk->pid; - goto udo_err; - } - error = 0; - } - else if (engine != NULL) { - utrace_detach(tsk, engine); - debug_task_finder_detach(); - } + rc = stap_utrace_detach(tsk, ops); + if (rc != 0) + goto udo_err; } while_each_thread(grp, tsk); udo_err: rcu_read_unlock(); - - if (error != 0) { - _stp_error("utrace_attach returned error %d on pid %d", - error, pid); - } debug_task_finder_report(); } @@ -382,14 +432,10 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk, cb_tgt->engine_attached = 1; } else { - struct utrace_attached_engine *engine; - engine = utrace_attach(tsk, - UTRACE_ATTACH_MATCH_OPS, - &cb_tgt->ops, 0); - if (! IS_ERR(engine) && engine != NULL) { - utrace_detach(tsk, engine); - debug_task_finder_detach(); - } + rc = stap_utrace_detach(tsk, &cb_tgt->ops); + if (rc != 0) + break; + cb_tgt->engine_attached = 0; } } } |