diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/io.c | 9 | ||||
-rw-r--r-- | runtime/regs.h | 20 | ||||
-rw-r--r-- | runtime/staprun/relay_old.c | 6 | ||||
-rw-r--r-- | runtime/sym.c | 58 | ||||
-rw-r--r-- | runtime/sym.h | 2 | ||||
-rw-r--r-- | runtime/syscall.h | 1 | ||||
-rw-r--r-- | runtime/task_finder.c | 13 | ||||
-rw-r--r-- | runtime/transport/control.c | 3 | ||||
-rw-r--r-- | runtime/transport/ring_buffer.c | 10 | ||||
-rw-r--r-- | runtime/transport/symbols.c | 2 | ||||
-rw-r--r-- | runtime/transport/transport.c | 5 |
11 files changed, 83 insertions, 46 deletions
diff --git a/runtime/io.c b/runtime/io.c index 687926fd..0136aae5 100644 --- a/runtime/io.c +++ b/runtime/io.c @@ -32,7 +32,7 @@ static void _stp_vlog (enum code type, const char *func, int line, const char *f int start = 0; if (type == DBUG) { - start = _stp_snprintf(buf, STP_LOG_BUF_LEN, "\033[36m%s:%d:\033[0m ", func, line); + start = _stp_snprintf(buf, STP_LOG_BUF_LEN, "%s:%d: ", func, line); } else if (type == WARN) { strcpy (buf, WARN_STRING); start = sizeof(WARN_STRING) - 1; @@ -49,12 +49,19 @@ static void _stp_vlog (enum code type, const char *func, int line, const char *f buf[num + start] = '\0'; } +#ifdef STAP_DEBUG_PRINTK + if (type == DBUG) printk (KERN_DEBUG "%s", buf); + else if (type == WARN) printk (KERN_WARNING "%s", buf); + else if (type == ERROR) printk (KERN_ERR "%s", buf); + else printk (KERN_INFO "%s", buf); +#else if (type != DBUG) _stp_ctl_write(STP_OOB_DATA, buf, start + num + 1); else { _stp_print(buf); _stp_print_flush(); } +#endif } put_cpu(); } diff --git a/runtime/regs.h b/runtime/regs.h index d80cdf0a..dc6b50af 100644 --- a/runtime/regs.h +++ b/runtime/regs.h @@ -12,53 +12,61 @@ #define _REGS_H_ #if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__)) + #define REG_IP(regs) regs->ip -#define REG_IP_LVALUE 1 #define REG_SP(regs) regs->sp #define REG_FP(regs) regs->bp #elif defined (__x86_64__) #define REG_IP(regs) regs->rip -#define REG_IP_LVALUE 1 #define REG_SP(regs) regs->rsp #elif defined (__i386__) #define REG_IP(regs) regs->eip -#define REG_IP_LVALUE 1 #define REG_SP(regs) regs->esp #define REG_FP(regs) regs->ebp #elif defined (__ia64__) + #define REG_IP(regs) ((regs)->cr_iip +ia64_psr(regs)->ri) #define REG_SP(regs) ((regs)->r12) +#define SET_REG_IP(regs, x) \ + (((regs)->cr_iip = (x) & ~3UL), (ia64_psr(regs)->ri = (x) & 3UL)) + #elif defined (__powerpc64__) #define REG_IP(regs) regs->nip -#define REG_IP_LVALUE 1 #define REG_SP(regs) regs->gpr[1] #define REG_LINK(regs) regs->link #elif defined (__arm__) #define REG_IP(regs) regs->ARM_pc -#define REG_IP_LVALUE 1 #define REG_SP(regs) regs->ARM_sp #define REG_LINK(regs) regs->ARM_lr #elif defined (__s390__) || defined (__s390x__) + #ifndef __s390x__ #define PSW_ADDR_AMODE 0x80000000UL +#define PSW_ADDR_INSN 0x7FFFFFFFUL #else /* __s390x__ */ #define PSW_ADDR_AMODE 0x0000000000000000UL +#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL #endif /* __s390x__ */ -#define REG_IP(regs) (((regs)->psw.addr) | PSW_ADDR_AMODE) +#define REG_IP(regs) (((regs)->psw.addr) & PSW_ADDR_INSN) #define REG_SP(regs) (regs)->gprs[15] +#define SET_REG_IP(regs,x) (regs)->psw.addr = (x) | PSW_ADDR_AMODE #else #error "Unimplemented architecture" #endif +#ifndef SET_REG_IP +#define SET_REG_IP(regs, x) REG_IP(regs) = x +#endif + #endif /* _REGS_H_ */ diff --git a/runtime/staprun/relay_old.c b/runtime/staprun/relay_old.c index 71d8acee..0254173f 100644 --- a/runtime/staprun/relay_old.c +++ b/runtime/staprun/relay_old.c @@ -110,7 +110,8 @@ static int open_oldoutfile(int fnum, int cpu, int remove_file) perr("Couldn't open output file %s", buf); return -1; } - if (set_clexec(fileno(percpu_tmpfile[cpu])) < 0) { + out_fd[cpu] = fileno(percpu_tmpfile[cpu]); + if (set_clexec(out_fd[cpu]) < 0) { perr("Couldn't clear exec bit of open output file %s", buf); return -1; } @@ -181,7 +182,8 @@ static int open_relayfs_files(int cpu, const char *relay_filebase, const char *p perr("Couldn't open output file %s", tmp); goto err2; } - if (set_clexec(fileno(percpu_tmpfile[cpu])) < 0) { + out_fd[cpu] = fileno(percpu_tmpfile[cpu]); + if (set_clexec(out_fd[cpu]) < 0) { perr("Couldn't open output file %s", tmp); goto err2; } diff --git a/runtime/sym.c b/runtime/sym.c index dd2235cc..0baa1a5e 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -16,21 +16,6 @@ #include "string.c" #include "task_finder_vma.c" -/** @file sym.c - * @addtogroup sym Symbolic Functions - * Symbolic Lookup Functions - * @{ - */ - -static void _stp_sym_init(void) -{ - static int initialized = 0; - if (! initialized) { - __stp_tf_vma_initialize(); - initialized = 1; - } -} - /* Callback that needs to be registered (in session.unwindsyms_modules) for every user task path for which we might need symbols or unwind info. */ @@ -259,7 +244,8 @@ static int _stp_module_check(void) /* notes end address */ if (!strcmp(m->name, "kernel")) { - notes_addr = m->build_id_offset; + notes_addr = _stp_module_relocate("kernel", + "_stext", m->build_id_offset); base_addr = _stp_module_relocate("kernel", "_stext", 0); } else { @@ -408,4 +394,44 @@ static void _stp_symbol_snprint(char *str, size_t len, unsigned long address, } /** @} */ + + +/** @file sym.c + * @addtogroup sym Symbolic Functions + * Symbolic Lookup Functions + * @{ + */ +static void _stp_sym_init(void) +{ + // NB: it's too "early" to make this conditional on STP_NEED_VMA_TRACKER, + // since we're #included at the top of the generated module, before any + // tapset-induced #define's. +#if defined(CONFIG_UTRACE) + static int initialized = 0; + static struct stap_task_finder_target vmcb = { + // NB: no .pid, no .procname filters here. + // This means that we get a system-wide mmap monitoring + // widget while the script is running. (The system-wideness may + // be restricted by stap -c or -x.) But this seems to + // be necessary if we want to to stack tracebacks through arbitrary + // shared libraries. XXX: There may be an optimization opportunity + // for executables (for which the main task-finder callback should be + // sufficient). + .mmap_callback = &_stp_tf_mmap_cb, + .munmap_callback = &_stp_tf_munmap_cb, + }; + if (! initialized) { + int rc; + __stp_tf_vma_initialize(); + rc = stap_register_task_finder_target (& vmcb); +#ifdef DEBUG_TASK_FINDER_VMA + _stp_dbug(__FUNCTION__, __LINE__, "registered vmcb"); +#endif + (void) rc; // XXX + initialized = 1; + } +#endif +} + + #endif /* _STP_SYM_C_ */ diff --git a/runtime/sym.h b/runtime/sym.h index 262b1776..ca69345f 100644 --- a/runtime/sym.h +++ b/runtime/sym.h @@ -30,8 +30,6 @@ struct _stp_module { struct _stp_section *sections; unsigned num_sections; - struct stap_task_finder_target *vmcb; /* PR10228 */ - /* A pointer to the struct module. Note that we cannot */ /* trust this because as of 2.6.19, there are not yet */ /* any notifier hooks that will tell us when a module */ diff --git a/runtime/syscall.h b/runtime/syscall.h index 38b523e1..786965f4 100644 --- a/runtime/syscall.h +++ b/runtime/syscall.h @@ -52,6 +52,7 @@ : __MREMAP_SYSCALL_NO_X86_64) # else #define MMAP_SYSCALL_NO(tsk) __MMAP_SYSCALL_NO_X86_64 +#define MMAP2_SYSCALL_NO(tsk) __MMAP2_SYSCALL_NO_X86_64 #define MPROTECT_SYSCALL_NO(tsk) __MPROTECT_SYSCALL_NO_X86_64 #define MUNMAP_SYSCALL_NO(tsk) __MUNMAP_SYSCALL_NO_X86_64 #define MREMAP_SYSCALL_NO(tsk) __MREMAP_SYSCALL_NO_X86_64 diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 1a9a738a..6b50f1b9 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -45,18 +45,10 @@ static atomic_t __stp_attach_count = ATOMIC_INIT (0); #define debug_task_finder_attach() (atomic_inc(&__stp_attach_count)) #define debug_task_finder_detach() (atomic_dec(&__stp_attach_count)) -#ifdef DEBUG_TASK_FINDER_PRINTK -#define debug_task_finder_report() (printk(KERN_ERR \ - "%s:%d attach count: %d, inuse count: %d\n", \ - __FUNCTION__, __LINE__, \ - atomic_read(&__stp_attach_count), \ - atomic_read(&__stp_inuse_count))) -#else #define debug_task_finder_report() (_stp_dbug(__FUNCTION__, __LINE__, \ "attach count: %d, inuse count: %d\n", \ atomic_read(&__stp_attach_count), \ atomic_read(&__stp_inuse_count))) -#endif /* !DEBUG_TASK_FINDER_PRINTK */ #else #define debug_task_finder_attach() /* empty */ #define debug_task_finder_detach() /* empty */ @@ -1357,7 +1349,6 @@ stap_start_task_finder(void) char *mmpath_buf; uid_t tsk_euid; - debug_task_finder_report(); mmpath_buf = _stp_kmalloc(PATH_MAX); if (mmpath_buf == NULL) { _stp_error("Unable to allocate space for path"); @@ -1443,7 +1434,7 @@ stap_start_task_finder(void) #ifndef STP_PRIVILEGED /* Make sure unprivileged users only probe their own threads. */ if (_stp_uid != tsk_euid) { - if (tgt->pid != 0) { + if (tgt->pid != 0 || _stp_target) { _stp_warn("Process %d does not belong to unprivileged user %d", tsk->pid, _stp_uid); } @@ -1462,8 +1453,8 @@ stap_start_task_finder(void) } while_each_thread(grp, tsk); stf_err: rcu_read_unlock(); - _stp_kfree(mmpath_buf); + debug_task_finder_report(); // report at end for utrace engine counting return rc; } diff --git a/runtime/transport/control.c b/runtime/transport/control.c index 925a6768..0e18bb8b 100644 --- a/runtime/transport/control.c +++ b/runtime/transport/control.c @@ -173,6 +173,9 @@ static int _stp_ctl_send(int type, void *data, int len) msleep(5); if (err > 0) wake_up_interruptible(&_stp_ctl_wq); + else + // printk instead of _stp_error since an error here means our transport is suspect + printk(KERN_ERR "ctl_send (type=%d len=%d) failed: %d\n", type, len, err); dbug_trans(1, "returning %d\n", err); return err; } diff --git a/runtime/transport/ring_buffer.c b/runtime/transport/ring_buffer.c index 43448076..251d6ed9 100644 --- a/runtime/transport/ring_buffer.c +++ b/runtime/transport/ring_buffer.c @@ -162,7 +162,7 @@ _stp_event_to_user(struct ring_buffer_event *event, char __user *ubuf, return -EFAULT; } - entry = (struct _stp_data_entry *)ring_buffer_event_data(event); + entry = ring_buffer_event_data(event); if (entry == NULL) { dbug_trans(1, "returning -EFAULT(2)\n"); return -EFAULT; @@ -578,7 +578,7 @@ _stp_data_write_reserve(size_t size_request, void **entry) if (event) { ssize_t len; - sde = (struct _stp_data_entry *)ring_buffer_event_data(event); + sde = ring_buffer_event_data(event); if (sde->len < size_request) size_request = sde->len; _stp_ring_buffer_consume(iter); @@ -605,7 +605,7 @@ _stp_data_write_reserve(size_t size_request, void **entry) } } - sde = (struct _stp_data_entry *)ring_buffer_event_data(event); + sde = ring_buffer_event_data(event); sde->len = size_request; *entry = event; @@ -620,7 +620,7 @@ static unsigned char *_stp_data_entry_data(void *entry) if (event == NULL) return NULL; - sde = (struct _stp_data_entry *)ring_buffer_event_data(event); + sde = ring_buffer_event_data(event); return sde->buf; } @@ -635,7 +635,7 @@ static int _stp_data_write_commit(void *entry) #if defined(DEBUG_TRANS) && (DEBUG_TRANS >= 2) { - struct _stp_data_entry *sde = (struct _stp_data_entry *)ring_buffer_event_data(event); + struct _stp_data_entry *sde = ring_buffer_event_data(event); char *last = sde->buf + (sde->len - 5); dbug_trans2("commiting %.5s...%.5s\n", sde->buf, last); } diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index 3e6a2fb1..a214d1f2 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -15,7 +15,7 @@ static void _stp_do_relocation(const char __user *buf, size_t count) { - struct _stp_msg_relocation msg; + static struct _stp_msg_relocation msg; /* by protocol, never concurrently used */ unsigned mi, si; if (sizeof(msg) != count) diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index 1d029e53..f5efce9f 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -31,8 +31,9 @@ static int _stp_ctl_attached = 0; static pid_t _stp_target = 0; static int _stp_probes_started = 0; -// For now, disable transport version 3 -#if STP_TRANSPORT_VERSION == 3 +// For now, disable transport version 3 (unless STP_USE_RING_BUFFER is +// defined). +#if STP_TRANSPORT_VERSION == 3 && !defined(STP_USE_RING_BUFFER) #undef STP_TRANSPORT_VERSION #define STP_TRANSPORT_VERSION 2 #endif |