From 2fa2a091a0b248855d7f77aa20677ef4c7a7cc61 Mon Sep 17 00:00:00 2001 From: Nobuhiro Tachino Date: Tue, 16 Sep 2008 22:04:02 -0400 Subject: add new stap -F (flight recorder) option that just passes through to staprun -L --- NEWS | 5 +++++ buildrun.cxx | 3 +++ main.cxx | 8 +++++++- session.h | 1 + stap.1.in | 4 ++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b7647c30..824f3ded 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,10 @@ * What's new +- The stap "-F" flag activates "flight recorder" mode, which consists of + translating the given script as usual, but implicitly launching it into + the background with staprun's existing "-L" (launch) option. A user + can later reattach to the module with "staprun -A MODULENAME". + - Additional context variables are available on user-space syscall probes. - $argN ($arg1, $arg2, ... $arg6) in process(PATH_OR_PID).syscall gives you the argument of the system call. diff --git a/buildrun.cxx b/buildrun.cxx index ada00027..8ec731df 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -287,6 +287,9 @@ run_pass (systemtap_session& s) if (s.need_uprobes) staprun_cmd += "-u "; + if (s.load_only) + staprun_cmd += "-L "; + staprun_cmd += s.tmpdir + "/" + s.module_name + ".ko"; if (s.verbose>1) clog << "Running " << staprun_cmd << endl; diff --git a/main.cxx b/main.cxx index 563e4b01..ce4572c1 100644 --- a/main.cxx +++ b/main.cxx @@ -108,6 +108,7 @@ usage (systemtap_session& s, int exitcode) << " -c CMD start the probes, run CMD, and exit when it finishes" << endl << " -x PID sets target() to PID" << endl + << " -F load module and start probes, then detach" << endl << " -d OBJECT add unwind/symbol data for OBJECT file"; if (s.unwindsym_modules.size() == 0) clog << endl; @@ -363,6 +364,7 @@ main (int argc, char * const argv []) s.consult_symtab = false; s.ignore_vmlinux = false; s.ignore_dwarf = false; + s.load_only = false; const char* s_p = getenv ("SYSTEMTAP_TAPSET"); if (s_p != NULL) @@ -426,7 +428,7 @@ main (int argc, char * const argv []) { "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF }, { NULL, 0, NULL, 0 } }; - int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:", + int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:F", long_options, NULL); if (grc < 0) break; @@ -611,6 +613,10 @@ main (int argc, char * const argv []) have_script = true; break; + case 'F': + s.load_only = true; + break; + case 0: switch (long_opt) { diff --git a/session.h b/session.h index 22575e8d..b8bd971a 100644 --- a/session.h +++ b/session.h @@ -104,6 +104,7 @@ struct systemtap_session bool prologue_searching; bool tapset_compile_coverage; bool need_uprobes; + bool load_only; // flight recorder mode // Cache data bool use_cache; diff --git a/stap.1.in b/stap.1.in index 22336cd5..0546d022 100644 --- a/stap.1.in +++ b/stap.1.in @@ -185,6 +185,10 @@ and aliases. .BI \-L " PROBE" Similar to "-l", but list probe points and local variables. .TP +.BI \-F +Load module and start probes, then detach from the module leaving the +probes running. +.TP .B \-\-kelf For names and addresses of functions to probe, consult the symbol tables in the kernel and modules. -- cgit From 85d2b7ff564b8530a984c8d767a18bae6ca73eac Mon Sep 17 00:00:00 2001 From: Jim Keniston Date: Wed, 17 Sep 2008 12:10:22 -0400 Subject: PR6879: uprobe support for 0x64/0x65 segment prefix instructions --- runtime/uprobes/uprobes_i386.c | 5 +++-- runtime/uprobes/uprobes_x86.c | 11 ++++++----- runtime/uprobes/uprobes_x86_64.c | 11 ++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/runtime/uprobes/uprobes_i386.c b/runtime/uprobes/uprobes_i386.c index 5fe7d781..51b06f79 100644 --- a/runtime/uprobes/uprobes_i386.c +++ b/runtime/uprobes/uprobes_i386.c @@ -41,7 +41,7 @@ W(0x30, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1), /* 30 */ W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 50 */ - W(0x60, 1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1), /* 90 */ @@ -111,7 +111,8 @@ * * others -- Do we need to support these? * 07, 17, 1f - pop es, pop ss, pop ds - * 26, 2e, 36, 3e, 64, 65 - es:, cs:, ss:, ds:, fs:, gs: segment prefixes + * 26, 2e, 36, 3e, - es:, cs:, ss:, ds: segment prefixes -- + * but 64 and 65 (fs: and gs:) seems to be used, so we support them. * 67 - addr16 prefix * 9b - wait/fwait * ce - into diff --git a/runtime/uprobes/uprobes_x86.c b/runtime/uprobes/uprobes_x86.c index ebb10d4e..05d2a978 100644 --- a/runtime/uprobes/uprobes_x86.c +++ b/runtime/uprobes/uprobes_x86.c @@ -43,7 +43,7 @@ static const unsigned long long good_insns_64[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0), /* 30 */ W(0x40, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -68,7 +68,7 @@ static const unsigned long long good_insns_32[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1), /* 30 */ W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -138,7 +138,8 @@ static const unsigned long long good_2byte_insns[256 / 64] = { * others -- Do we need to support these? * 0f - (floating-point?) prefetch instructions * 07, 17, 1f - pop es, pop ss, pop ds - * 26, 2e, 36, 3e, 64, 65 - es:, cs:, ss:, ds:, fs:, gs: segment prefixes + * 26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes -- + * but 64 and 65 (fs: and gs:) seems to be used, so we support them. * 67 - addr16 prefix * 9b - wait/fwait * ce - into @@ -165,10 +166,10 @@ static inline int check_legacy_prefix(u8 byte) case 0x2e: case 0x36: case 0x3e: - case 0x64: - case 0x65: case 0xf0: return -1; + case 0x64: + case 0x65: case 0x66: case 0x67: case 0xf2: diff --git a/runtime/uprobes/uprobes_x86_64.c b/runtime/uprobes/uprobes_x86_64.c index 78969248..a681cab5 100644 --- a/runtime/uprobes/uprobes_x86_64.c +++ b/runtime/uprobes/uprobes_x86_64.c @@ -43,7 +43,7 @@ static const unsigned long good_insns_64[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0), /* 30 */ W(0x40, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -68,7 +68,7 @@ static const unsigned long good_insns_32[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1), /* 30 */ W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -138,7 +138,8 @@ static const unsigned long good_2byte_insns[256 / 64] = { * others -- Do we need to support these? * 0f - (floating-point?) prefetch instructions * 07, 17, 1f - pop es, pop ss, pop ds - * 26, 2e, 36, 3e, 64, 65 - es:, cs:, ss:, ds:, fs:, gs: segment prefixes + * 26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes -- + * but 64 and 65 (fs: and gs:) seems to be used, so we support them. * 67 - addr16 prefix * 9b - wait/fwait * ce - into @@ -165,10 +166,10 @@ static inline int check_legacy_prefix(u8 byte) case 0x2e: case 0x36: case 0x3e: - case 0x64: - case 0x65: case 0xf0: return -1; + case 0x64: + case 0x65: case 0x66: case 0x67: case 0xf2: -- cgit From 316ebf03eff7fcff893dc9913c4866ad991c0e85 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 17 Sep 2008 16:27:44 +0200 Subject: Removed commented out code and unneeded embedded C-code from aux_syscalls.stp. --- tapset/ChangeLog | 5 ++ tapset/aux_syscalls.stp | 190 +++++++++--------------------------------------- 2 files changed, 41 insertions(+), 154 deletions(-) diff --git a/tapset/ChangeLog b/tapset/ChangeLog index f25db410..46e15fd6 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,8 @@ +2008-09-17 Mark Wielaard + + * aux_syscalls.stp: Removed commented out code. Removed unneeded + unpure embedded C-code. + 2008-09-15 Mark Wielaard * x86_64/syscalls.stp (syscall.vm86_warning): Add argstr. diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index f79acaf0..6ef9ed1e 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -134,13 +134,10 @@ function _struct_compat_utimbuf_modtime:long(uaddr:long) #endif %} -%{ -#define STP_UTIME_NOW ((1l << 30) - 1l) -#define STP_UTIME_OMIT ((1l << 30) - 2l) -%} - function _struct_timespec_u:string(uaddr:long, n:long) %{ /* pure */ +#define STP_UTIME_NOW ((1l << 30) - 1l) +#define STP_UTIME_OMIT ((1l << 30) - 2l) int n = (int)THIS->n; struct timespec ts[n]; char *ptr = (char *)(unsigned long)THIS->uaddr; @@ -168,10 +165,14 @@ function _struct_timespec_u:string(uaddr:long, n:long) } } } +#undef STP_UTIME_NOW +#undef STP_UTIME_OMIT %} function _struct_compat_timespec_u:string(uaddr:long, n:long) %{ /* pure */ #ifdef CONFIG_COMPAT +#define STP_UTIME_NOW ((1l << 30) - 1l) +#define STP_UTIME_OMIT ((1l << 30) - 2l) int n = (int)THIS->n; struct compat_timespec ts[n]; char *ptr = (char *)(unsigned long)THIS->uaddr; @@ -199,6 +200,8 @@ function _struct_compat_timespec_u:string(uaddr:long, n:long) } } } +#undef STP_UTIME_NOW +#undef STP_UTIME_OMIT #endif %} @@ -256,16 +259,31 @@ function _struct_compat_itimerval_u:string(uaddr:long) #endif %} - %{ -#include +// Needed for function _struct_sockaddr_u. Unfortunately cannot be +// inlined into the function since these header files define static +// functions themselves. #include #include +#include +%} + +function _struct_sockaddr_u:string(uaddr:long, len:long) +%{ /* pure */ +#include #include #include -#include #include + char *ptr = (char *)(unsigned long)THIS->uaddr; + if (ptr == NULL) + strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN); + else { + char buf[128]; + size_t len = THIS->len < 128 ? THIS->len : 128; + if(_stp_copy_from_user(buf, ptr, len)) + strlcpy (THIS->__retvalue, "[...]", MAXSTRINGLEN); + else { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) #define LPORT (inet->inet.num) #define DADDR (&inet->inet.daddr) @@ -274,10 +292,9 @@ function _struct_compat_itimerval_u:string(uaddr:long) #define DADDR (&inet->daddr) #endif -//FIXME. Not done yet. - -void _stp_sockaddr_str(char *str, const int strlen, char *buf, int len) -{ + //FIXME. Not done yet. + char *str = THIS->__retvalue; + const int strlen = MAXSTRINGLEN; struct sockaddr *sa = (struct sockaddr *)buf; if ((sa->sa_family == AF_INET)&&(len == sizeof(struct sockaddr_in))) { @@ -321,29 +338,15 @@ void _stp_sockaddr_str(char *str, const int strlen, char *buf, int len) { if (len >= sizeof(sa_family_t)) { - snprintf(str, strlen, "{unknown sockaddr with sa=%d, salen=%d}", sa->sa_family, len); + snprintf(str, strlen, "{unknown sockaddr with sa=%d, salen=%d}", sa->sa_family, (int) len); } else { - snprintf(str, strlen, "{unknown sockaddr with salen=%d}", len); + snprintf(str, strlen, "{unknown sockaddr with salen=%d}", (int)len); } } -} -%} - -function _struct_sockaddr_u:string(uaddr:long, len:long) -%{ /* pure */ - char *ptr = (char *)(unsigned long)THIS->uaddr; - if (ptr == NULL) - strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN); - else { - char buf[128]; - size_t len = THIS->len < 128 ? THIS->len : 128; - if(_stp_copy_from_user(buf, ptr, len)) - strlcpy (THIS->__retvalue, "[...]", MAXSTRINGLEN); - else - _stp_sockaddr_str(THIS->__retvalue, MAXSTRINGLEN, buf, len); } +} %} function _struct_rlimit_u:string(uaddr:long) @@ -518,124 +521,6 @@ function __get_compat_argv:string(a:long, first:long) #endif %} -/* - * Return a integer member value of struct - * timezone user space pointer parameter - * CALLERS: - * syscall.gettimeofday - * syscall.settimeofday - */ -/* -function __uget_tz_m:long(u_addr:long,member:long) -%{ - struct timezone tz; - char *ptr = (char *)(unsigned long)THIS->u_addr; - size_t sz = sizeof(struct timezone); - - if(copy_from_user(&tz,ptr,sz)) - THIS->__retvalue = -EFAULT; - else if(THIS->member == 0) - THIS->__retvalue = tz.tz_minuteswest; - else - THIS->__retvalue = tz.tz_dsttime; -%} -*/ -/* - * Return integer member value of struct - * timex user space pointer parameter - * CALLERS: - * syscall.adjtimex - */ -/* -function __uget_timex_m:long(u_addr:long,member:long) -%{ - struct timex tx; - char *ptr = (char *)(unsigned long)THIS->u_addr; - size_t sz = sizeof(struct timex); - - if(copy_from_user(&tx,ptr,sz)) { - THIS->__retvalue = -EFAULT; - } else - switch(THIS->member) { - case 0: THIS->__retvalue = tx.modes; - break; - case 1: THIS->__retvalue = tx.offset; - break; - case 2: THIS->__retvalue = tx.freq; - break; - case 3: THIS->__retvalue = tx.maxerror; - break; - case 4: THIS->__retvalue = tx.esterror; - break; - case 5: THIS->__retvalue = tx.status; - break; - case 6: THIS->__retvalue = tx.constant; - break; - case 7: THIS->__retvalue = tx.precision; - break; - case 8: THIS->__retvalue = tx.tolerance; - break; - case 9: THIS->__retvalue = tx.time.tv_sec; - break; - case 10: THIS->__retvalue = tx.time.tv_usec; - break; - case 11: THIS->__retvalue = tx.tick; - break; - default: THIS->__retvalue = -1; - } -%} -*/ -/* - * Return the clock_t member value of the - * struct tms user space pointer parameter - * CALLERS: - * syscall.times - */ -/* -%{ #include %} -function __uget_tms_m:long(u_addr:long,member:long) -%{ - struct tms tms; - char *ptr = (char *)(unsigned long)THIS->u_addr; - size_t sz = sizeof(struct tms); - - if(copy_from_user(&tms,ptr,sz)) - THIS->__retvalue = -EFAULT; - switch(THIS->member) { - case 0: THIS->__retvalue = tms.tms_utime; - break; - case 1: THIS->__retvalue = tms.tms_stime; - break; - case 2: THIS->__retvalue = tms.tms_cutime; - break; - case 3: THIS->__retvalue = tms.tms_cstime; - break; - default: THIS->__retvalue = -1; - } -%} -*/ -/* - * Return a time_t / long member value of the - * struct timespec user space pointer parameter - * CALLERS: - * syscall.nanosleep - */ -/* -function __uget_ts_m:long(u_addr:long,member:long) -%{ - struct timespec ts; - char *ptr = (char *)(unsigned long)THIS->u_addr; - size_t sz = sizeof(struct timespec); - - if(copy_from_user(&ts,ptr,sz)) - THIS->__retvalue = -EFAULT; - else if(THIS->member == 0) - THIS->__retvalue = ts.tv_sec; - else - THIS->__retvalue = ts.tv_nsec; -%} -*/ - /* * Return the symbolic string representation * of the struct timex.mode member of adjtimex @@ -915,13 +800,10 @@ function _recvflags_str(f) { return substr(bs,0,strlen(bs)-1) } -%{ -#include -%} - /* `man mlockall` for more information */ function _mlockall_flags_str:string(flags:long) %{ /* pure */ + #include int len; long f = THIS->flags; char *str = THIS->__retvalue; @@ -973,11 +855,9 @@ function _shutdown_how_str(how) { return sprintf("UNKNOWN VALUE: %d", how) } -%{ -#include -%} function _reboot_magic_str:string(magic:long) %{ /* pure */ + #include int magic = (int)THIS->magic; switch (magic) { case LINUX_REBOOT_MAGIC1: @@ -1756,6 +1636,7 @@ function _shmat_flags_str:string(f:long) %{ +#include const _stp_val_array const _stp_mprotect_list[] = { {0, "PROT_NONE"}, V(PROT_READ), @@ -1772,6 +1653,7 @@ function _mprotect_prot_str:string(prot:long) %} %{ +#include const _stp_val_array const _stp_mmap_list[] = { V(MAP_SHARED), V(MAP_PRIVATE), -- cgit From 66fc44b2df24bf0229def28be9126cefa945c6a0 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 17 Sep 2008 16:48:54 +0200 Subject: Don't try including unnecessary asm/page.h in swap.c test. --- testsuite/systemtap.syscall/ChangeLog | 4 ++++ testsuite/systemtap.syscall/swap.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/testsuite/systemtap.syscall/ChangeLog b/testsuite/systemtap.syscall/ChangeLog index 0a3d51ae..ca123564 100644 --- a/testsuite/systemtap.syscall/ChangeLog +++ b/testsuite/systemtap.syscall/ChangeLog @@ -1,3 +1,7 @@ +2008-09-17 Mark Wielaard + + * swap.c: Don't try including unnecessary asm/page.h. + 2008-02-22 Frank Ch. Eigler * test.tcl: Support noexec /tmp by creating test directory diff --git a/testsuite/systemtap.syscall/swap.c b/testsuite/systemtap.syscall/swap.c index a2db301e..3708a477 100755 --- a/testsuite/systemtap.syscall/swap.c +++ b/testsuite/systemtap.syscall/swap.c @@ -1,6 +1,5 @@ /* COVERAGE: swapon swapoff */ #include -#include #include -- cgit From 3aa3a6bd7ff9730cbca2d695b4380e62f50adf31 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 17 Sep 2008 17:23:06 +0200 Subject: Timer id in timer.c test can be arbitrary number. --- testsuite/systemtap.syscall/ChangeLog | 4 ++++ testsuite/systemtap.syscall/timer.c | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/testsuite/systemtap.syscall/ChangeLog b/testsuite/systemtap.syscall/ChangeLog index ca123564..768b5c21 100644 --- a/testsuite/systemtap.syscall/ChangeLog +++ b/testsuite/systemtap.syscall/ChangeLog @@ -1,3 +1,7 @@ +2008-09-17 Mark Wielaard + + * timer.c: Timer id can be arbitrary number. + 2008-09-17 Mark Wielaard * swap.c: Don't try including unnecessary asm/page.h. diff --git a/testsuite/systemtap.syscall/timer.c b/testsuite/systemtap.syscall/timer.c index f7b888ae..947f6a77 100644 --- a/testsuite/systemtap.syscall/timer.c +++ b/testsuite/systemtap.syscall/timer.c @@ -16,16 +16,16 @@ int main() // timer_create (CLOCK_REALTIME, 0x[0]+, XXXX) syscall(SYS_timer_gettime, tid, &val); - // timer_gettime (0, XXXX) + // timer_gettime (NNNN, XXXX) syscall(SYS_timer_settime, 0, tid, &val, &oval); - // timer_settime (0, 0, \[0.000000,0.000000\], XXXX) + // timer_settime (0, NNNN, \[0.000000,0.000000\], XXXX) syscall(SYS_timer_getoverrun, tid); - // timer_getoverrun (0) + // timer_getoverrun (NNNN) syscall(SYS_timer_delete, tid); - // timer_delete (0) + // timer_delete (NNNN) return 0; } -- cgit From 8844346125b135280bee9fee12cbdbceb750d898 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 17 Sep 2008 17:58:58 +0200 Subject: Low byte of clone flags is always set to SIGCHLD in forkwait.c test. --- testsuite/systemtap.syscall/ChangeLog | 4 ++++ testsuite/systemtap.syscall/forkwait.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/testsuite/systemtap.syscall/ChangeLog b/testsuite/systemtap.syscall/ChangeLog index 768b5c21..772f980a 100644 --- a/testsuite/systemtap.syscall/ChangeLog +++ b/testsuite/systemtap.syscall/ChangeLog @@ -1,3 +1,7 @@ +2008-09-17 Mark Wielaard + + * forkwait.c: Low byte of flags is always set to SIGCHLD. + 2008-09-17 Mark Wielaard * timer.c: Timer id can be arbitrary number. diff --git a/testsuite/systemtap.syscall/forkwait.c b/testsuite/systemtap.syscall/forkwait.c index 10f8d6ac..ffc98708 100644 --- a/testsuite/systemtap.syscall/forkwait.c +++ b/testsuite/systemtap.syscall/forkwait.c @@ -12,7 +12,7 @@ int main () int status; child = fork(); - // clone (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID) = NNNN + // clone (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD) = NNNN if (!child) { int i = 0xfffff; while (i > 0) i--; -- cgit From 7ef27e8ab9c7921350fd32af5c4b4d86205ca34b Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Wed, 17 Sep 2008 15:20:07 -0400 Subject: PR 6487, 6504: robustify __stp_print_flush --- runtime/ChangeLog | 6 +++ runtime/print_new.c | 6 +-- runtime/transport/ChangeLog | 6 +++ runtime/transport/utt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ runtime/transport/utt.h | 36 +++++++++++++++++ 5 files changed, 145 insertions(+), 3 deletions(-) diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 6ad7e51f..e5594783 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,9 @@ +2008-09-17 Frank Ch. Eigler + + PR 6487, 6504. + From Masami Hiramatsu + * print_new.c (stp_print_flush): Use new utt_reserve(). + 2008-09-12 Masami Hiramatsu BZ 6028 diff --git a/runtime/print_new.c b/runtime/print_new.c index 07af2e33..4136ecbe 100644 --- a/runtime/print_new.c +++ b/runtime/print_new.c @@ -34,13 +34,13 @@ void EXPORT_FN(stp_print_flush) (_stp_pbuf *pb) #ifdef STP_BULKMODE { #ifdef NO_PERCPU_HEADERS - void *buf = relay_reserve(_stp_utt->rchan, len); + void *buf = utt_reserve(_stp_utt, len); if (likely(buf)) memcpy(buf, pb->buf, len); else atomic_inc (&_stp_transport_failures); #else - void *buf = relay_reserve(_stp_utt->rchan, + void *buf = utt_reserve(_stp_utt, sizeof(struct _stp_trace) + len); if (likely(buf)) { struct _stp_trace t = { .sequence = _stp_seq_inc(), @@ -56,7 +56,7 @@ void EXPORT_FN(stp_print_flush) (_stp_pbuf *pb) void *buf; unsigned long flags; spin_lock_irqsave(&_stp_print_lock, flags); - buf = relay_reserve(_stp_utt->rchan, len); + buf = utt_reserve(_stp_utt, len); if (likely(buf)) memcpy(buf, pb->buf, len); else diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index 693f06d1..42c6fc2a 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,9 @@ +2008-09-17 Frank Ch. Eigler + + PR 6487, 6504. + From Masami Hiramatsu + * utt.c (utt_switch_subbof, _utt_wakeup*, utt_reserve): New. + 2008-07-17 Frank Ch. Eigler * symbols.c (_stp_do_relocation): Adapt to stp_module decl changes. diff --git a/runtime/transport/utt.c b/runtime/transport/utt.c index 182c1178..b8281bb4 100644 --- a/runtime/transport/utt.c +++ b/runtime/transport/utt.c @@ -31,6 +31,96 @@ static int utt_overwrite_flag = 0; +/* + * utt_switch_subbuf - switch to a new sub-buffer + * + * Most of this function is deadcopy of relay_switch_subbuf. + */ +size_t utt_switch_subbuf(struct utt_trace *utt, struct rchan_buf *buf, + size_t length) +{ + void *old, *new; + size_t old_subbuf, new_subbuf; + + if (unlikely(buf == NULL)) + return 0; + + if (unlikely(length > buf->chan->subbuf_size)) + goto toobig; + + if (buf->offset != buf->chan->subbuf_size + 1) { + buf->prev_padding = buf->chan->subbuf_size - buf->offset; + old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs; + buf->padding[old_subbuf] = buf->prev_padding; + buf->subbufs_produced++; + buf->dentry->d_inode->i_size += buf->chan->subbuf_size - + buf->padding[old_subbuf]; + smp_mb(); + if (waitqueue_active(&buf->read_wait)) + /* + * Calling wake_up_interruptible() and __mod_timer() + * from here will deadlock if we happen to be logging + * from the scheduler and timer (trying to re-grab + * rq->lock/timer->base->lock), so just set a flag. + */ + atomic_set(&utt->wakeup, 1); + } + + old = buf->data; + new_subbuf = buf->subbufs_produced % buf->chan->n_subbufs; + new = buf->start + new_subbuf * buf->chan->subbuf_size; + buf->offset = 0; + if (!buf->chan->cb->subbuf_start(buf, new, old, buf->prev_padding)) { + buf->offset = buf->chan->subbuf_size + 1; + return 0; + } + buf->data = new; + buf->padding[new_subbuf] = 0; + + if (unlikely(length + buf->offset > buf->chan->subbuf_size)) + goto toobig; + + return length; + +toobig: + buf->chan->last_toobig = length; + return 0; +} + +static void __utt_wakeup_readers(struct rchan_buf *buf) +{ + if (buf && waitqueue_active(&buf->read_wait) && + buf->subbufs_produced != buf->subbufs_consumed) + wake_up_interruptible(&buf->read_wait); +} + +static void __utt_wakeup_timer(unsigned long val) +{ + struct utt_trace *utt = (struct utt_trace *)val; + int i; + + if (atomic_read(&utt->wakeup)) { + atomic_set(&utt->wakeup, 0); + if (utt->is_global) + __utt_wakeup_readers(utt->rchan->buf[0]); + else + for_each_possible_cpu(i) + __utt_wakeup_readers(utt->rchan->buf[i]); + } + + mod_timer(&utt->timer, jiffies + UTT_TIMER_INTERVAL); +} + +static void __utt_timer_init(struct utt_trace * utt) +{ + atomic_set(&utt->wakeup, 0); + init_timer(&utt->timer); + utt->timer.expires = jiffies + UTT_TIMER_INTERVAL; + utt->timer.function = __utt_wakeup_timer; + utt->timer.data = (unsigned long)utt; + add_timer(&utt->timer); +} + void utt_set_overwrite(int overwrite) { utt_overwrite_flag = overwrite; @@ -241,6 +331,8 @@ struct utt_trace *utt_trace_setup(struct utt_trace_setup *utts) goto err; utt->rchan->private_data = utt; + utt->is_global = utts->is_global; + utt->trace_state = Utt_trace_setup; utts->err = 0; @@ -274,6 +366,7 @@ int utt_trace_startstop(struct utt_trace *utt, int start, utt->trace_state == Utt_trace_stopped) { if (trace_seq) (*trace_seq)++; + __utt_timer_init(utt); smp_mb(); utt->trace_state = Utt_trace_running; ret = 0; @@ -281,6 +374,7 @@ int utt_trace_startstop(struct utt_trace *utt, int start, } else { if (utt->trace_state == Utt_trace_running) { utt->trace_state = Utt_trace_stopped; + del_timer_sync(&utt->timer); relay_flush(utt->rchan); ret = 0; } diff --git a/runtime/transport/utt.h b/runtime/transport/utt.h index b2c9fa9f..fd704009 100644 --- a/runtime/transport/utt.h +++ b/runtime/transport/utt.h @@ -15,11 +15,18 @@ struct utt_trace { atomic_t dropped; struct dentry *utt_tree_root; /* systemtap */ void *private_data; + atomic_t wakeup; + struct timer_list timer; + int is_global; }; #define UTT_TRACE_ROOT_NAME_SIZE 64 /* Largest string for a root dir identifier */ #define UTT_TRACE_NAME_SIZE 64 /* Largest string for a trace identifier */ +#ifndef UTT_TIMER_INTERVAL +#define UTT_TIMER_INTERVAL ((HZ + 99) / 100) /* Wakeup timer interval in jiffies (default 10 ms)*/ +#endif + /* * User setup structure */ @@ -39,4 +46,33 @@ extern int utt_trace_startstop(struct utt_trace *utt, int start, extern void utt_trace_cleanup(struct utt_trace *utt); extern int utt_trace_remove(struct utt_trace *utt); +#ifndef STP_OLD_TRANSPORT +extern size_t utt_switch_subbuf(struct utt_trace *utt, struct rchan_buf *buf, + size_t length); +/** + * utt_reserve - reserve slot in channel buffer + * @utt: utt channel + * @length: number of bytes to reserve + * + * Returns pointer to reserved slot, NULL if full. + * + * This function is utt_switch_subbuf version of relay_reserve. + */ +static inline void *utt_reserve(struct utt_trace *utt, size_t length) +{ + void *reserved; + struct rchan_buf *buf = utt->rchan->buf[smp_processor_id()]; + + if (unlikely(buf->offset + length > buf->chan->subbuf_size)) { + length = utt_switch_subbuf(utt, buf, length); + if (!length) + return NULL; + } + reserved = buf->data + buf->offset; + buf->offset += length; + + return reserved; +} +#endif + #endif -- cgit From 0387bde4d7cb9853a93af0d266330dea7938b506 Mon Sep 17 00:00:00 2001 From: David Smith Date: Thu, 18 Sep 2008 16:23:12 -0500 Subject: Fix PR 6903 by checking for the real uid, not the euid. 2008-09-18 David Smith PR 6903. * staprun_funcs.c (check_permissions): Instead of checking the effective uid, check the real uid for root permissions. --- runtime/staprun/ChangeLog | 6 ++++++ runtime/staprun/staprun_funcs.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog index 21e02e47..c6d75106 100644 --- a/runtime/staprun/ChangeLog +++ b/runtime/staprun/ChangeLog @@ -1,3 +1,9 @@ +2008-09-18 David Smith + + PR 6903. + * staprun_funcs.c (check_permissions): Instead of checking the + effective uid, check the real uid for root permissions. + 2008-09-06 Frank Ch. Eigler * mainloop.c (start_cmd): Rewrite to use wordexp/execvp/ptrace. diff --git a/runtime/staprun/staprun_funcs.c b/runtime/staprun/staprun_funcs.c index 8fa95e45..5e7fa102 100644 --- a/runtime/staprun/staprun_funcs.c +++ b/runtime/staprun/staprun_funcs.c @@ -307,7 +307,7 @@ int check_permissions(void) int path_check = 0; /* If we're root, we can do anything. */ - if (geteuid() == 0) + if (getuid() == 0) return 1; /* Lookup the gid for group "stapdev" */ -- cgit From e8ea4501122483436cdeb0352d833ccefeda7d14 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 18 Sep 2008 23:33:06 +0200 Subject: Moved reboot.h include out of _reboot_magic_str in aux_syscalls.stp. --- tapset/ChangeLog | 4 ++++ tapset/aux_syscalls.stp | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tapset/ChangeLog b/tapset/ChangeLog index 46e15fd6..94531989 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,7 @@ +2008-09-18 Mark Wielaard + + * aux_syscalls.stp (_reboot_magic_str): Moved reboot.h include out. + 2008-09-17 Mark Wielaard * aux_syscalls.stp: Removed commented out code. Removed unneeded diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index 6ef9ed1e..a748a132 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -855,9 +855,15 @@ function _shutdown_how_str(how) { return sprintf("UNKNOWN VALUE: %d", how) } +%{ +// Needed for function __reboot_magic_str:string. Unfortunately cannot +// be inlined into the function since these header file defines static +// functions on some architectures. +#include +%} + function _reboot_magic_str:string(magic:long) %{ /* pure */ - #include int magic = (int)THIS->magic; switch (magic) { case LINUX_REBOOT_MAGIC1: -- cgit