summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-03-17 16:58:35 +0100
committerMark Wielaard <mjw@redhat.com>2009-03-17 16:58:35 +0100
commitbf33ee46c8fff4d181b7f28521f12175bd32ec77 (patch)
tree5e0a9e1047af60389eee36da54182b52d3d53ee7 /runtime
parent524c6f82b0a3c010d0fd6a67b1afcfbf55b789a6 (diff)
parent30cb532a560ed152b86506b80490e99195970271 (diff)
downloadsystemtap-steved-bf33ee46c8fff4d181b7f28521f12175bd32ec77.tar.gz
systemtap-steved-bf33ee46c8fff4d181b7f28521f12175bd32ec77.tar.xz
systemtap-steved-bf33ee46c8fff4d181b7f28521f12175bd32ec77.zip
Merge branch 'master' into pr6866
Resolved conflicts: runtime/task_finder.c: name vs path.
Diffstat (limited to 'runtime')
-rw-r--r--runtime/alloc.c25
-rw-r--r--runtime/autoconf-alloc-percpu-align.c6
-rw-r--r--runtime/autoconf-save-stack-trace.c22
-rw-r--r--runtime/itrace.c146
-rw-r--r--runtime/loc2c-runtime.h25
-rw-r--r--runtime/sduprobes.c61
-rw-r--r--runtime/stack-i386.c2
-rw-r--r--runtime/stack-x86_64.c2
-rw-r--r--runtime/stack.c7
-rw-r--r--runtime/staprun/mainloop.c8
-rw-r--r--runtime/sym.h1
-rw-r--r--runtime/task_finder.c2
-rw-r--r--runtime/time.c8
-rw-r--r--runtime/transport/control.c7
-rw-r--r--runtime/transport/debugfs.c2
-rw-r--r--runtime/transport/relayfs.h1
-rw-r--r--runtime/transport/transport.c26
-rw-r--r--runtime/transport/transport_msgs.h8
18 files changed, 210 insertions, 149 deletions
diff --git a/runtime/alloc.c b/runtime/alloc.c
index 89d16612..439e8a7e 100644
--- a/runtime/alloc.c
+++ b/runtime/alloc.c
@@ -233,30 +233,14 @@ static void *_stp_vmalloc(unsigned long size)
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
static void *_stp_alloc_percpu(size_t size)
{
-#ifdef DEBUG_MEM
+#ifdef STAPCONF_ALLOC_PERCPU_ALIGN
void *ret = __alloc_percpu(size, 8);
- if (likely(ret)) {
- struct _stp_mem_entry *m = kmalloc(sizeof(struct _stp_mem_entry), STP_ALLOC_FLAGS);
- if (unlikely(m == NULL)) {
- free_percpu(ret);
- return NULL;
- }
- _stp_mem_debug_percpu(m, ret, size);
- _stp_allocated_memory += size * num_online_cpus();
- }
- return ret;
#else
- return __alloc_percpu(size, 8);
+ void *ret = __alloc_percpu(size);
#endif
-}
-#else
-static void *_stp_alloc_percpu(size_t size)
-{
#ifdef DEBUG_MEM
- void *ret = __alloc_percpu(size);
if (likely(ret)) {
struct _stp_mem_entry *m = kmalloc(sizeof(struct _stp_mem_entry), STP_ALLOC_FLAGS);
if (unlikely(m == NULL)) {
@@ -266,12 +250,9 @@ static void *_stp_alloc_percpu(size_t size)
_stp_mem_debug_percpu(m, ret, size);
_stp_allocated_memory += size * num_online_cpus();
}
- return ret;
-#else
- return __alloc_percpu(size);
#endif
+ return ret;
}
-#endif /* LINUX_VERSION_CODE */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
#define _stp_kmalloc_node(size,node) _stp_kmalloc(size)
diff --git a/runtime/autoconf-alloc-percpu-align.c b/runtime/autoconf-alloc-percpu-align.c
new file mode 100644
index 00000000..158d579c
--- /dev/null
+++ b/runtime/autoconf-alloc-percpu-align.c
@@ -0,0 +1,6 @@
+#include <linux/percpu.h>
+
+/* kernel commit f2a8205c */
+void foo (void) {
+ (void) __alloc_percpu(sizeof(int), 8);
+}
diff --git a/runtime/autoconf-save-stack-trace.c b/runtime/autoconf-save-stack-trace.c
new file mode 100644
index 00000000..39ded684
--- /dev/null
+++ b/runtime/autoconf-save-stack-trace.c
@@ -0,0 +1,22 @@
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <asm/stacktrace.h>
+
+void foo(struct task_struct *foo)
+{
+ struct stack_trace trace;
+ unsigned long backtrace[20];
+ memset(&trace, 0, sizeof(trace));
+ trace.entries = &backtrace[0];
+ trace.max_entries = 20;
+ trace.skip = 0;
+ save_stack_trace_tsk(tsk, &trace);
+}
+
+static const struct stacktrace_ops print_stack_ops;
+
+void dumper(struct task_struct *foo)
+{
+ dump_trace(foo, 0, 0, 0, &print_stack_ops, 0);
+}
diff --git a/runtime/itrace.c b/runtime/itrace.c
index df18a400..ed32b0bc 100644
--- a/runtime/itrace.c
+++ b/runtime/itrace.c
@@ -1,6 +1,6 @@
/*
* user space instruction tracing
- * Copyright (C) 2005, 2006, 2007, 2008 IBM Corp.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 IBM Corp.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
@@ -18,8 +18,6 @@
#include <linux/rcupdate.h>
#include <linux/utrace.h>
#include <asm/string.h>
-#include <asm/tracehook.h>
-#include <asm/ptrace.h>
#include "uprobes/uprobes.h"
#ifndef put_task_struct
@@ -65,10 +63,81 @@ static struct itrace_info *create_itrace_info(
struct task_struct *tsk, u32 step_flag,
struct stap_itrace_probe *itrace_probe);
-static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine,
+/*
+ * The kernel's access_process_vm is not exported in kernel.org kernels, although
+ * some distros export it on some architectures. To workaround this inconsistency,
+ * we copied and pasted it here. Fortunately, everything it calls is exported.
+ */
+#include <linux/pagemap.h>
+#include <asm/cacheflush.h>
+static int __access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+ struct page *page;
+ void *old_buf = buf;
+
+ mm = get_task_mm(tsk);
+ if (!mm)
+ return 0;
+
+ down_read(&mm->mmap_sem);
+ /* ignore errors, just check how much was sucessfully transfered */
+ while (len) {
+ int bytes, ret, offset;
+ void *maddr;
+
+ ret = get_user_pages(tsk, mm, addr, 1,
+ write, 1, &page, &vma);
+ if (ret <= 0)
+ break;
+
+ bytes = len;
+ offset = addr & (PAGE_SIZE-1);
+ if (bytes > PAGE_SIZE-offset)
+ bytes = PAGE_SIZE-offset;
+
+ maddr = kmap(page);
+ if (write) {
+ copy_to_user_page(vma, page, addr,
+ maddr + offset, buf, bytes);
+ set_page_dirty_lock(page);
+ } else {
+ copy_from_user_page(vma, page, addr,
+ buf, maddr + offset, bytes);
+ }
+ kunmap(page);
+ page_cache_release(page);
+ len -= bytes;
+ buf += bytes;
+ addr += bytes;
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm);
+
+ return buf - old_buf;
+}
+
+static u32 usr_itrace_report_quiesce(enum utrace_resume_action action,
+ struct utrace_attached_engine *engine,
+ struct task_struct *tsk,
+ unsigned long event)
+{
+ int status;
+ struct itrace_info *ui;
+
+ ui = rcu_dereference(engine->data);
+ WARN_ON(!ui);
+
+ return (event == 0 ? ui->step_flag : UTRACE_RESUME);
+}
+
+
+static u32 usr_itrace_report_signal(u32 action,
+ struct utrace_attached_engine *engine,
struct task_struct *tsk,
struct pt_regs *regs,
- u32 action, siginfo_t *info,
+ siginfo_t *info,
const struct k_sigaction *orig_ka,
struct k_sigaction *return_ka)
{
@@ -83,12 +152,10 @@ static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine,
WARN_ON(!ui);
if (info->si_signo != SIGTRAP || !ui)
- return UTRACE_ACTION_RESUME;
-
- /* normal case: continue stepping, hide this trap from other engines */
- return_flags = ui->step_flag | UTRACE_ACTION_HIDE | UTRACE_SIGNAL_IGN |
- UTRACE_ACTION_NEWSTATE;
+ return UTRACE_RESUME;
+ /* normal case: continue stepping */
+ return_flags = ui->step_flag | UTRACE_SIGNAL_IGN;
#ifdef CONFIG_PPC
if (ui->ppc_atomic_ss.step_over_atomic) {
remove_atomic_ss_breakpoint(tsk, &ui->ppc_atomic_ss.end_bpt);
@@ -99,8 +166,7 @@ static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine,
}
if (handle_ppc_atomic_seq(tsk, regs, &ui->ppc_atomic_ss))
- return_flags = UTRACE_ACTION_RESUME | UTRACE_ACTION_NEWSTATE |
- UTRACE_SIGNAL_IGN;
+ return_flags = UTRACE_RESUME | UTRACE_SIGNAL_IGN;
#endif
enter_itrace_probe(ui->itrace_probe, regs, (void *)&data);
@@ -108,24 +174,26 @@ static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine,
return return_flags;
}
-static u32 usr_itrace_report_clone(struct utrace_attached_engine *engine,
+static u32 usr_itrace_report_clone(enum utrace_resume_action action,
+ struct utrace_attached_engine *engine,
struct task_struct *parent, unsigned long clone_flags,
struct task_struct *child)
{
- return UTRACE_ACTION_RESUME;
+ return UTRACE_RESUME;
}
static u32 usr_itrace_report_death(struct utrace_attached_engine *e,
- struct task_struct *tsk)
+ struct task_struct *tsk, bool group_dead, int signal)
{
struct itrace_info *ui = rcu_dereference(e->data);
WARN_ON(!ui);
- return (UTRACE_ACTION_NEWSTATE | UTRACE_ACTION_DETACH);
+ return (UTRACE_DETACH);
}
static const struct utrace_engine_ops utrace_ops =
{
+ .report_quiesce = usr_itrace_report_quiesce,
.report_signal = usr_itrace_report_signal,
.report_clone = usr_itrace_report_clone,
.report_death = usr_itrace_report_death
@@ -137,6 +205,7 @@ static struct itrace_info *create_itrace_info(
struct stap_itrace_probe *itrace_probe)
{
struct itrace_info *ui;
+ int status;
if (debug)
printk(KERN_INFO "create_itrace_info: tid=%d\n", tsk->pid);
@@ -154,20 +223,34 @@ static struct itrace_info *create_itrace_info(
/* push ui onto usr_itrace_info */
spin_lock(&itrace_lock);
list_add(&ui->link, &usr_itrace_info);
+ spin_unlock(&itrace_lock);
/* attach a single stepping engine */
- ui->engine = utrace_attach(ui->tsk, UTRACE_ATTACH_CREATE, &utrace_ops, ui);
+ ui->engine = utrace_attach_task(ui->tsk, UTRACE_ATTACH_CREATE, &utrace_ops, ui);
if (IS_ERR(ui->engine)) {
printk(KERN_ERR "utrace_attach returns %ld\n",
PTR_ERR(ui->engine));
- ui = NULL;
- } else {
- utrace_set_flags(tsk, ui->engine, ui->engine->flags |
- ui->step_flag |
- UTRACE_EVENT(CLONE) | UTRACE_EVENT_SIGNAL_ALL |
- UTRACE_EVENT(DEATH));
+ return NULL;
}
- spin_unlock(&itrace_lock);
+ status = utrace_set_events(tsk, ui->engine, ui->engine->flags |
+ UTRACE_EVENT(QUIESCE) |
+ UTRACE_EVENT(CLONE) | UTRACE_EVENT_SIGNAL_ALL |
+ UTRACE_EVENT(DEATH));
+ if (status < 0) {
+ printk(KERN_ERR "utrace_attach returns %d\n", status);
+ return NULL;
+ }
+
+ status = utrace_control(tsk, ui->engine, UTRACE_STOP);
+ if (status == 0) {
+ status = utrace_control(tsk, ui->engine, step_flag);
+ if (status < 0) {
+ printk(KERN_ERR "utrace_control(%d) returns %d\n",
+ step_flag, status);
+ return NULL;
+ }
+ }
+
return ui;
}
@@ -193,7 +276,7 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe
struct task_struct *tsk;
rcu_read_lock();
- tsk = find_task_by_pid(tid);
+ tsk = find_task_by_vpid(tid);
if (!tsk) {
printk(KERN_ERR "usr_itrace_init: Cannot find process %d\n", tid);
rcu_read_unlock();
@@ -203,7 +286,7 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe
get_task_struct(tsk);
ui = create_itrace_info(tsk,
(single_step ?
- UTRACE_ACTION_SINGLESTEP : UTRACE_ACTION_BLOCKSTEP), p);
+ UTRACE_SINGLESTEP : UTRACE_BLOCKSTEP), p);
if (!ui)
return 1;
@@ -223,6 +306,7 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe
void static remove_usr_itrace_info(struct itrace_info *ui)
{
struct itrace_info *tmp;
+ int status;
if (!ui)
return;
@@ -232,7 +316,11 @@ void static remove_usr_itrace_info(struct itrace_info *ui)
spin_lock(&itrace_lock);
if (ui->tsk && ui->engine) {
- (void) utrace_detach(ui->tsk, ui->engine);
+ status = utrace_control(ui->tsk, ui->engine, UTRACE_DETACH);
+ if (status < 0 && status != -ESRCH && status != -EALREADY)
+ printk(KERN_ERR
+ "utrace_control(UTRACE_DETACH) returns %d\n",
+ status);
}
list_del(&ui->link);
spin_unlock(&itrace_lock);
@@ -292,7 +380,7 @@ static void insert_atomic_ss_breakpoint (struct task_struct *tsk,
cur_instr = get_instr(bpt->addr, "insert_atomic_ss_breakpoint");
if (cur_instr != BPT_TRAP) {
bpt->instr = cur_instr;
- WARN_ON(access_process_vm(tsk, bpt->addr, &bp_instr, INSTR_SZ, 1) !=
+ WARN_ON(__access_process_vm(tsk, bpt->addr, &bp_instr, INSTR_SZ, 1) !=
INSTR_SZ);
}
}
@@ -300,7 +388,7 @@ static void insert_atomic_ss_breakpoint (struct task_struct *tsk,
static void remove_atomic_ss_breakpoint (struct task_struct *tsk,
struct bpt_info *bpt)
{
- WARN_ON(access_process_vm(tsk, bpt->addr, &bpt->instr, INSTR_SZ, 1) !=
+ WARN_ON(__access_process_vm(tsk, bpt->addr, &bpt->instr, INSTR_SZ, 1) !=
INSTR_SZ);
}
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 0af19edc..16ddb950 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -186,37 +186,34 @@
*/
#define kread(ptr) ({ \
- typeof(*(ptr)) _v; \
- if (probe_kernel_read((void *)&_v, (void *)(ptr), sizeof(*(ptr)))) \
- DEREF_FAULT(ptr); \
+ typeof(*(ptr)) _v = 0; \
+ if (lookup_bad_addr((unsigned long)(ptr)) || \
+ probe_kernel_read((void *)&_v, (void *)(ptr), sizeof(*(ptr)))) \
+ DEREF_FAULT(ptr); \
_v; \
})
#define kwrite(ptr, value) ({ \
typeof(*(ptr)) _v; \
_v = (typeof(*(ptr)))(value); \
- if (probe_kernel_write((void *)(ptr), (void *)&_v, sizeof(*(ptr)))) \
- STORE_DEREF_FAULT(ptr); \
+ if (lookup_bad_addr((unsigned long)addr) || \
+ probe_kernel_write((void *)(ptr), (void *)&_v, sizeof(*(ptr)))) \
+ STORE_DEREF_FAULT(ptr); \
})
#define deref(size, addr) ({ \
- intptr_t _i; \
- if (lookup_bad_addr((unsigned long)addr)) \
- __deref_bad(); \
+ intptr_t _i = 0; \
switch (size) { \
case 1: _i = kread((u8 *)(addr)); break; \
case 2: _i = kread((u16 *)(addr)); break; \
case 4: _i = kread((u32 *)(addr)); break; \
case 8: _i = kread((u64 *)(addr)); break; \
default: __deref_bad(); \
- /* uninitialized _i should also be caught by -Werror */ \
} \
_i; \
})
#define store_deref(size, addr, value) ({ \
- if (lookup_bad_addr((unsigned long)addr)) \
- __store_deref_bad(); \
switch (size) { \
case 1: kwrite((u8 *)(addr), (value)); break; \
case 2: kwrite((u16 *)(addr), (value)); break; \
@@ -237,7 +234,7 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
u8 _b; u16 _w; u32 _l; \
- intptr_t _v; \
+ intptr_t _v = 0; \
if (lookup_bad_addr((unsigned long)addr)) \
_bad = 1; \
else \
@@ -277,7 +274,7 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
u8 _b; u16 _w; u32 _l; u64 _q; \
- intptr_t _v; \
+ intptr_t _v = 0; \
if (lookup_bad_addr((unsigned long)addr)) \
_bad = 1; \
else \
@@ -394,7 +391,7 @@ extern void __store_deref_bad(void);
#define deref(size, addr) \
({ \
int _bad = 0; \
- intptr_t _v; \
+ intptr_t _v = 0; \
if (lookup_bad_addr((unsigned long)addr)) \
_bad = 1; \
else \
diff --git a/runtime/sduprobes.c b/runtime/sduprobes.c
deleted file mode 100644
index 83bc8e72..00000000
--- a/runtime/sduprobes.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2005-2008 Red Hat Inc.
-// Copyright (C) 2006 Intel Corporation.
-//
-// This file is part of systemtap, and is free software. You can
-// redistribute it and/or modify it under the terms of the GNU General
-// Public License (GPL); either version 2, or (at your option) any
-// later version.
-
-#include <stddef.h>
-#define unused __attribute__ ((unused))
-
-int
-_stap_probe_0 (char* probe unused)
-{
- return 1;
-}
-
-int
-_stap_probe_1 (char* probe unused,
- size_t arg1 unused)
-{
- return 1;
-}
-
-int
-_stap_probe_2 (char* probe unused ,
- size_t arg1 unused,
- size_t arg2 unused)
-{
- return 1;
-}
-
-int
-_stap_probe_3 (char* probe unused,
- size_t arg1 unused,
- size_t arg2 unused,
- size_t arg3 unused)
-{
- return 1;
-}
-
-int
-_stap_probe_4 (char* probe unused,
- size_t arg1 unused,
- size_t arg2 unused,
- size_t arg3 unused,
- size_t arg4 unused)
-{
- return 1;
-}
-
-int
-_stap_probe_5 (char* probe unused,
- size_t arg1 unused,
- size_t arg2 unused,
- size_t arg3 unused,
- size_t arg4 unused,
- size_t arg5 unused)
-{
- return 1;
-}
diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c
index 206801d8..5a18c9d8 100644
--- a/runtime/stack-i386.c
+++ b/runtime/stack-i386.c
@@ -14,7 +14,7 @@ static int _stp_valid_stack_ptr(unsigned long context, unsigned long p)
}
/* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */
-#if ! (defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+#if !defined(STAPCONF_KERNEL_STACKTRACE)
static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels)
{
unsigned long addr;
diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c
index 183de0a0..03d88ef0 100644
--- a/runtime/stack-x86_64.c
+++ b/runtime/stack-x86_64.c
@@ -10,7 +10,7 @@
/* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */
-#if ! (defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+#if !defined(STAPCONF_KERNEL_STACKTRACE)
static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels)
{
unsigned long addr;
diff --git a/runtime/stack.c b/runtime/stack.c
index aa0e6d65..f6b1cd08 100644
--- a/runtime/stack.c
+++ b/runtime/stack.c
@@ -27,8 +27,7 @@
#define MAXBACKTRACE 20
-#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)
-// XXX: PR9866: hacky temporarily restriction to recent kernels
+#if defined(STAPCONF_KERNEL_STACKTRACE)
#include <linux/stacktrace.h>
#include <asm/stacktrace.h>
#endif
@@ -51,7 +50,7 @@ static void _stp_stack_print_fallback(unsigned long, int, int);
#error "Unsupported architecture"
#endif
-#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)
+#if defined(STAPCONF_KERNEL_STACKTRACE)
struct print_stack_data
{
@@ -161,7 +160,7 @@ static void _stp_ustack_print(char *str)
void _stp_stack_print_tsk(struct task_struct *tsk, int verbose, int levels)
{
-#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)
+#if defined(STAPCONF_KERNEL_STACKTRACE)
int i;
unsigned long backtrace[MAXBACKTRACE];
struct stack_trace trace;
diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c
index 29eb4f1f..db6ef6b7 100644
--- a/runtime/staprun/mainloop.c
+++ b/runtime/staprun/mainloop.c
@@ -477,6 +477,14 @@ int stp_main_loop(void)
cleanup_and_exit(0);
break;
}
+ case STP_REQUEST_EXIT:
+ {
+ /* module asks us to start exiting, so send STP_EXIT */
+ dbug(2, "got STP_REQUEST_EXIT\n");
+ int32_t rc, btype = STP_EXIT;
+ rc = write(control_channel, &btype, sizeof(btype));
+ break;
+ }
case STP_START:
{
struct _stp_msg_start *t = (struct _stp_msg_start *)data;
diff --git a/runtime/sym.h b/runtime/sym.h
index e642cab4..586b10ca 100644
--- a/runtime/sym.h
+++ b/runtime/sym.h
@@ -25,6 +25,7 @@ struct _stp_section {
struct _stp_module {
const char* name;
+ const char* path; /* canonical path used for runtime matching. */
struct _stp_section *sections;
unsigned num_sections;
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index ae381a41..38f9145d 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -72,7 +72,7 @@ static int __stp_tf_vm_cb(struct stap_task_finder_target *tgt,
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)
+ if (strcmp(vm_path, _stp_modules[i]->path) == 0)
{
#ifdef DEBUG_TASK_FINDER_VMA
_stp_dbug(__FUNCTION__, __LINE__,
diff --git a/runtime/time.c b/runtime/time.c
index ad7cef9d..58c23e57 100644
--- a/runtime/time.c
+++ b/runtime/time.c
@@ -223,6 +223,7 @@ _stp_kill_time(void)
#endif
_stp_free_percpu(stp_time);
+ stp_time = NULL;
}
}
@@ -232,6 +233,8 @@ _stp_init_time(void)
{
int ret = 0;
+ _stp_kill_time();
+
stp_time = _stp_alloc_percpu(sizeof(stp_time_t));
if (unlikely(stp_time == 0))
return -1;
@@ -263,7 +266,7 @@ _stp_init_time(void)
}
}
#endif
- if (ret)
+ if (ret)
_stp_kill_time();
return ret;
}
@@ -278,6 +281,9 @@ _stp_gettimeofday_ns(void)
stp_time_t *time;
int i = 0;
+ if (!stp_time)
+ return -1;
+
preempt_disable();
time = per_cpu_ptr(stp_time, smp_processor_id());
diff --git a/runtime/transport/control.c b/runtime/transport/control.c
index edde244d..680d7306 100644
--- a/runtime/transport/control.c
+++ b/runtime/transport/control.c
@@ -13,6 +13,8 @@ static _stp_mempool_t *_stp_pool_q;
static struct list_head _stp_ctl_ready_q;
static DEFINE_SPINLOCK(_stp_ctl_ready_lock);
+static void _stp_cleanup_and_exit(int send_exit);
+
static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
u32 type;
@@ -46,7 +48,7 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz
}
break;
case STP_EXIT:
- _stp_exit_flag = 1;
+ _stp_cleanup_and_exit(1);
break;
case STP_BULK:
#ifdef STP_BULKMODE
@@ -93,6 +95,9 @@ static void _stp_ctl_write_dbug(int type, void *data, int len)
case STP_TRANSPORT:
_dbug("sending STP_TRANSPORT\n");
break;
+ case STP_REQUEST_EXIT:
+ _dbug("sending STP_REQUEST_EXIT\n");
+ break;
default:
_dbug("ERROR: unknown message type: %d\n", type);
break;
diff --git a/runtime/transport/debugfs.c b/runtime/transport/debugfs.c
index dc651a56..85ee604d 100644
--- a/runtime/transport/debugfs.c
+++ b/runtime/transport/debugfs.c
@@ -9,6 +9,8 @@
* later version.
*/
+#include <linux/debugfs.h>
+
#define STP_DEFAULT_BUFFERS 50
inline static int _stp_ctl_write_fs(int type, void *data, unsigned len)
diff --git a/runtime/transport/relayfs.h b/runtime/transport/relayfs.h
index c33e9b08..e984b05b 100644
--- a/runtime/transport/relayfs.h
+++ b/runtime/transport/relayfs.h
@@ -9,7 +9,6 @@
# include <linux/relayfs_fs.h>
#elif defined (CONFIG_RELAY)
# include <linux/relay.h>
-# include <linux/debugfs.h>
#else
# undef STP_RELAYFS
#endif
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 0755781e..762c0a92 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -25,7 +25,6 @@ static struct utt_trace *_stp_utt = NULL;
static unsigned int utt_seq = 1;
static int _stp_probes_started = 0;
static pid_t _stp_target = 0;
-static int _stp_exit_called = 0;
static int _stp_exit_flag = 0;
#include "control.h"
#ifdef STP_OLD_TRANSPORT
@@ -89,13 +88,14 @@ static void _stp_handle_start(struct _stp_msg_start *st)
/* when someone does /sbin/rmmod on a loaded systemtap module. */
static void _stp_cleanup_and_exit(int send_exit)
{
- if (!_stp_exit_called) {
+ static int called = 0;
+ if (!called) {
int failures;
dbug_trans(1, "cleanup_and_exit (%d)\n", send_exit);
_stp_exit_flag = 1;
/* we only want to do this stuff once */
- _stp_exit_called = 1;
+ called = 1;
if (_stp_probes_started) {
dbug_trans(1, "calling probe_exit\n");
@@ -119,6 +119,18 @@ static void _stp_cleanup_and_exit(int send_exit)
}
}
+static void _stp_request_exit(void)
+{
+ static int called = 0;
+ if (!called) {
+ /* we only want to do this once */
+ called = 1;
+ dbug_trans(1, "ctl_send STP_REQUEST_EXIT\n");
+ _stp_ctl_send(STP_REQUEST_EXIT, NULL, 0);
+ dbug_trans(1, "done with ctl_send STP_REQUEST_EXIT\n");
+ }
+}
+
/*
* Called when stapio closes the control channel.
*/
@@ -169,7 +181,7 @@ static void _stp_work_queue(void *data)
/* if exit flag is set AND we have finished with probe_start() */
if (unlikely(_stp_exit_flag && _stp_probes_started))
- _stp_cleanup_and_exit(1);
+ _stp_request_exit();
if (likely(_stp_attached))
queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER);
}
@@ -188,7 +200,6 @@ static void _stp_transport_close()
_stp_unregister_ctl_channel();
if (_stp_utt)
utt_trace_remove(_stp_utt);
- _stp_kill_time(); /* Go to a beach. Drink a beer. */
_stp_print_cleanup(); /* free print buffers */
_stp_mem_debug_done();
dbug_trans(1, "---- CLOSED ----\n");
@@ -244,10 +255,6 @@ static int _stp_transport_init(void)
dbug_trans(1, "Using %d subbufs of size %d\n", _stp_nsubbufs, _stp_subbuf_size);
}
- /* initialize timer code */
- if (_stp_init_time())
- return -1;
-
#if !defined (STP_OLD_TRANSPORT) || defined (STP_BULKMODE)
/* open utt (relayfs) channel to send data to userspace */
_stp_utt = _stp_utt_open();
@@ -286,7 +293,6 @@ err1:
if (_stp_utt)
utt_trace_remove(_stp_utt);
err0:
- _stp_kill_time();
return -1;
}
diff --git a/runtime/transport/transport_msgs.h b/runtime/transport/transport_msgs.h
index 596f4925..0d9a5983 100644
--- a/runtime/transport/transport_msgs.h
+++ b/runtime/transport/transport_msgs.h
@@ -21,19 +21,20 @@ struct _stp_trace {
enum
{
STP_START,
- STP_EXIT,
+ STP_EXIT,
STP_OOB_DATA,
STP_SYSTEM,
STP_TRANSPORT,
STP_CONNECT,
- STP_DISCONNECT,
+ STP_DISCONNECT,
STP_BULK,
STP_READY,
- STP_RELOCATION,
+ STP_RELOCATION,
/** deprecated STP_OLD_TRANSPORT **/
STP_BUF_INFO,
STP_SUBBUFS_CONSUMED,
STP_REALTIME_DATA,
+ STP_REQUEST_EXIT,
STP_MAX_CMD
};
@@ -52,6 +53,7 @@ static const char *_stp_command_name[] = {
"STP_BUF_INFO",
"STP_SUBBUFS_CONSUMED",
"STP_REALTIME_DATA",
+ "STP_REQUEST_EXIT",
};
#endif /* DEBUG_TRANS */