summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/ChangeLog23
-rw-r--r--runtime/staprun/ChangeLog25
-rw-r--r--runtime/staprun/common.c6
-rw-r--r--runtime/staprun/mainloop.c122
-rw-r--r--runtime/staprun/stapio.c2
-rw-r--r--runtime/staprun/staprun.c2
-rw-r--r--runtime/task_finder.c139
-rw-r--r--runtime/time.c7
-rw-r--r--runtime/transport/ChangeLog6
-rw-r--r--runtime/transport/transport.c6
-rw-r--r--runtime/vsprintf.c6
11 files changed, 223 insertions, 121 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 3eabede9..8410b918 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,26 @@
+2008-05-05 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6481.
+ * time.c (__stp_time_timer_callback): Reenable irq's before
+ mod_timer.
+
+2008-05-05 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (stap_utrace_detach_ops): Make sure we ignore
+ /sbin/init.
+ (__stp_utrace_attach): Added function to handle details of
+ attaching a utrace engine.
+ (__stp_utrace_task_finder_report_clone): Calls
+ __stp_utrace_attach.
+ (__stp_utrace_task_finder_report_exec): Ditto.
+ (stap_start_task_finder): Ditto.
+
+2008-04-30 Masami Hiramatsu <mhiramat@redhat.com>
+
+ PR 5648
+ From Shaohua Li <shaohua.li@intel.com>
+ * vsprintf.c (_stp_vsnprintf): Fix unaligned access warning on ia64.
+
2008-04-29 David Smith <dsmith@redhat.com>
* task_finder.c: Made more robust by ensuring that all utrace
diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog
index 9e0ccb73..969c299d 100644
--- a/runtime/staprun/ChangeLog
+++ b/runtime/staprun/ChangeLog
@@ -1,3 +1,28 @@
+2008-05-05 Martin Hunt <hunt@redhat.com>
+
+ * mainloop.c (child_proc): Handle sig_chld
+ in the proper thread.
+ (signal_thread): Don't call send_request()
+ because it isn't thread-safe.
+
+2008-05-05 Martin Hunt <hunt@redhat.com>
+
+ * mainloop.c (signal_thread): New thread to handle signals
+ better.
+ (setup_main_signals): Create signal thread.
+
+2008-04-30 Masami Hiramatsu <mhiramat@redhat.com>
+
+ PR 6008
+ * common.c (parse_args): Increase the limitation of the buffer size
+ to 4095MB.
+ * common.c (usage): Ditto.
+
+2008-04-30 Masami Hiramatsu <mhiramat@redhat.com>
+
+ * stapio.c (main): Fix a typo in a debug message.
+ * staprun.c (main): Ditto.
+
2008-04-24 Frank Ch. Eigler <fche@elastic.org>
PR 6451.
diff --git a/runtime/staprun/common.c b/runtime/staprun/common.c
index b716d27f..93da51d8 100644
--- a/runtime/staprun/common.c
+++ b/runtime/staprun/common.c
@@ -58,8 +58,8 @@ void parse_args(int argc, char **argv)
break;
case 'b':
buffer_size = (unsigned)atoi(optarg);
- if (buffer_size < 1 || buffer_size > 64) {
- err("Invalid buffer size '%d' (should be 1-64).\n", buffer_size);
+ if (buffer_size < 1 || buffer_size > 4095) {
+ err("Invalid buffer size '%d' (should be 1-4095).\n", buffer_size);
usage(argv[0]);
}
break;
@@ -130,7 +130,7 @@ void usage(char *prog)
err("-o FILE Send output to FILE.\n");
err("-b buffer size The systemtap module specifies a buffer size.\n");
err(" Setting one here will override that value. The\n");
- err(" value should be an integer between 1 and 64\n");
+ err(" value should be an integer between 1 and 4095 \n");
err(" which be assumed to be the buffer size in MB.\n");
err(" That value will be per-cpu in bulk mode.\n");
err("-L Load module and start probes, then detach.\n");
diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c
index 37a4f58a..61963743 100644
--- a/runtime/staprun/mainloop.c
+++ b/runtime/staprun/mainloop.c
@@ -16,8 +16,8 @@
/* globals */
int ncpus;
static int use_old_transport = 0;
-enum _stp_sig_type { sig_none, sig_done, sig_detach };
-static enum _stp_sig_type got_signal = sig_none;
+//enum _stp_sig_type { sig_none, sig_done, sig_detach };
+//static enum _stp_sig_type got_signal = sig_none;
/**
* send_request - send request to kernel over control channel
@@ -29,48 +29,83 @@ static enum _stp_sig_type got_signal = sig_none;
*/
int send_request(int type, void *data, int len)
{
- char buf[1024];
-
- /* Before doing memcpy, make sure 'buf' is big enough. */
- if ((len + 4) > (int)sizeof(buf)) {
- _err("exceeded maximum send_request size.\n");
- return -1;
- }
- memcpy(buf, &type, 4);
- memcpy(&buf[4], data, len);
- return write(control_channel, buf, len+4);
+ char buf[1024];
+
+ /* Before doing memcpy, make sure 'buf' is big enough. */
+ if ((len + 4) > (int)sizeof(buf)) {
+ _err("exceeded maximum send_request size.\n");
+ return -1;
+ }
+ memcpy(buf, &type, 4);
+ memcpy(&buf[4], data, len);
+ return write(control_channel, buf, len + 4);
}
+static void *signal_thread(void *arg)
+{
+ sigset_t *s = (sigset_t *) arg;
+ int signum, rc, btype = STP_EXIT;
+
+ while (1) {
+ if (sigwait(s, &signum) < 0) {
+ _perr("sigwait");
+ continue;
+ }
+ dbug(2, "sigproc %d (%s)\n", signum, strsignal(signum));
+ if (signum == SIGQUIT)
+ cleanup_and_exit(1);
+ else if (signum == SIGINT || signum == SIGHUP || signum == SIGTERM) {
+ // send STP_EXIT
+ rc = write(control_channel, &btype, sizeof(btype));
+ break;
+ }
+ }
+ return NULL;
+}
-static void sigproc(int signum)
+static void chld_proc(int signum)
{
- dbug(2, "sigproc %d (%s)\n", signum, strsignal(signum));
-
- if (signum == SIGCHLD) {
- pid_t pid = waitpid(-1, NULL, WNOHANG);
- if (pid != target_pid)
- return;
- send_request(STP_EXIT, NULL, 0);
- } else if (signum == SIGQUIT)
- got_signal = sig_detach;
- else if (signum == SIGINT || signum == SIGHUP || signum == SIGTERM)
- got_signal = sig_done;
+ int32_t rc, btype = STP_EXIT;
+ dbug(2, "chld_proc %d (%s)\n", signum, strsignal(signum));
+ pid_t pid = waitpid(-1, NULL, WNOHANG);
+ if (pid != target_pid)
+ return;
+ // send STP_EXIT
+ rc = write(control_channel, &btype, sizeof(btype));
}
-static void setup_main_signals(int cleanup)
+static void setup_main_signals(void)
{
- struct sigaction a;
- memset(&a, 0, sizeof(a));
- sigfillset(&a.sa_mask);
- if (cleanup == 0) {
- a.sa_handler = sigproc;
- sigaction(SIGCHLD, &a, NULL);
- } else
- a.sa_handler = SIG_IGN;
- sigaction(SIGINT, &a, NULL);
- sigaction(SIGTERM, &a, NULL);
- sigaction(SIGHUP, &a, NULL);
- sigaction(SIGQUIT, &a, NULL);
+ pthread_t tid;
+ struct sigaction sa;
+ sigset_t *s = malloc(sizeof(*s));
+ if (!s) {
+ _perr("malloc failed");
+ exit(1);
+ }
+ sigfillset(s);
+ pthread_sigmask(SIG_SETMASK, s, NULL);
+ memset(&sa, 0, sizeof(sa));
+ sigfillset(&sa.sa_mask);
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+
+ sa.sa_handler = chld_proc;
+ sigaction(SIGCHLD, &sa, NULL);
+
+ sigemptyset(s);
+ sigaddset(s, SIGINT);
+ sigaddset(s, SIGTERM);
+ sigaddset(s, SIGHUP);
+ sigaddset(s, SIGQUIT);
+ pthread_sigmask(SIG_SETMASK, s, NULL);
+ if (pthread_create(&tid, NULL, signal_thread, s) < 0) {
+ _perr("failed to create thread");
+ exit(1);
+ }
}
/*
@@ -229,7 +264,7 @@ void cleanup_and_exit(int detach)
return;
exiting = 1;
- setup_main_signals(1);
+ setup_main_signals();
dbug(1, "detach=%d\n", detach);
@@ -272,20 +307,17 @@ int stp_main_loop(void)
char recvbuf[8196];
setvbuf(ofp, (char *)NULL, _IOLBF, 0);
- setup_main_signals(0);
+ setup_main_signals();
dbug(2, "in main loop\n");
send_request(STP_READY, NULL, 0);
- while (1) { /* handle messages from control channel */
+ /* handle messages from control channel */
+ while (1) {
nb = read(control_channel, recvbuf, sizeof(recvbuf));
dbug(2, "nb=%d\n", (int)nb);
if (nb <= 0) {
- if (got_signal == sig_done)
- send_request(STP_EXIT, NULL, 0);
- else if (got_signal == sig_detach)
- cleanup_and_exit(1);
- else if (errno != EINTR)
+ if (errno != EINTR)
_perr("Unexpected EOF in read (nb=%ld)", (long)nb);
continue;
}
diff --git a/runtime/staprun/stapio.c b/runtime/staprun/stapio.c
index b591244f..3c8c4f7f 100644
--- a/runtime/staprun/stapio.c
+++ b/runtime/staprun/stapio.c
@@ -30,7 +30,7 @@ int main(int argc, char **argv)
parse_args(argc, argv);
if (buffer_size)
- dbug(1, "Using a buffer of %u bytes.\n", buffer_size);
+ dbug(1, "Using a buffer of %u MB.\n", buffer_size);
if (optind < argc) {
parse_modpath(argv[optind++]);
diff --git a/runtime/staprun/staprun.c b/runtime/staprun/staprun.c
index ee9bdc7b..0291d01f 100644
--- a/runtime/staprun/staprun.c
+++ b/runtime/staprun/staprun.c
@@ -230,7 +230,7 @@ int main(int argc, char **argv)
parse_args(argc, argv);
if (buffer_size)
- dbug(2, "Using a buffer of %u bytes.\n", buffer_size);
+ dbug(2, "Using a buffer of %u MB.\n", buffer_size);
if (optind < argc) {
parse_modpath(argv[optind++]);
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index 915925a3..6d79c98a 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -93,6 +93,10 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops)
rcu_read_lock();
for_each_process(tsk) {
struct mm_struct *mm;
+
+ if (tsk->pid <= 1)
+ continue;
+
mm = get_task_mm(tsk);
if (mm) {
mmput(mm);
@@ -188,6 +192,45 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
#define __STP_UTRACE_ATTACHED_TASK_EVENTS (UTRACE_EVENT(DEATH))
+static int
+__stp_utrace_attach(struct task_struct *tsk,
+ const struct utrace_engine_ops *ops, void *data,
+ unsigned long event_flags)
+{
+ struct utrace_attached_engine *engine;
+ struct mm_struct *mm;
+ int rc = 0;
+
+ // Ignore init
+ if (tsk->pid <= 1)
+ return EPERM;
+
+ // Ignore threads with no mm (which are kernel threads).
+ mm = get_task_mm(tsk);
+ if (! mm)
+ return EPERM;
+ mmput(mm);
+
+ engine = utrace_attach(tsk, UTRACE_ATTACH_CREATE, ops, data);
+ if (IS_ERR(engine)) {
+ int error = -PTR_ERR(engine);
+ if (error != ENOENT) {
+ _stp_error("utrace_attach returned error %d on pid %d",
+ error, (int)tsk->pid);
+ rc = error;
+ }
+ }
+ else if (unlikely(engine == NULL)) {
+ _stp_error("utrace_attach returned NULL on pid %d",
+ (int)tsk->pid);
+ rc = EFAULT;
+ }
+ else {
+ utrace_set_flags(tsk, engine, event_flags);
+ }
+ return rc;
+}
+
static u32
__stp_utrace_task_finder_report_clone(struct utrace_attached_engine *engine,
struct task_struct *parent,
@@ -200,21 +243,9 @@ __stp_utrace_task_finder_report_clone(struct utrace_attached_engine *engine,
if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING)
return UTRACE_ACTION_RESUME;
- // On clone, attach to the child. Ignore threads with no mm
- // (which are kernel threads).
- mm = get_task_mm(child);
- if (mm) {
- mmput(mm);
- child_engine = utrace_attach(child, UTRACE_ATTACH_CREATE,
- engine->ops, 0);
- if (IS_ERR(child_engine))
- _stp_error("attach to clone child %d failed: %ld",
- (int)child->pid, PTR_ERR(child_engine));
- else {
- utrace_set_flags(child, child_engine,
- __STP_UTRACE_TASK_FINDER_EVENTS);
- }
- }
+ // On clone, attach to the child.
+ (void) __stp_utrace_attach(child, engine->ops, 0,
+ __STP_UTRACE_TASK_FINDER_EVENTS);
return UTRACE_ACTION_RESUME;
}
@@ -253,6 +284,8 @@ __stp_utrace_task_finder_report_exec(struct utrace_attached_engine *engine,
struct list_head *cb_node;
list_for_each(cb_node, &tgt->callback_list_head) {
struct stap_task_finder_target *cb_tgt;
+ int rc;
+
cb_tgt = list_entry(cb_node,
struct stap_task_finder_target,
callback_list);
@@ -269,19 +302,11 @@ __stp_utrace_task_finder_report_exec(struct utrace_attached_engine *engine,
}
// Set up thread death notification.
- engine = utrace_attach(tsk,
- UTRACE_ATTACH_CREATE,
- &cb_tgt->ops, cb_tgt);
- if (IS_ERR(engine)) {
- _stp_error("attach to exec'ed %d failed: %ld",
- (int)tsk->pid,
- PTR_ERR(engine));
- }
- else {
- utrace_set_flags(tsk, engine,
+ rc = __stp_utrace_attach(tsk, &cb_tgt->ops, cb_tgt,
__STP_UTRACE_ATTACHED_TASK_EVENTS);
- cb_tgt->engine_attached = 1;
- }
+ if (rc != 0 && rc != EPERM)
+ break;
+ cb_tgt->engine_attached = 1;
}
}
return UTRACE_ACTION_RESUME;
@@ -346,46 +371,35 @@ stap_start_task_finder(void)
}
atomic_set(&__stp_task_finder_state, __STP_TF_RUNNING);
- printk(KERN_ERR "SYSTEMTAP: in RUNNING state\n");
rcu_read_lock();
for_each_process(tsk) {
- struct utrace_attached_engine *engine;
struct mm_struct *mm;
char *mmpath;
size_t mmpathlen;
struct list_head *tgt_node;
+ /* Attach to the thread */
+ rc = __stp_utrace_attach(tsk, &__stp_utrace_task_finder_ops, 0,
+ __STP_UTRACE_TASK_FINDER_EVENTS);
+ if (rc == EPERM) {
+ /* Ignore EPERM errors, which mean this wasn't
+ * a thread we can attach to. */
+ rc = 0;
+ continue;
+ }
+ else if (rc != 0) {
+ /* If we get a real error, quit. */
+ break;
+ }
+
+ /* Grab the path associated with this task. */
mm = get_task_mm(tsk);
if (! mm) {
/* If the thread doesn't have a mm_struct, it is
* a kernel thread which we need to skip. */
continue;
}
-
- /* Attach to the thread */
- engine = utrace_attach(tsk, UTRACE_ATTACH_CREATE,
- &__stp_utrace_task_finder_ops, 0);
- if (IS_ERR(engine)) {
- int error = -PTR_ERR(engine);
- if (error != ENOENT) {
- mmput(mm);
- _stp_error("utrace_attach returned error %d on pid %d",
- error, (int)tsk->pid);
- rc = error;
- break;
- }
- }
- else if (unlikely(engine == NULL)) {
- mmput(mm);
- _stp_error("utrace_attach returned NULL on pid %d",
- (int)tsk->pid);
- rc = EFAULT;
- break;
- }
- utrace_set_flags(tsk, engine, __STP_UTRACE_TASK_FINDER_EVENTS);
-
- /* Check the thread's exe's path/pid against our list. */
mmpath = __stp_get_mm_path(mm, mmpath_buf, PATH_MAX);
mmput(mm); /* We're done with mm */
if (IS_ERR(mmpath)) {
@@ -395,6 +409,7 @@ stap_start_task_finder(void)
break;
}
+ /* Check the thread's exe's path/pid against our list. */
mmpathlen = strlen(mmpath);
list_for_each(tgt_node, &__stp_task_finder_list) {
struct stap_task_finder_target *tgt;
@@ -430,23 +445,17 @@ stap_start_task_finder(void)
}
// Set up thread death notification.
- engine = utrace_attach(tsk,
- UTRACE_ATTACH_CREATE,
- &cb_tgt->ops, cb_tgt);
- if (IS_ERR(engine)) {
- _stp_error("attach to %d failed: %ld",
- (int)tsk->pid,
- PTR_ERR(engine));
- }
- else {
- utrace_set_flags(tsk, engine,
+ rc = __stp_utrace_attach(tsk, &cb_tgt->ops,
+ cb_tgt,
__STP_UTRACE_ATTACHED_TASK_EVENTS);
- cb_tgt->engine_attached = 1;
- }
+ if (rc != 0 && rc != EPERM)
+ break;
+ cb_tgt->engine_attached = 1;
}
}
}
rcu_read_unlock();
+
_stp_kfree(mmpath_buf);
return rc;
}
diff --git a/runtime/time.c b/runtime/time.c
index 52a2edbb..8a0b6fad 100644
--- a/runtime/time.c
+++ b/runtime/time.c
@@ -131,10 +131,13 @@ __stp_time_timer_callback(unsigned long val)
time->base_cycles = cycles;
write_sequnlock(&time->lock);
+ local_irq_restore(flags);
+ /* PR6481: reenable IRQs before resetting the timer.
+ XXX: The worst that can probably happen is that we get
+ two consecutive timer resets. */
+
if (likely(stp_timer_reregister))
mod_timer(&time->timer, jiffies + 1);
-
- local_irq_restore(flags);
}
/* This is called as an IPI, with interrupts disabled. */
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index b0f2aee8..9d0ba162 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,9 @@
+2008-04-30 Masami Hiramatsu <mhiramat@redhat.com>
+
+ PR 5645
+ * transport.c (_stp_transport_init): Fix subbuffer size calculation
+ overflow.
+
2008-04-21 hunt <hunt@redhat.com>
* control.c (_stp_ctl_write): Return len + sizeof(int) so
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 1f9a1667..a4e4e652 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -225,7 +225,11 @@ int _stp_transport_init(void)
if (_stp_bufsize) {
unsigned size = _stp_bufsize * 1024 * 1024;
- _stp_subbuf_size = ((size >> 2) + 1) * 65536;
+ _stp_subbuf_size = 65536;
+ while (size / _stp_subbuf_size > 64 &&
+ _stp_subbuf_size < 1024 * 1024) {
+ _stp_subbuf_size <<= 1;
+ }
_stp_nsubbufs = size / _stp_subbuf_size;
dbug_trans(1, "Using %d subbufs of size %d\n", _stp_nsubbufs, _stp_subbuf_size);
}
diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c
index 0bf625a5..dcaa1bc3 100644
--- a/runtime/vsprintf.c
+++ b/runtime/vsprintf.c
@@ -256,18 +256,18 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
break;
case 2:
if((str + 1) <= end)
- *(int16_t *)str = (int16_t)num;
+ memcpy(str, &num, 2);
str+=2;
break;
case 4:
if((str + 3) <= end)
- *(int32_t *)str = num;
+ memcpy(str, &num, 4);
str+=4;
break;
default: // "%.8b" by default
case 8:
if((str + 7) <= end)
- *(int64_t *)str = num;
+ memcpy(str, &num, 8);
str+=8;
break;
}