summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/task_finder.c22
-rw-r--r--runtime/task_finder_vma.c30
-rw-r--r--tapsets.cxx4
3 files changed, 45 insertions, 11 deletions
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index 9db713c3..ae381a41 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -55,7 +55,6 @@ typedef int (*stap_task_finder_vm_callback)(struct stap_task_finder_target *tgt,
unsigned long vm_end,
unsigned long vm_pgoff);
-#ifdef DEBUG_TASK_FINDER_VMA
static int __stp_tf_vm_cb(struct stap_task_finder_target *tgt,
struct task_struct *tsk,
int map_p, char *vm_path,
@@ -63,21 +62,32 @@ static int __stp_tf_vm_cb(struct stap_task_finder_target *tgt,
unsigned long vm_end,
unsigned long vm_pgoff)
{
+ int i;
+#ifdef DEBUG_TASK_FINDER_VMA
_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);
+#endif
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);
+ struct _stp_module *module = NULL;
+ if (vm_path != NULL)
+ for (i = 0; i < _stp_num_modules; i++)
+ if (strcmp(vm_path, _stp_modules[i]->name) == 0)
+ {
+#ifdef DEBUG_TASK_FINDER_VMA
+ _stp_dbug(__FUNCTION__, __LINE__,
+ "vm_cb: matched path %s to module\n", vm_path);
+#endif
+ module = _stp_modules[i];
+ break;
+ }
+ stap_add_vma_map_info(tsk, vm_start, vm_end, vm_pgoff, module);
}
else {
stap_remove_vma_map_info(tsk, vm_start, vm_end, vm_pgoff);
}
return 0;
}
-#endif
struct stap_task_finder_target {
/* private: */
diff --git a/runtime/task_finder_vma.c b/runtime/task_finder_vma.c
index 4dce4be8..87a32fe5 100644
--- a/runtime/task_finder_vma.c
+++ b/runtime/task_finder_vma.c
@@ -25,6 +25,9 @@ struct __stp_tf_vma_entry {
unsigned long vm_end;
unsigned long vm_pgoff;
// Is that enough? Should we store a dcookie for vm_file?
+
+ // Module that this vma entry is mapped from, if any.
+ struct _stp_module *module;
};
static struct __stp_tf_vma_entry
@@ -211,7 +214,8 @@ __stp_tf_get_vma_map_entry_internal(struct task_struct *tsk,
// Add the vma info to the vma map hash table.
static int
stap_add_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
- unsigned long vm_end, unsigned long vm_pgoff)
+ unsigned long vm_end, unsigned long vm_pgoff,
+ struct _stp_module *module)
{
struct hlist_head *head;
struct hlist_node *node;
@@ -242,6 +246,7 @@ stap_add_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
entry->vm_start = vm_start;
entry->vm_end = vm_end;
entry->vm_pgoff = vm_pgoff;
+ entry->module = module;
head = &__stp_tf_vma_map[__stp_tf_vma_map_hash(tsk)];
hlist_add_head(&entry->hlist, head);
@@ -305,3 +310,26 @@ stap_find_vma_map_info(struct task_struct *tsk, unsigned long vm_addr,
mutex_unlock(&__stp_tf_vma_mutex);
return rc;
}
+
+// Get vma_entry of the address (vm_start/vm_end) if the vma is
+// present in the vma hash table containing.
+// Returns NULL if not present.
+static struct __stp_tf_vma_entry *
+__stp_tf_get_vma_entry_addr(struct task_struct *tsk, unsigned long addr)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct __stp_tf_vma_entry *entry;
+
+ mutex_lock(&__stp_tf_vma_mutex);
+ head = &__stp_tf_vma_map[__stp_tf_vma_map_hash(tsk)];
+ hlist_for_each_entry(entry, node, head, hlist) {
+ if (tsk->pid == entry->pid
+ && addr >= entry->vm_start && addr < entry->vm_end) {
+ mutex_unlock(&__stp_tf_vma_mutex);
+ return entry;
+ }
+ }
+ mutex_unlock(&__stp_tf_vma_mutex);
+ return NULL;
+}
diff --git a/tapsets.cxx b/tapsets.cxx
index b02e2cce..6efcb3af 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -7172,10 +7172,8 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
// Emit a "fake" probe decl that is really a hook for to get
// our vm_callback called.
string path = it->first;
- s.op->newline() << "#ifdef DEBUG_TASK_FINDER_VMA";
emit_vm_callback_probe_decl (s, true, path, (int64_t)0,
"__stp_tf_vm_cb");
- s.op->newline() << "#endif";
for (unsigned i = 0; i < it->second.size(); i++)
{
@@ -7193,10 +7191,8 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
{
// Emit a "fake" probe decl that is really a hook for to get
// our vm_callback called.
- s.op->newline() << "#ifdef DEBUG_TASK_FINDER_VMA";
emit_vm_callback_probe_decl (s, false, "", it->first,
"__stp_tf_vm_cb");
- s.op->newline() << "#endif";
for (unsigned i = 0; i < it->second.size(); i++)
{