From 1f0cfd980bc0a5e3e360f4ee46808b239bca6b55 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 16 Dec 2008 10:34:01 -0500 Subject: Convert .mark to .statement(0x) instead of .statement(foo.c:N) --- runtime/ChangeLog | 4 ++ runtime/sduprobes.h | 119 ++++++++++++++++++++++++---------------------------- 2 files changed, 59 insertions(+), 64 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 3f88bae2..7026b276 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,7 @@ +2008-12-16 Stan Cox + + * sduprobes.h (STAP_PROBE): Add synthetic reference to probe label. + 2008-12-09 Frank Ch. Eigler * time.c (_stp_gettimeofday_ns): Protect some more against freq=0. diff --git a/runtime/sduprobes.h b/runtime/sduprobes.h index b91dea93..efa25be7 100644 --- a/runtime/sduprobes.h +++ b/runtime/sduprobes.h @@ -9,23 +9,23 @@ #include #if _LP64 -#define STAP_PROBE_STRUCT_ARG \ - __uint64_t probe_arg; +#define STAP_PROBE_STRUCT_ARG(arg) \ + __uint64_t arg; #else -#define STAP_PROBE_STRUCT_ARG \ - long probe_arg __attribute__ ((aligned(8))); +#define STAP_PROBE_STRUCT_ARG(arg) \ + long arg __attribute__ ((aligned(8))); #endif #define STAP_PROBE_STRUCT(probe,type,argc) \ struct _probe_ ## probe \ { \ char probe_name [strlen(#probe)+1]; \ - int probe_type; \ - STAP_PROBE_STRUCT_ARG \ + int probe_type; \ + STAP_PROBE_STRUCT_ARG (probe_arg); \ }; \ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {#probe,type,argc}; -#ifndef USE_STAP_DEBUGINFO_PROBE +#ifdef USE_STAP_PROBE #define STAP_PROBE(provider,probe) \ STAP_PROBE_STRUCT(probe,0,0) \ _stap_probe_0 (_probe_ ## probe.probe_name); @@ -34,108 +34,99 @@ struct _probe_ ## probe \ _probe_ ## probe: \ asm volatile ("nop"); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - asm volatile ("# %0" :: "m" ((_probe_ ## probe.probe_type))); + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe; #endif -#ifndef USE_STAP_DEBUGINFO_PROBE +#ifdef USE_STAP_PROBE #define STAP_PROBE1(provider,probe,arg1) \ STAP_PROBE_STRUCT(probe,0,1) \ _stap_probe_1 (_probe_ ## probe.probe_name,(size_t)arg1); #else #define STAP_PROBE1(provider,probe,parm1) \ + volatile typeof(parm1) probe ## _arg1 = parm1; \ _probe_ ## probe: \ - asm volatile ("nop"); \ - volatile typeof(parm1) arg1 = parm1; \ + asm volatile ("nop" :: "r"(probe ## _arg1)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - asm volatile ("# %0" :: "r"(arg1)); \ - asm volatile ("# %0" :: "m" ((_probe_ ## probe.probe_type))); + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe; #endif -#ifndef USE_STAP_DEBUGINFO_PROBE +#ifdef USE_STAP_PROBE #define STAP_PROBE2(provider,probe,arg1,arg2) \ STAP_PROBE_STRUCT(probe,0,2) \ _stap_probe_2 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2); #else #define STAP_PROBE2(provider,probe,parm1,parm2) \ + volatile typeof(parm1) probe ## _arg1 = parm1; \ + volatile typeof(parm2) probe ## _arg2 = parm2; \ _probe_ ## probe: \ - asm volatile ("nop"); \ - volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ + asm volatile ("nop" :: "r"(probe ## _arg1), "r"(probe ## _arg2)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe)\ - asm volatile ("# %0" :: "r"(arg1)); \ - asm volatile ("# %0" :: "r"(arg2)); \ - asm volatile ("# %0" :: "m" ((_probe_ ## probe.probe_type))); + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe; #endif -#ifndef USE_STAP_DEBUGINFO_PROBE +#ifdef USE_STAP_PROBE #define STAP_PROBE3(provider,probe,arg1,arg2,arg3) \ STAP_PROBE_STRUCT(probe,0,3) \ _stap_probe_3 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3); #else #define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ + volatile typeof(parm1) probe ## _arg1 = parm1; \ + volatile typeof(parm2) probe ## _arg2 = parm2; \ + volatile typeof(parm3) probe ## _arg3 = parm3; \ _probe_ ## probe: \ - asm volatile ("nop"); \ - volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ + asm volatile ("nop" :: "r"(probe ## _arg1), "r"(probe ## _arg2), "r"(probe ## _arg3)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - asm volatile ("# %0" :: "r"(arg1)); \ - asm volatile ("# %0" :: "r"(arg2)); \ - asm volatile ("# %0" :: "r"(arg3)); \ - asm volatile ("# %0" :: "m" ((_probe_ ## probe.probe_type))); + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe; #endif -#ifndef USE_STAP_DEBUGINFO_PROBE +#ifdef USE_STAP_PROBE #define STAP_PROBE4(provider,probe,arg1,arg2,arg3,arg4) \ STAP_PROBE_STRUCT(probe,0,4) \ _stap_probe_4 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4); #else -#define STAP_PROBE4(provider,probe,parm1,parm2,parm3) \ +#define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ + volatile typeof(parm1) probe ## _arg1 = parm1; \ + volatile typeof(parm2) probe ## _arg2 = parm2; \ + volatile typeof(parm3) probe ## _arg3 = parm3; \ + volatile typeof(parm4) probe ## _arg4 = parm4; \ _probe_ ## probe: \ - asm volatile ("nop"); \ - volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ - volatile typeof(parm4) arg4 = parm4; \ + asm volatile ("nop" "r"(probe ## _arg1), "r"(probe ## _arg2), "r"(probe ## _arg3), "r"(probe ## _arg4)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - asm volatile ("# %0" :: "r"(arg1)); \ - asm volatile ("# %0" :: "r"(arg2)); \ - asm volatile ("# %0" :: "r"(arg3)); \ - asm volatile ("# %0" :: "r"(arg4)); \ - asm volatile ("# %0" :: "m" ((_probe_ ## probe.probe_type))); + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe; #endif -#ifndef USE_STAP_DEBUGINFO_PROBE +#ifdef USE_STAP_PROBE #define STAP_PROBE5(provider,probe,arg1,arg2,arg3,arg4,arg5) \ STAP_PROBE_STRUCT(probe,0,5) \ _stap_probe_5 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5); #else #define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ + volatile typeof(parm1) probe ## _arg1 = parm1; \ + volatile typeof(parm2) probe ## _arg2 = parm2; \ + volatile typeof(parm3) probe ## _arg3 = parm3; \ + volatile typeof(parm4) probe ## _arg4 = parm4; \ + volatile typeof(parm5) probe ## _arg5 = parm5; \ _probe_ ## probe: \ - asm volatile ("nop"); \ - volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ - volatile typeof(parm4) arg4 = parm4; \ - volatile typeof(parm5) arg5 = parm5; \ + asm volatile ("nop" "r"(probe ## _arg1), "r"(probe ## _arg2), "r"(probe ## _arg3), "r"(probe ## _arg4), "r"(probe ## _arg5)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - asm volatile ("# %0" :: "r"(arg1)); \ - asm volatile ("# %0" :: "r"(arg2)); \ - asm volatile ("# %0" :: "r"(arg3)); \ - asm volatile ("# %0" :: "r"(arg4)); \ - asm volatile ("# %0" :: "r"(arg5)); \ - asm volatile ("# %0" :: "m" ((_probe_ ## probe.probe_type))); + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe; #endif -#define DTRACE_PROBE1(provider,probe,parm1,parm2,parm3,parm4,parm5) \ -STAP_PROBE1(provider,probe,parm1,parm2,parm3,parm4,parm5) -#define DTRACE_PROBE2(provider,probe,parm1,parm2,parm3,parm4,parm5) \ -STAP_PROBE2(provider,probe,parm1,parm2,parm3,parm4,parm5) -#define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3,parm4,parm5) \ -STAP_PROBE3(provider,probe,parm1,parm2,parm3,parm4,parm5) -#define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4,parm5) \ -STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4,parm5) -#define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ -STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) +#define DTRACE_PROBE(provider,probe) \ +STAP_PROBE(provider,probe) +#define DTRACE_PROBE1(provider,probe,parm1) \ +STAP_PROBE1(provider,probe,parm1) +#define DTRACE_PROBE2(provider,probe,parm1,parm2) \ +STAP_PROBE2(provider,probe,parm1,parm2) +#define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \ +STAP_PROBE3(provider,probe,parm1,parm2,parm3) +#define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ +STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) -- cgit From 30c94a80d5f7bef33450bd1a7e090c8e99b6db89 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Fri, 19 Dec 2008 10:03:35 -0500 Subject: First attempt at printf kernel memory hex dump --- runtime/vsprintf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c index 831b7a2b..fbd90a83 100644 --- a/runtime/vsprintf.c +++ b/runtime/vsprintf.c @@ -283,6 +283,7 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) continue; case 's': + case 'M': case 'm': s = va_arg(args, char *); if ((unsigned long)s < PAGE_SIZE) @@ -303,8 +304,12 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) } } for (i = 0; i < len; ++i) { - if (str <= end) + if (str <= end) { + if (*fmt == 'M') + str = number(str, str + 2, (uint64_t)(unsigned char) *s, 16, 2, 2, STP_SPACE); + else *str = *s; + } ++str; ++s; } while (len < field_width--) { -- cgit From 51d997112e435da6fc84713ef09908b3b8659798 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Fri, 19 Dec 2008 17:00:51 -0500 Subject: Better implementation for %M --- runtime/vsprintf.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'runtime') diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c index fbd90a83..60852872 100644 --- a/runtime/vsprintf.c +++ b/runtime/vsprintf.c @@ -283,7 +283,7 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) continue; case 's': - case 'M': + case 'M': case 'm': s = va_arg(args, char *); if ((unsigned long)s < PAGE_SIZE) @@ -303,15 +303,23 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++str; } } - for (i = 0; i < len; ++i) { - if (str <= end) { - if (*fmt == 'M') - str = number(str, str + 2, (uint64_t)(unsigned char) *s, 16, 2, 2, STP_SPACE); - else - *str = *s; - } - ++str; ++s; + if (*fmt == 'M') { + str = number(str, str + len - 1 < end ? str + len - 1 : end, + (unsigned long) *(uint64_t *) s, + 16, field_width, len, flags); + } + else { + for (i = 0; i < len; ++i) { + if (str <= end) { + //if (*fmt == 'M') + //str = number(str, str + 2, (uint64_t)(unsigned char) *s, 16, 2, 2, STP_SPACE); + //else + *str = *s; + } + ++str; ++s; + } } + while (len < field_width--) { if (str <= end) *str = ' '; @@ -323,7 +331,6 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++str; } continue; - case 'X': flags |= STP_LARGE; case 'x': -- cgit From 5fab0487aa45893289ad9a688a513eb7925f5133 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Fri, 19 Dec 2008 17:03:20 -0500 Subject: Removed left over remnant from previous implementation --- runtime/vsprintf.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'runtime') diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c index 60852872..2c3067cf 100644 --- a/runtime/vsprintf.c +++ b/runtime/vsprintf.c @@ -311,9 +311,6 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) else { for (i = 0; i < len; ++i) { if (str <= end) { - //if (*fmt == 'M') - //str = number(str, str + 2, (uint64_t)(unsigned char) *s, 16, 2, 2, STP_SPACE); - //else *str = *s; } ++str; ++s; -- cgit From a688cff28de458448f40584acfa5f22d7e444471 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Sun, 21 Dec 2008 22:48:38 -0500 Subject: Put a block around the probe point. --- runtime/ChangeLog | 4 ++++ runtime/sduprobes.h | 51 ++++++++++++++++++++++++++------------------------- 2 files changed, 30 insertions(+), 25 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 7026b276..ca852d53 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,7 @@ +2008-12-21 Stan Cox + + * sduprobes.h (STAP_PROBE): Put block around probe point. + 2008-12-16 Stan Cox * sduprobes.h (STAP_PROBE): Add synthetic reference to probe label. diff --git a/runtime/sduprobes.h b/runtime/sduprobes.h index efa25be7..17c1be71 100644 --- a/runtime/sduprobes.h +++ b/runtime/sduprobes.h @@ -25,6 +25,7 @@ struct _probe_ ## probe \ }; \ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {#probe,type,argc}; +// The goto _probe_ prevents the label from "drifting" #ifdef USE_STAP_PROBE #define STAP_PROBE(provider,probe) \ STAP_PROBE_STRUCT(probe,0,0) \ @@ -45,12 +46,12 @@ _probe_ ## probe: \ _stap_probe_1 (_probe_ ## probe.probe_name,(size_t)arg1); #else #define STAP_PROBE1(provider,probe,parm1) \ - volatile typeof(parm1) probe ## _arg1 = parm1; \ + {volatile typeof(parm1) arg1 = parm1; \ _probe_ ## probe: \ - asm volatile ("nop" :: "r"(probe ## _arg1)); \ + asm volatile ("nop" :: "r"(arg1)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe; + goto _probe_ ## probe;} #endif @@ -60,13 +61,13 @@ _probe_ ## probe: \ _stap_probe_2 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2); #else #define STAP_PROBE2(provider,probe,parm1,parm2) \ - volatile typeof(parm1) probe ## _arg1 = parm1; \ - volatile typeof(parm2) probe ## _arg2 = parm2; \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ _probe_ ## probe: \ - asm volatile ("nop" :: "r"(probe ## _arg1), "r"(probe ## _arg2)); \ + asm volatile ("nop" :: "r"(arg1), "r"(arg2)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe)\ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe; + goto _probe_ ## probe;} #endif #ifdef USE_STAP_PROBE @@ -75,14 +76,14 @@ _probe_ ## probe: \ _stap_probe_3 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3); #else #define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ - volatile typeof(parm1) probe ## _arg1 = parm1; \ - volatile typeof(parm2) probe ## _arg2 = parm2; \ - volatile typeof(parm3) probe ## _arg3 = parm3; \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ + volatile typeof(parm3) arg3 = parm3; \ _probe_ ## probe: \ - asm volatile ("nop" :: "r"(probe ## _arg1), "r"(probe ## _arg2), "r"(probe ## _arg3)); \ + asm volatile ("nop" :: "r"(arg1), "r"(arg2), "r"(arg3)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe; + goto _probe_ ## probe;} #endif #ifdef USE_STAP_PROBE @@ -91,15 +92,15 @@ _probe_ ## probe: \ _stap_probe_4 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4); #else #define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ - volatile typeof(parm1) probe ## _arg1 = parm1; \ - volatile typeof(parm2) probe ## _arg2 = parm2; \ - volatile typeof(parm3) probe ## _arg3 = parm3; \ - volatile typeof(parm4) probe ## _arg4 = parm4; \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ + volatile typeof(parm3) arg3 = parm3; \ + volatile typeof(parm4) arg4 = parm4; \ _probe_ ## probe: \ - asm volatile ("nop" "r"(probe ## _arg1), "r"(probe ## _arg2), "r"(probe ## _arg3), "r"(probe ## _arg4)); \ + asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe; + goto _probe_ ## probe;} #endif #ifdef USE_STAP_PROBE @@ -108,16 +109,16 @@ _probe_ ## probe: \ _stap_probe_5 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5); #else #define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ - volatile typeof(parm1) probe ## _arg1 = parm1; \ - volatile typeof(parm2) probe ## _arg2 = parm2; \ - volatile typeof(parm3) probe ## _arg3 = parm3; \ - volatile typeof(parm4) probe ## _arg4 = parm4; \ - volatile typeof(parm5) probe ## _arg5 = parm5; \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ + volatile typeof(parm3) arg3 = parm3; \ + volatile typeof(parm4) arg4 = parm4; \ + volatile typeof(parm5) arg5 = parm5; \ _probe_ ## probe: \ - asm volatile ("nop" "r"(probe ## _arg1), "r"(probe ## _arg2), "r"(probe ## _arg3), "r"(probe ## _arg4), "r"(probe ## _arg5)); \ + asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5)); \ STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe; + goto _probe_ ## probe;} #endif #define DTRACE_PROBE(provider,probe) \ -- cgit From 96d683104121c80f344732d780ee9ee07e4f7981 Mon Sep 17 00:00:00 2001 From: Jim Keniston Date: Mon, 29 Dec 2008 12:53:46 -0500 Subject: PR7082: patch for uprobes1 (kernel <= 2.6.24) --- runtime/uprobes/uprobes.c | 78 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 11 deletions(-) (limited to 'runtime') diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c index 22d62ecc..9dfb82b9 100644 --- a/runtime/uprobes/uprobes.c +++ b/runtime/uprobes/uprobes.c @@ -453,13 +453,24 @@ static int quiesce_all_threads(struct uprobe_process *uproc, return survivors; } +static void utask_free_uretprobe_instances(struct uprobe_task *utask) +{ + struct uretprobe_instance *ri; + struct hlist_node *r1, *r2; + + hlist_for_each_entry_safe(ri, r1, r2, &utask->uretprobe_instances, + hlist) { + hlist_del(&ri->hlist); + kfree(ri); + uprobe_decref_process(utask->uproc); + } +} + /* Called with utask->uproc write-locked. */ static void uprobe_free_task(struct uprobe_task *utask) { struct deferred_registration *dr, *d; struct delayed_signal *ds, *ds2; - struct uretprobe_instance *ri; - struct hlist_node *r1, *r2; uprobe_unhash_utask(utask); list_del(&utask->list); @@ -473,12 +484,8 @@ static void uprobe_free_task(struct uprobe_task *utask) kfree(ds); } - hlist_for_each_entry_safe(ri, r1, r2, &utask->uretprobe_instances, - hlist) { - hlist_del(&ri->hlist); - kfree(ri); - uprobe_decref_process(utask->uproc); - } + utask_free_uretprobe_instances(utask); + kfree(utask); } @@ -809,6 +816,27 @@ static void purge_uprobe(struct uprobe_kimg *uk) uprobe_free_probept(ppt); } +/* TODO: Avoid code duplication with uprobe_validate_vaddr(). */ +static int uprobe_validate_vma(struct task_struct *t, unsigned long vaddr) +{ + struct vm_area_struct *vma; + struct mm_struct *mm; + int ret = 0; + + mm = get_task_mm(t); + if (!mm) + return -EINVAL; + down_read(&mm->mmap_sem); + vma = find_vma(mm, vaddr); + if (!vma || vaddr < vma->vm_start) + ret = -ENOENT; + else if (!(vma->vm_flags & VM_EXEC)) + ret = -EFAULT; + up_read(&mm->mmap_sem); + mmput(mm); + return ret; +} + /* Probed address must be in an executable VM area, outside the SSOL area. */ static int uprobe_validate_vaddr(struct task_struct *p, unsigned long vaddr, struct uprobe_process *uproc) @@ -1942,9 +1970,9 @@ done: /* * uproc's process is exiting or exec-ing, so zap all the (now irrelevant) - * probepoints. Runs with uproc->rwsem write-locked. Caller must ref-count - * uproc before calling this function, to ensure that uproc doesn't get - * freed in the middle of this. + * probepoints and uretprobe_instances. Runs with uproc->rwsem write-locked. + * Caller must ref-count uproc before calling this function, to ensure that + * uproc doesn't get freed in the middle of this. */ static void uprobe_cleanup_process(struct uprobe_process *uproc) { @@ -1953,6 +1981,7 @@ static void uprobe_cleanup_process(struct uprobe_process *uproc) struct hlist_node *pnode1, *pnode2; struct hlist_head *head; struct uprobe_kimg *uk, *unode; + struct uprobe_task *utask; uproc->finished = 1; @@ -1988,6 +2017,16 @@ static void uprobe_cleanup_process(struct uprobe_process *uproc) } } } + + /* + * Free uretprobe_instances. This is a nop on exit, since all + * the uprobe_tasks are already gone. We do this here on exec + * (as opposed to letting uprobe_free_process() take care of it) + * because uprobe_free_process() never gets called if we don't + * tick down the ref count here (PR #7082). + */ + list_for_each_entry(utask, &uproc->thread_list, list) + utask_free_uretprobe_instances(utask); } /* @@ -2134,6 +2173,23 @@ static int uprobe_fork_uproc(struct uprobe_process *parent_uproc, BUG_ON(!parent_uproc->uretprobe_trampoline_addr || IS_ERR(parent_uproc->uretprobe_trampoline_addr)); + ret = uprobe_validate_vma(child_tsk, + (unsigned long) parent_uproc->ssol_area.insn_area); + if (ret) { + int ret2; + printk(KERN_ERR "uprobes: Child %d failed to inherit" + " parent %d's SSOL vma at %p. Error = %d\n", + child_tsk->pid, parent_utask->tsk->pid, + parent_uproc->ssol_area.insn_area, ret); + ret2 = uprobe_validate_vma(parent_utask->tsk, + (unsigned long) parent_uproc->ssol_area.insn_area); + if (ret2 != 0) + printk(KERN_ERR "uprobes: Parent %d's SSOL vma" + " is no longer valid. Error = %d\n", + parent_utask->tsk->pid, ret2); + return ret; + } + if (!try_module_get(THIS_MODULE)) return -ENOSYS; child_uproc = uprobe_mk_process(child_tsk); -- cgit From 27053aa14ba234a0d5e1b4affd272a5c7b01aa1b Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 6 Jan 2009 17:06:30 -0500 Subject: PR9699: build fixes for kernel 2.6.28 --- runtime/ChangeLog | 5 +++++ runtime/autoconf-task-uid.c | 5 +++++ runtime/transport/ChangeLog | 5 +++++ runtime/transport/transport.c | 7 ++++++- 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 runtime/autoconf-task-uid.c (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index ca852d53..fad46be1 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,8 @@ +2009-01-06 Frank Ch. Eigler + + PR9699. + * autoconf-task-uid.c: New test. + 2008-12-21 Stan Cox * sduprobes.h (STAP_PROBE): Put block around probe point. diff --git a/runtime/autoconf-task-uid.c b/runtime/autoconf-task-uid.c new file mode 100644 index 00000000..5f5a321c --- /dev/null +++ b/runtime/autoconf-task-uid.c @@ -0,0 +1,5 @@ +#include + +struct task_struct *foo; +void bar () { foo->uid = 0; } +/* as opposed to linux/cred.h wrappers current_uid() etc. */ diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index c6dfa005..e8e2a047 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,8 @@ +2009-01-06 Frank Ch. Eigler + + PR9699. + * transport.c (_stp_transport_init): Adapt to task_struct cred switch. + 2008-11-28 Frank Ch. Eigler PR5947: make code -Wpointer-arith clean diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index 9f7a25f2..f5ee2c36 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -2,7 +2,7 @@ * transport.c - stp transport functions * * Copyright (C) IBM Corporation, 2005 - * Copyright (C) Red Hat Inc, 2005-2008 + * Copyright (C) Red Hat Inc, 2005-2009 * Copyright (C) Intel Corporation, 2006 * * This file is part of systemtap, and is free software. You can @@ -211,8 +211,13 @@ int _stp_transport_init(void) dbug_trans(1, "transport_init\n"); _stp_init_pid = current->pid; +#ifdef STAPCONF_TASK_UID _stp_uid = current->uid; _stp_gid = current->gid; +#else + _stp_uid = current_uid(); + _stp_gid = current_gid(); +#endif #ifdef RELAY_GUEST /* Guest scripts use relay only for reporting warnings and errors */ -- cgit From ec77429d7f3b6e5bc6bb8a93beb8dac6c6dd99b1 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 6 Jan 2009 19:30:17 -0500 Subject: PR9699: tweak autoconf file for Strict C Language Standards Compliance (tm) --- runtime/autoconf-task-uid.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/autoconf-task-uid.c b/runtime/autoconf-task-uid.c index 5f5a321c..8e40f831 100644 --- a/runtime/autoconf-task-uid.c +++ b/runtime/autoconf-task-uid.c @@ -1,5 +1,6 @@ #include -struct task_struct *foo; -void bar () { foo->uid = 0; } +int bar (struct task_struct *foo) { + return (foo->uid = 0); +} /* as opposed to linux/cred.h wrappers current_uid() etc. */ -- cgit From 50431f30cac19c57f53bdfe0fd138cdc2dcfa2f9 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 11 Jan 2009 14:37:28 +0100 Subject: Pick up --prefix dependency usage in config.h. --- runtime/staprun/ChangeLog | 4 ++++ runtime/staprun/staprun.h | 3 +++ 2 files changed, 7 insertions(+) (limited to 'runtime') diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog index 3611b55e..6c2304ce 100644 --- a/runtime/staprun/ChangeLog +++ b/runtime/staprun/ChangeLog @@ -1,3 +1,7 @@ +2008-01-11 Mark Wielaard + + * staprun.h: include config.h for dependency. + 2008-12-08 Frank Ch. Eigler PR7062 diff --git a/runtime/staprun/staprun.h b/runtime/staprun/staprun.h index 2014ce5b..84cf63fc 100644 --- a/runtime/staprun/staprun.h +++ b/runtime/staprun/staprun.h @@ -34,6 +34,9 @@ #include #include +/* Include config.h to pick up dependency for --prefix usage. */ +#include "config.h" + #define dbug(level, args...) {if (verbose>=level) {fprintf(stderr,"%s:%s:%d ",__name__,__FUNCTION__, __LINE__); fprintf(stderr,args);}} extern char *__name__; -- cgit From 525584b0c2d19dbb14ca84876db1e8bfe25851a4 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Mon, 12 Jan 2009 19:34:28 -0500 Subject: Adapt _stp_sort to 2.6.29. Acked-by: Masami Hiramatsu Signed-off-by: Wenji Huang --- runtime/ChangeLog | 4 ++++ runtime/transport/symbols.c | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index fad46be1..bce0ea30 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,7 @@ +2009-01-12 Wenji Huang + + * transport/symbols.c (_stp_sort): Adapt it to 2.6.29. + 2009-01-06 Frank Ch. Eigler PR9699. diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index 6e3bef1b..72f9ad80 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -92,8 +92,8 @@ static void generic_swap(void *a, void *b, int size) * @base: pointer to data to sort * @num: number of elements * @size: size of each element - * @cmp: pointer to comparison function - * @swap: pointer to swap function or NULL + * @cmp_func: pointer to comparison function + * @swap_func: pointer to swap function or NULL * * This function does a heapsort on the given array. You may provide a * swap function optimized to your element type. @@ -104,37 +104,37 @@ static void generic_swap(void *a, void *b, int size) * it less suitable for kernel use. */ void _stp_sort(void *_base, size_t num, size_t size, - int (*cmp) (const void *, const void *), void (*swap) (void *, void *, int size)) + int (*cmp_func) (const void *, const void *), void (*swap_func) (void *, void *, int size)) { char *base = (char*) _base; /* pre-scale counters for performance */ int i = (num / 2 - 1) * size, n = num * size, c, r; - if (!swap) - swap = (size == 4 ? u32_swap : generic_swap); + if (!swap_func) + swap_func = (size == 4 ? u32_swap : generic_swap); /* heapify */ for (; i >= 0; i -= size) { for (r = i; r * 2 + size < n; r = c) { c = r * 2 + size; - if (c < n - size && cmp(base + c, base + c + size) < 0) + if (c < n - size && cmp_func(base + c, base + c + size) < 0) c += size; - if (cmp(base + r, base + c) >= 0) + if (cmp_func(base + r, base + c) >= 0) break; - swap(base + r, base + c, size); + swap_func(base + r, base + c, size); } } /* sort */ for (i = n - size; i >= 0; i -= size) { - swap(base, base + i, size); + swap_func(base, base + i, size); for (r = 0; r * 2 + size < i; r = c) { c = r * 2 + size; - if (c < i - size && cmp(base + c, base + c + size) < 0) + if (c < i - size && cmp_func(base + c, base + c + size) < 0) c += size; - if (cmp(base + r, base + c) >= 0) + if (cmp_func(base + r, base + c) >= 0) break; - swap(base + r, base + c, size); + swap_func(base + r, base + c, size); } } } -- cgit From e869a84298ccba93b5d244b11657d4183c0eeb64 Mon Sep 17 00:00:00 2001 From: Jim Keniston Date: Tue, 13 Jan 2009 13:14:43 -0800 Subject: PR 7082: patch for uprobes2 (kernel > 2.6.26) --- runtime/ChangeLog | 8 +++++ runtime/uprobes2/uprobes.c | 78 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 11 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index bce0ea30..c023fac6 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,11 @@ +2009-01-13 Jim Keniston + + PR 7082. + * uprobes2/uprobes.c: On exec, free up outstanding + uretprobe_instances and tick down the uproc's ref-count + accordingly, so the (old image's) uproc goes away as + desired. + 2009-01-12 Wenji Huang * transport/symbols.c (_stp_sort): Adapt it to 2.6.29. diff --git a/runtime/uprobes2/uprobes.c b/runtime/uprobes2/uprobes.c index 02496a4e..af187fc9 100644 --- a/runtime/uprobes2/uprobes.c +++ b/runtime/uprobes2/uprobes.c @@ -498,13 +498,24 @@ static bool quiesce_all_threads(struct uprobe_process *uproc, return survivors; } +static void utask_free_uretprobe_instances(struct uprobe_task *utask) +{ + struct uretprobe_instance *ri; + struct hlist_node *r1, *r2; + + hlist_for_each_entry_safe(ri, r1, r2, &utask->uretprobe_instances, + hlist) { + hlist_del(&ri->hlist); + kfree(ri); + uprobe_decref_process(utask->uproc); + } +} + /* Called with utask->uproc write-locked. */ static void uprobe_free_task(struct uprobe_task *utask, bool in_callback) { struct deferred_registration *dr, *d; struct delayed_signal *ds, *ds2; - struct uretprobe_instance *ri; - struct hlist_node *r1, *r2; if (utask->engine && (utask->tsk != current || !in_callback)) { /* @@ -530,12 +541,8 @@ static void uprobe_free_task(struct uprobe_task *utask, bool in_callback) kfree(ds); } - hlist_for_each_entry_safe(ri, r1, r2, &utask->uretprobe_instances, - hlist) { - hlist_del(&ri->hlist); - kfree(ri); - uprobe_decref_process(utask->uproc); - } + utask_free_uretprobe_instances(utask); + kfree(utask); } @@ -873,6 +880,27 @@ static void purge_uprobe(struct uprobe_kimg *uk) uprobe_free_probept(ppt); } +/* TODO: Avoid code duplication with uprobe_validate_vaddr(). */ +static int uprobe_validate_vma(struct task_struct *t, unsigned long vaddr) +{ + struct vm_area_struct *vma; + struct mm_struct *mm; + int ret = 0; + + mm = get_task_mm(t); + if (!mm) + return -EINVAL; + down_read(&mm->mmap_sem); + vma = find_vma(mm, vaddr); + if (!vma || vaddr < vma->vm_start) + ret = -ENOENT; + else if (!(vma->vm_flags & VM_EXEC)) + ret = -EFAULT; + up_read(&mm->mmap_sem); + mmput(mm); + return ret; +} + /* Probed address must be in an executable VM area, outside the SSOL area. */ static int uprobe_validate_vaddr(struct pid *p, unsigned long vaddr, struct uprobe_process *uproc) @@ -2085,9 +2113,9 @@ static u32 uprobe_report_quiesce(enum utrace_resume_action action, /* * uproc's process is exiting or exec-ing, so zap all the (now irrelevant) - * probepoints. Runs with uproc->rwsem write-locked. Caller must ref-count - * uproc before calling this function, to ensure that uproc doesn't get - * freed in the middle of this. + * probepoints and uretprobe_instances. Runs with uproc->rwsem write-locked. + * Caller must ref-count uproc before calling this function, to ensure that + * uproc doesn't get freed in the middle of this. */ static void uprobe_cleanup_process(struct uprobe_process *uproc) { @@ -2096,6 +2124,7 @@ static void uprobe_cleanup_process(struct uprobe_process *uproc) struct hlist_node *pnode1, *pnode2; struct hlist_head *head; struct uprobe_kimg *uk, *unode; + struct uprobe_task *utask; uproc->finished = 1; @@ -2131,6 +2160,16 @@ static void uprobe_cleanup_process(struct uprobe_process *uproc) } } } + + /* + * Free uretprobe_instances. This is a nop on exit, since all + * the uprobe_tasks are already gone. We do this here on exec + * (as opposed to letting uprobe_free_process() take care of it) + * because uprobe_free_process() never gets called if we don't + * tick down the ref count here (PR #7082). + */ + list_for_each_entry(utask, &uproc->thread_list, list) + utask_free_uretprobe_instances(utask); } /* @@ -2280,6 +2319,23 @@ static int uprobe_fork_uproc(struct uprobe_process *parent_uproc, BUG_ON(!parent_uproc->uretprobe_trampoline_addr || IS_ERR(parent_uproc->uretprobe_trampoline_addr)); + ret = uprobe_validate_vma(child_tsk, + (unsigned long) parent_uproc->ssol_area.insn_area); + if (ret) { + int ret2; + printk(KERN_ERR "uprobes: Child %d failed to inherit" + " parent %d's SSOL vma at %p. Error = %d\n", + child_tsk->pid, parent_utask->tsk->pid, + parent_uproc->ssol_area.insn_area, ret); + ret2 = uprobe_validate_vma(parent_utask->tsk, + (unsigned long) parent_uproc->ssol_area.insn_area); + if (ret2 != 0) + printk(KERN_ERR "uprobes: Parent %d's SSOL vma" + " is no longer valid. Error = %d\n", + parent_utask->tsk->pid, ret2); + return ret; + } + if (!try_module_get(THIS_MODULE)) return -ENOSYS; child_pid = get_pid(find_vpid(child_tsk->pid)); -- cgit From b899aa795f925edb7fad318d2e90bb9c3da90b24 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 13 Jan 2009 17:17:47 -0500 Subject: Create the rpm subpackage systemtap-sdt-devel --- runtime/sduprobes.h | 133 ---------------------------------------------------- 1 file changed, 133 deletions(-) delete mode 100644 runtime/sduprobes.h (limited to 'runtime') diff --git a/runtime/sduprobes.h b/runtime/sduprobes.h deleted file mode 100644 index 17c1be71..00000000 --- a/runtime/sduprobes.h +++ /dev/null @@ -1,133 +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 - -#if _LP64 -#define STAP_PROBE_STRUCT_ARG(arg) \ - __uint64_t arg; -#else -#define STAP_PROBE_STRUCT_ARG(arg) \ - long arg __attribute__ ((aligned(8))); -#endif - -#define STAP_PROBE_STRUCT(probe,type,argc) \ -struct _probe_ ## probe \ -{ \ - char probe_name [strlen(#probe)+1]; \ - int probe_type; \ - STAP_PROBE_STRUCT_ARG (probe_arg); \ -}; \ - static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {#probe,type,argc}; - -// The goto _probe_ prevents the label from "drifting" -#ifdef USE_STAP_PROBE -#define STAP_PROBE(provider,probe) \ - STAP_PROBE_STRUCT(probe,0,0) \ - _stap_probe_0 (_probe_ ## probe.probe_name); -#else -#define STAP_PROBE(provider,probe) \ -_probe_ ## probe: \ - asm volatile ("nop"); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe; -#endif - - -#ifdef USE_STAP_PROBE -#define STAP_PROBE1(provider,probe,arg1) \ - STAP_PROBE_STRUCT(probe,0,1) \ - _stap_probe_1 (_probe_ ## probe.probe_name,(size_t)arg1); -#else -#define STAP_PROBE1(provider,probe,parm1) \ - {volatile typeof(parm1) arg1 = parm1; \ -_probe_ ## probe: \ - asm volatile ("nop" :: "r"(arg1)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} -#endif - - -#ifdef USE_STAP_PROBE -#define STAP_PROBE2(provider,probe,arg1,arg2) \ - STAP_PROBE_STRUCT(probe,0,2) \ - _stap_probe_2 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2); -#else -#define STAP_PROBE2(provider,probe,parm1,parm2) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ -_probe_ ## probe: \ - asm volatile ("nop" :: "r"(arg1), "r"(arg2)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe)\ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE3(provider,probe,arg1,arg2,arg3) \ - STAP_PROBE_STRUCT(probe,0,3) \ - _stap_probe_3 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3); -#else -#define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ -_probe_ ## probe: \ - asm volatile ("nop" :: "r"(arg1), "r"(arg2), "r"(arg3)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE4(provider,probe,arg1,arg2,arg3,arg4) \ - STAP_PROBE_STRUCT(probe,0,4) \ - _stap_probe_4 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4); -#else -#define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ - volatile typeof(parm4) arg4 = parm4; \ -_probe_ ## probe: \ - asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE5(provider,probe,arg1,arg2,arg3,arg4,arg5) \ - STAP_PROBE_STRUCT(probe,0,5) \ - _stap_probe_5 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5); -#else -#define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ - volatile typeof(parm4) arg4 = parm4; \ - volatile typeof(parm5) arg5 = parm5; \ -_probe_ ## probe: \ - asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} -#endif - -#define DTRACE_PROBE(provider,probe) \ -STAP_PROBE(provider,probe) -#define DTRACE_PROBE1(provider,probe,parm1) \ -STAP_PROBE1(provider,probe,parm1) -#define DTRACE_PROBE2(provider,probe,parm1,parm2) \ -STAP_PROBE2(provider,probe,parm1,parm2) -#define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \ -STAP_PROBE3(provider,probe,parm1,parm2,parm3) -#define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ -STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) -- cgit From d294a64913b810cbe067655e06ea46a0184f99dc Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 13 Jan 2009 17:20:37 -0500 Subject: Add dtrace and sdt.h --- runtime/sdt.h | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 runtime/sdt.h (limited to 'runtime') diff --git a/runtime/sdt.h b/runtime/sdt.h new file mode 100644 index 00000000..17c1be71 --- /dev/null +++ b/runtime/sdt.h @@ -0,0 +1,133 @@ +// 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 + +#if _LP64 +#define STAP_PROBE_STRUCT_ARG(arg) \ + __uint64_t arg; +#else +#define STAP_PROBE_STRUCT_ARG(arg) \ + long arg __attribute__ ((aligned(8))); +#endif + +#define STAP_PROBE_STRUCT(probe,type,argc) \ +struct _probe_ ## probe \ +{ \ + char probe_name [strlen(#probe)+1]; \ + int probe_type; \ + STAP_PROBE_STRUCT_ARG (probe_arg); \ +}; \ + static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {#probe,type,argc}; + +// The goto _probe_ prevents the label from "drifting" +#ifdef USE_STAP_PROBE +#define STAP_PROBE(provider,probe) \ + STAP_PROBE_STRUCT(probe,0,0) \ + _stap_probe_0 (_probe_ ## probe.probe_name); +#else +#define STAP_PROBE(provider,probe) \ +_probe_ ## probe: \ + asm volatile ("nop"); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe; +#endif + + +#ifdef USE_STAP_PROBE +#define STAP_PROBE1(provider,probe,arg1) \ + STAP_PROBE_STRUCT(probe,0,1) \ + _stap_probe_1 (_probe_ ## probe.probe_name,(size_t)arg1); +#else +#define STAP_PROBE1(provider,probe,parm1) \ + {volatile typeof(parm1) arg1 = parm1; \ +_probe_ ## probe: \ + asm volatile ("nop" :: "r"(arg1)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe;} +#endif + + +#ifdef USE_STAP_PROBE +#define STAP_PROBE2(provider,probe,arg1,arg2) \ + STAP_PROBE_STRUCT(probe,0,2) \ + _stap_probe_2 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2); +#else +#define STAP_PROBE2(provider,probe,parm1,parm2) \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ +_probe_ ## probe: \ + asm volatile ("nop" :: "r"(arg1), "r"(arg2)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe)\ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe;} +#endif + +#ifdef USE_STAP_PROBE +#define STAP_PROBE3(provider,probe,arg1,arg2,arg3) \ + STAP_PROBE_STRUCT(probe,0,3) \ + _stap_probe_3 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3); +#else +#define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ + volatile typeof(parm3) arg3 = parm3; \ +_probe_ ## probe: \ + asm volatile ("nop" :: "r"(arg1), "r"(arg2), "r"(arg3)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe;} +#endif + +#ifdef USE_STAP_PROBE +#define STAP_PROBE4(provider,probe,arg1,arg2,arg3,arg4) \ + STAP_PROBE_STRUCT(probe,0,4) \ + _stap_probe_4 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4); +#else +#define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ + volatile typeof(parm3) arg3 = parm3; \ + volatile typeof(parm4) arg4 = parm4; \ +_probe_ ## probe: \ + asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe;} +#endif + +#ifdef USE_STAP_PROBE +#define STAP_PROBE5(provider,probe,arg1,arg2,arg3,arg4,arg5) \ + STAP_PROBE_STRUCT(probe,0,5) \ + _stap_probe_5 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5); +#else +#define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ + {volatile typeof(parm1) arg1 = parm1; \ + volatile typeof(parm2) arg2 = parm2; \ + volatile typeof(parm3) arg3 = parm3; \ + volatile typeof(parm4) arg4 = parm4; \ + volatile typeof(parm5) arg5 = parm5; \ +_probe_ ## probe: \ + asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto _probe_ ## probe;} +#endif + +#define DTRACE_PROBE(provider,probe) \ +STAP_PROBE(provider,probe) +#define DTRACE_PROBE1(provider,probe,parm1) \ +STAP_PROBE1(provider,probe,parm1) +#define DTRACE_PROBE2(provider,probe,parm1,parm2) \ +STAP_PROBE2(provider,probe,parm1,parm2) +#define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \ +STAP_PROBE3(provider,probe,parm1,parm2,parm3) +#define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ +STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) -- cgit From b1efd8a3e42869cf0b7610f00ea34c8e47ff5982 Mon Sep 17 00:00:00 2001 From: David Smith Date: Tue, 20 Jan 2009 10:35:53 -0600 Subject: PR 9673. Only use one utrace engine for all targets with same path or pid. 2009-01-20 David Smith PR 9673. * task_finder.c (struct stap_task_finder_target): Added 'vm_events' field. (stap_register_task_finder_target): Sets vm_events if a vm_callback is present. (__stp_task_finder_cleanup): Only detaches engines on the main __stp_task_finder_list linked list. (__stp_call_callbacks): New function. (__stp_call_vm_callbacks): New function. (__stp_utrace_attach_match_filename): Calls __stp_call_callbacks() to call callbacks. (__stp_utrace_task_finder_target_death): Ditto. (__stp_utrace_task_finder_target_quiesce): Calls __stp_call_callbacks() and __stp_call_vm_callbacks() to call callbacks. (__stp_call_vm_callbacks_with_vma): Renamed from __stp_target_call_vm_callback. (__stp_utrace_task_finder_target_syscall_exit): Calls __stp_call_vm_callbacks() to call vm callbacks. (stap_start_task_finder): Instead of a utrace engine for every task_finder_target, there is now one utrace engine for all targets with the same path or pid. --- runtime/ChangeLog | 25 +++++ runtime/task_finder.c | 303 ++++++++++++++++++++++++-------------------------- 2 files changed, 173 insertions(+), 155 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index c023fac6..ffe0c57f 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,28 @@ +2009-01-20 David Smith + + PR 9673. + * task_finder.c (struct stap_task_finder_target): Added + 'vm_events' field. + (stap_register_task_finder_target): Sets vm_events if a + vm_callback is present. + (__stp_task_finder_cleanup): Only detaches engines on the main + __stp_task_finder_list linked list. + (__stp_call_callbacks): New function. + (__stp_call_vm_callbacks): New function. + (__stp_utrace_attach_match_filename): Calls __stp_call_callbacks() + to call callbacks. + (__stp_utrace_task_finder_target_death): Ditto. + (__stp_utrace_task_finder_target_quiesce): Calls + __stp_call_callbacks() and __stp_call_vm_callbacks() to call + callbacks. + (__stp_call_vm_callbacks_with_vma): Renamed from + __stp_target_call_vm_callback. + (__stp_utrace_task_finder_target_syscall_exit): Calls + __stp_call_vm_callbacks() to call vm callbacks. + (stap_start_task_finder): Instead of a utrace engine for every + task_finder_target, there is now one utrace engine for all targets + with the same path or pid. + 2009-01-13 Jim Keniston PR 7082. diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 25fad1a4..f982eef1 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -85,7 +85,8 @@ struct stap_task_finder_target { struct list_head callback_list_head; struct list_head callback_list; struct utrace_engine_ops ops; - int engine_attached; + unsigned engine_attached:1; + unsigned vm_events:1; size_t pathlen; /* public: */ @@ -164,6 +165,7 @@ stap_register_task_finder_target(struct stap_task_finder_target *new_tgt) // Make sure everything is initialized properly. new_tgt->engine_attached = 0; + new_tgt->vm_events = 0; memset(&new_tgt->ops, 0, sizeof(new_tgt->ops)); new_tgt->ops.report_death = &__stp_utrace_task_finder_target_death; new_tgt->ops.report_quiesce = &__stp_utrace_task_finder_target_quiesce; @@ -199,6 +201,10 @@ stap_register_task_finder_target(struct stap_task_finder_target *new_tgt) // Add this target to the callback list for this task. list_add_tail(&new_tgt->callback_list, &tgt->callback_list_head); + + // If the new target has a vm_callback, remember this. + if (new_tgt->vm_callback != NULL) + tgt->vm_events = 1; return 0; } @@ -299,7 +305,6 @@ static void __stp_task_finder_cleanup(void) { struct list_head *tgt_node, *tgt_next; - struct list_head *cb_node, *cb_next; struct stap_task_finder_target *tgt; // Walk the main list, cleaning up as we go. @@ -309,22 +314,15 @@ __stp_task_finder_cleanup(void) if (tgt == NULL) continue; - list_for_each_safe(cb_node, cb_next, - &tgt->callback_list_head) { - struct stap_task_finder_target *cb_tgt; - cb_tgt = list_entry(cb_node, - struct stap_task_finder_target, - callback_list); - if (cb_tgt == NULL) - continue; + if (tgt->engine_attached) { + stap_utrace_detach_ops(&tgt->ops); + tgt->engine_attached = 0; + } - if (cb_tgt->engine_attached) { - stap_utrace_detach_ops(&cb_tgt->ops); - cb_tgt->engine_attached = 0; - } + // Notice we're not walking the callback_list here. + // There isn't anything to clean up and doing it would + // mess up callbacks in progress. - list_del(&cb_tgt->callback_list); - } list_del(&tgt->list); } } @@ -369,10 +367,10 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen) /* * __STP_TASK_BASE_EVENTS: base events for stap_task_finder_target's - * without a vm_callback + * without vm_callback's * * __STP_TASK_VM_BASE_EVENTS: base events for - * stap_task_finder_target's with a vm_callback + * stap_task_finder_target's with vm_callback's */ #define __STP_TASK_BASE_EVENTS (UTRACE_EVENT(DEATH)) @@ -390,8 +388,7 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen) | UTRACE_EVENT(QUIESCE)) #define __STP_ATTACHED_TASK_BASE_EVENTS(tgt) \ - ((((tgt)->vm_callback) == NULL) ? __STP_TASK_BASE_EVENTS \ - : __STP_TASK_VM_BASE_EVENTS) + ((tgt)->vm_events ? __STP_TASK_VM_BASE_EVENTS : __STP_TASK_BASE_EVENTS) static int __stp_utrace_attach(struct task_struct *tsk, @@ -474,6 +471,61 @@ stap_utrace_attach(struct task_struct *tsk, return __stp_utrace_attach(tsk, ops, data, event_flags, UTRACE_RESUME); } +static inline void +__stp_call_callbacks(struct stap_task_finder_target *tgt, + struct task_struct *tsk, int register_p, int process_p) +{ + struct list_head *cb_node; + int rc; + + if (tgt == NULL || tsk == NULL) + return; + + list_for_each(cb_node, &tgt->callback_list_head) { + struct stap_task_finder_target *cb_tgt; + + cb_tgt = list_entry(cb_node, struct stap_task_finder_target, + callback_list); + if (cb_tgt == NULL || cb_tgt->callback == NULL) + continue; + + rc = cb_tgt->callback(cb_tgt, tsk, register_p, process_p); + if (rc != 0) { + _stp_error("callback for %d failed: %d", + (int)tsk->pid, rc); + } + } +} + +static inline void +__stp_call_vm_callbacks(struct stap_task_finder_target *tgt, + struct task_struct *tsk, int map_p, char *vm_path, + unsigned long vm_start, unsigned long vm_end, + unsigned long vm_pgoff) +{ + struct list_head *cb_node; + int rc; + + if (tgt == NULL || tsk == NULL) + return; + + list_for_each(cb_node, &tgt->callback_list_head) { + struct stap_task_finder_target *cb_tgt; + + cb_tgt = list_entry(cb_node, struct stap_task_finder_target, + callback_list); + if (cb_tgt == NULL || cb_tgt->vm_callback == NULL) + continue; + + rc = cb_tgt->vm_callback(cb_tgt, tsk, map_p, vm_path, + vm_start, vm_end, vm_pgoff); + if (rc != 0) { + _stp_error("vm callback for %d failed: %d", + (int)tsk->pid, rc); + } + } +} + static inline void __stp_utrace_attach_match_filename(struct task_struct *tsk, const char * const filename, @@ -485,7 +537,7 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk, filelen = strlen(filename); list_for_each(tgt_node, &__stp_task_finder_list) { - struct list_head *cb_node; + int rc; tgt = list_entry(tgt_node, struct stap_task_finder_target, list); @@ -505,52 +557,31 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk, /* Notice that "pid == 0" (which means to probe all * threads) falls through. */ - 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); - if (cb_tgt == NULL) - continue; - - // Set up events we need for attached tasks. - // When register_p is set, we won't actually - // call the callback here - we'll call it when - // the thread gets quiesced. When register_p - // isn't set, we can go ahead and call the - // callback. - if (register_p) { - rc = __stp_utrace_attach(tsk, &cb_tgt->ops, - cb_tgt, - __STP_ATTACHED_TASK_EVENTS, - UTRACE_STOP); - if (rc != 0 && rc != EPERM) - break; - cb_tgt->engine_attached = 1; - } - else { - if (cb_tgt->callback != NULL) { - rc = cb_tgt->callback(cb_tgt, tsk, - register_p, - process_p); - if (rc != 0) { - _stp_error("callback for %d failed: %d", - (int)tsk->pid, rc); - break; - } - } - - rc = stap_utrace_detach(tsk, &cb_tgt->ops); - if (rc != 0) - break; + // Set up events we need for attached tasks. When + // register_p is set, we won't actually call the + // callbacks here - we'll call it when the thread gets + // quiesced. When register_p isn't set, we can go + // ahead and call the callbacks. + if (register_p) { + rc = __stp_utrace_attach(tsk, &tgt->ops, + tgt, + __STP_ATTACHED_TASK_EVENTS, + UTRACE_STOP); + if (rc != 0 && rc != EPERM) + break; + tgt->engine_attached = 1; + } + else { + // Call the callbacks, then detach. + __stp_call_callbacks(tgt, tsk, register_p, process_p); + rc = stap_utrace_detach(tsk, &tgt->ops); + if (rc != 0) + break; - // Note that we don't want to set - // engine_attached to 0 here - only - // when *all* threads using this - // engine have been detached. - } + // Note that we don't want to set + // engine_attached to 0 here - only + // when *all* threads using this + // engine have been detached. } } } @@ -746,20 +777,14 @@ __stp_utrace_task_finder_target_death(struct utrace_attached_engine *engine, // don't know which callback(s) to call. // // So, now when an "interesting" thread is found, we add a - // separate UTRACE_EVENT(DEATH) handler for every probe. - - if (tgt != NULL && tgt->callback != NULL) { - int rc; - - // Call the callback - rc = tgt->callback(tgt, tsk, 0, - ((tsk->signal == NULL) - || (atomic_read(&tsk->signal->live) == 0))); - if (rc != 0) { - _stp_error("death callback for %d failed: %d", - (int)tsk->pid, rc); - } + // separate UTRACE_EVENT(DEATH) handler for each attached + // handler. + if (tgt != NULL && tsk != NULL) { + __stp_call_callbacks(tgt, tsk, 0, + ((tsk->signal == NULL) + || (atomic_read(&tsk->signal->live) == 0))); } + __stp_tf_handler_end(); debug_task_finder_detach(); return UTRACE_DETACH; @@ -785,7 +810,7 @@ __stp_utrace_task_finder_target_quiesce(enum utrace_resume_action action, return UTRACE_DETACH; } - if (tgt == NULL) { + if (tgt == NULL || tsk == NULL) { debug_task_finder_detach(); return UTRACE_DETACH; } @@ -815,20 +840,15 @@ __stp_utrace_task_finder_target_quiesce(enum utrace_resume_action action, _stp_error("utrace_set_events returned error %d on pid %d", rc, (int)tsk->pid); - if (tgt->callback != NULL) { - /* Call the callback. Assume that if the thread is a - * thread group leader, it is a process. */ - rc = tgt->callback(tgt, tsk, 1, (tsk->pid == tsk->tgid)); - if (rc != 0) { - _stp_error("callback for %d failed: %d", - (int)tsk->pid, rc); - } - } - /* If this is just a thread other than the thread group leader, + /* Call the callbacks. Assume that if the thread is a + * thread group leader, it is a process. */ + __stp_call_callbacks(tgt, tsk, 1, (tsk->pid == tsk->tgid)); + + /* If this is just a thread other than the thread group leader, don't bother inform vm_callback clients about its memory map, since they will simply duplicate each other. */ - if (tgt->vm_callback != NULL && (tsk->tgid == tsk->pid)) { + if (tgt->vm_events == 1 && tsk->tgid == tsk->pid) { struct mm_struct *mm; char *mmpath_buf; char *mmpath; @@ -862,18 +882,12 @@ __stp_utrace_task_finder_target_quiesce(enum utrace_resume_action action, mmpath_buf, PATH_MAX); #endif if (mmpath) { - // Call the callback - rc = tgt->vm_callback(tgt, tsk, 1, - mmpath, - vma->vm_start, - vma->vm_end, - (vma->vm_pgoff - << PAGE_SHIFT)); - if (rc != 0) { - _stp_error("vm callback for %d failed: %d", - (int)tsk->pid, rc); - } - + __stp_call_vm_callbacks(tgt, tsk, 1, + mmpath, + vma->vm_start, + vma->vm_end, + (vma->vm_pgoff + << PAGE_SHIFT)); } else { _stp_dbug(__FUNCTION__, __LINE__, @@ -934,7 +948,7 @@ __stp_utrace_task_finder_target_syscall_entry(enum utrace_resume_action action, return UTRACE_DETACH; } - if (tgt == NULL || tgt->vm_callback == NULL) + if (tgt == NULL || tgt->vm_events == 0) return UTRACE_RESUME; // See if syscall is one we're interested in. @@ -977,9 +991,9 @@ __stp_utrace_task_finder_target_syscall_entry(enum utrace_resume_action action, } static void -__stp_target_call_vm_callback(struct stap_task_finder_target *tgt, - struct task_struct *tsk, - struct vm_area_struct *vma) +__stp_call_vm_callbacks_with_vma(struct stap_task_finder_target *tgt, + struct task_struct *tsk, + struct vm_area_struct *vma) { char *mmpath_buf; char *mmpath; @@ -1005,13 +1019,9 @@ __stp_target_call_vm_callback(struct stap_task_finder_target *tgt, rc, (int)tsk->pid); } else { - rc = tgt->vm_callback(tgt, tsk, 1, mmpath, vma->vm_start, - vma->vm_end, - (vma->vm_pgoff << PAGE_SHIFT)); - if (rc != 0) { - _stp_error("vm callback for %d failed: %d", - (int)tsk->pid, rc); - } + __stp_call_vm_callbacks(tgt, tsk, 1, mmpath, + vma->vm_start, vma->vm_end, + (vma->vm_pgoff << PAGE_SHIFT)); } _stp_kfree(mmpath_buf); } @@ -1046,7 +1056,7 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, return UTRACE_DETACH; } - if (tgt == NULL || tgt->vm_callback == NULL) + if (tgt == NULL || tgt->vm_events == 0) return UTRACE_RESUME; // See if syscall is one we're interested in. @@ -1102,8 +1112,7 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, down_read(&mm->mmap_sem); vma = __stp_find_file_based_vma(mm, rv); if (vma != NULL) { - __stp_target_call_vm_callback(tgt, tsk, - vma); + __stp_call_vm_callbacks_with_vma(tgt, tsk, vma); } up_read(&mm->mmap_sem); mmput(mm); @@ -1128,15 +1137,12 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, // FIXME: We'll need to figure out to // retrieve the path of a deleted // vma. - rc = tgt->vm_callback(tgt, tsk, 0, NULL, - entry->vm_start, - entry->vm_end, - (entry->vm_pgoff - << PAGE_SHIFT)); - if (rc != 0) { - _stp_error("vm callback for %d failed: %d", - (int)tsk->pid, rc); - } + + __stp_call_vm_callbacks(tgt, tsk, 0, NULL, + entry->vm_start, + entry->vm_end, + (entry->vm_pgoff + << PAGE_SHIFT)); } // If nothing has changed, there is no @@ -1162,15 +1168,11 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, // FIXME: We'll need to figure out to // retrieve the path of a deleted // vma. - rc = tgt->vm_callback(tgt, tsk, 0, NULL, - entry->vm_start, - entry->vm_end, - (entry->vm_pgoff - << PAGE_SHIFT)); - if (rc != 0) { - _stp_error("vm callback for %d failed: %d", - (int)tsk->pid, rc); - } + __stp_call_vm_callbacks(tgt, tsk, 0, NULL, + entry->vm_start, + entry->vm_end, + (entry->vm_pgoff + << PAGE_SHIFT)); // Now find all the new vma's that // made up the original vma's address @@ -1181,8 +1183,9 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, tmp)) != NULL) && vma->vm_end <= entry->vm_end) { - __stp_target_call_vm_callback(tgt, tsk, - vma); + __stp_call_vm_callbacks_with_vma(tgt, + tsk, + vma); if (vma->vm_end >= entry->vm_end) break; tmp = vma->vm_end; @@ -1274,7 +1277,6 @@ stap_start_task_finder(void) mmpathlen = strlen(mmpath); list_for_each(tgt_node, &__stp_task_finder_list) { struct stap_task_finder_target *tgt; - struct list_head *cb_node; tgt = list_entry(tgt_node, struct stap_task_finder_target, list); @@ -1291,23 +1293,13 @@ stap_start_task_finder(void) /* Notice that "pid == 0" (which means to * probe all threads) falls through. */ - list_for_each(cb_node, &tgt->callback_list_head) { - struct stap_task_finder_target *cb_tgt; - cb_tgt = list_entry(cb_node, - struct stap_task_finder_target, - callback_list); - if (cb_tgt == NULL) - continue; - - // Set up events we need for attached tasks. - rc = __stp_utrace_attach(tsk, &cb_tgt->ops, - cb_tgt, - __STP_ATTACHED_TASK_EVENTS, - UTRACE_STOP); - if (rc != 0 && rc != EPERM) - goto stf_err; - cb_tgt->engine_attached = 1; - } + // Set up events we need for attached tasks. + rc = __stp_utrace_attach(tsk, &tgt->ops, tgt, + __STP_ATTACHED_TASK_EVENTS, + UTRACE_STOP); + if (rc != 0 && rc != EPERM) + goto stf_err; + tgt->engine_attached = 1; } } while_each_thread(grp, tsk); stf_err: @@ -1344,6 +1336,7 @@ stap_stop_task_finder(void) if (i > 0) printk(KERN_ERR "it took %d polling loops to quit.\n", i); #endif + debug_task_finder_report(); } -- cgit From c1008fd01d322bb12e66cb8dc513d488082777a4 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Thu, 22 Jan 2009 14:23:49 -0500 Subject: Add dtrace -h support --- runtime/sdt.h | 112 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 41 deletions(-) (limited to 'runtime') diff --git a/runtime/sdt.h b/runtime/sdt.h index 17c1be71..9fe7b176 100644 --- a/runtime/sdt.h +++ b/runtime/sdt.h @@ -1,4 +1,4 @@ -// Copyright (C) 2005-2008 Red Hat Inc. +// Copyright (C) 2005-2009 Red Hat Inc. // Copyright (C) 2006 Intel Corporation. // // This file is part of systemtap, and is free software. You can @@ -16,14 +16,23 @@ long arg __attribute__ ((aligned(8))); #endif +#define STAP_SENTINEL 0x31425250 + #define STAP_PROBE_STRUCT(probe,type,argc) \ struct _probe_ ## probe \ { \ - char probe_name [strlen(#probe)+1]; \ - int probe_type; \ + int probe_type; \ + char *probe_name; \ STAP_PROBE_STRUCT_ARG (probe_arg); \ }; \ - static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {#probe,type,argc}; +static char probe_name [strlen(#probe)+1] \ + __attribute__ ((section (".probes"))) \ + = #probe; \ +static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,&probe_name[0],argc}; + +#define STAP_CONCAT(a,b) a ## b +#define STAP_LABEL(p,n) \ + STAP_CONCAT(_probe_ ## p ## _, n) // The goto _probe_ prevents the label from "drifting" #ifdef USE_STAP_PROBE @@ -32,42 +41,40 @@ struct _probe_ ## probe \ _stap_probe_0 (_probe_ ## probe.probe_name); #else #define STAP_PROBE(provider,probe) \ -_probe_ ## probe: \ +STAP_LABEL(probe,__LINE__): \ asm volatile ("nop"); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe; + goto STAP_LABEL(probe,__LINE__); #endif - #ifdef USE_STAP_PROBE #define STAP_PROBE1(provider,probe,arg1) \ STAP_PROBE_STRUCT(probe,0,1) \ _stap_probe_1 (_probe_ ## probe.probe_name,(size_t)arg1); #else #define STAP_PROBE1(provider,probe,parm1) \ - {volatile typeof(parm1) arg1 = parm1; \ -_probe_ ## probe: \ + {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ +STAP_LABEL(probe,__LINE__): \ asm volatile ("nop" :: "r"(arg1)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} + goto STAP_LABEL(probe,__LINE__);} #endif - #ifdef USE_STAP_PROBE #define STAP_PROBE2(provider,probe,arg1,arg2) \ STAP_PROBE_STRUCT(probe,0,2) \ _stap_probe_2 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2); #else #define STAP_PROBE2(provider,probe,parm1,parm2) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ -_probe_ ## probe: \ + {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ +STAP_LABEL(probe,__LINE__): \ asm volatile ("nop" :: "r"(arg1), "r"(arg2)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe)\ + STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} + goto STAP_LABEL(probe,__LINE__);} #endif #ifdef USE_STAP_PROBE @@ -76,14 +83,14 @@ _probe_ ## probe: \ _stap_probe_3 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3); #else #define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ -_probe_ ## probe: \ + {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ +STAP_LABEL(probe,__LINE__): \ asm volatile ("nop" :: "r"(arg1), "r"(arg2), "r"(arg3)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} + goto STAP_LABEL(probe,__LINE__);} #endif #ifdef USE_STAP_PROBE @@ -92,15 +99,15 @@ _probe_ ## probe: \ _stap_probe_4 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4); #else #define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ - volatile typeof(parm4) arg4 = parm4; \ -_probe_ ## probe: \ - asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ +STAP_LABEL(probe,__LINE__): \ + asm volatile ("nop" :: "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} + goto STAP_LABEL(probe,__LINE__);} #endif #ifdef USE_STAP_PROBE @@ -109,16 +116,35 @@ _probe_ ## probe: \ _stap_probe_5 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5); #else #define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ - {volatile typeof(parm1) arg1 = parm1; \ - volatile typeof(parm2) arg2 = parm2; \ - volatile typeof(parm3) arg3 = parm3; \ - volatile typeof(parm4) arg4 = parm4; \ - volatile typeof(parm5) arg5 = parm5; \ -_probe_ ## probe: \ - asm volatile ("nop" "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& _probe_ ## probe) \ + {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ +STAP_LABEL(probe,__LINE__): \ + asm volatile ("nop" :: "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto STAP_LABEL(probe,__LINE__);} +#endif + +#ifdef USE_STAP_PROBE +#define STAP_PROBE6(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6) \ + STAP_PROBE_STRUCT(probe,0,6) \ + _stap_probe_6 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6); +#else +#define STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ + {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ + volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ +STAP_LABEL(probe,__LINE__): \ + asm volatile ("nop" :: "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5), "r"(arg6)); \ + STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto _probe_ ## probe;} + goto STAP_LABEL(probe,__LINE__);} #endif #define DTRACE_PROBE(provider,probe) \ @@ -131,3 +157,7 @@ STAP_PROBE2(provider,probe,parm1,parm2) STAP_PROBE3(provider,probe,parm1,parm2,parm3) #define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) +#define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ +STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4,parm5) +#define DTRACE_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ +STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) -- cgit