#include <string.h>
#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);
_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)
// Verify that a raw address matches the beginning of a
// statement. This is a somewhat lame check that the address
// is at the start of an assembly instruction.
- if (q->has_statement_num)
+ // Avoid for now since this thwarts a probe on a statement in a macro
+ if (0 && q->has_statement_num)
{
Dwarf_Addr queryaddr = q->statement_num_val;
dwarf_line_t address_line(dwarf_getsrc_die(cudie, queryaddr));
location->components[0]->arg = new literal_string(sess.cmd);
((literal_map_t&)parameters)[location->components[0]->functor] = location->components[0]->arg;
Dwarf_Addr bias;
- Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (dw->module, &bias))
- ?: dwfl_module_getelf (dw->module, &bias));
+ Elf* elf = dwfl_module_getelf (dw->module, &bias);
size_t shstrndx;
Elf_Scn *probe_scn = NULL;
dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
__uint64_t probe_arg = 0;
int probe_type = no_debuginfo;
+ char *probe_name;
// Find the .probes section where the static probe label and arg are stored
while ((probe_scn = elf_nextscn (elf, probe_scn)))
{
if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".probes") != 0)
continue;
- Elf_Data *pdata = elf_getdata (probe_scn, NULL);
+ Elf_Data *pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE);
assert (pdata != NULL);
size_t probe_scn_offset = 0;
while (probe_scn_offset < pdata->d_size)
{
- char *probe_name = (char*)pdata->d_buf + probe_scn_offset;
- probe_scn_offset += strlen(probe_name);
- probe_scn_offset += sizeof(int) - (probe_scn_offset % sizeof(int));
- probe_type = *(((char*)pdata->d_buf + probe_scn_offset));
+ probe_name = (char*)pdata->d_buf + probe_scn_offset;
+ probe_scn_offset += strlen(probe_name) + 1;
+ if (probe_scn_offset % (sizeof(int)))
+ probe_scn_offset += sizeof(int) - (probe_scn_offset % sizeof(int));
+ probe_type = *((int*)((char*)pdata->d_buf + probe_scn_offset));
probe_scn_offset += sizeof(int);
- probe_arg = *((__uint32_t*)((char*)pdata->d_buf + probe_scn_offset));
- probe_arg <<= 32;
- probe_arg |= *((__uint32_t*)((char*)pdata->d_buf + probe_scn_offset + 4));
+ if (probe_scn_offset % (sizeof(__uint64_t)))
+ probe_scn_offset += sizeof(__uint64_t) - (probe_scn_offset % sizeof(__uint64_t));
+ probe_arg = *((__uint64_t*)((char*)pdata->d_buf + probe_scn_offset));
if (strcmp (location->components[1]->arg->tok->content.c_str(), probe_name) == 0)
break;
- probe_scn_offset += sizeof(__uint64_t);
- probe_scn_offset += sizeof(__uint64_t)*2 - (probe_scn_offset % (sizeof(__uint64_t)*2));
+ if (probe_scn_offset % (sizeof(__uint64_t)*2))
+ probe_scn_offset = (probe_scn_offset + sizeof(__uint64_t)*2) - (probe_scn_offset % (sizeof(__uint64_t)*2));
}
}
size_t cuhl;
Dwarf_Off noff = 0;
const char *probe_file = "@sduprobes.c";
- int probe_line;
// Find where the probe instrumentation landing points are defined
while (dwarf_nextcu (dwarf, off = noff, &noff, &cuhl, NULL, NULL, NULL) == 0)
{
Dwarf_Die *cudie = dwarf_offdie (dwarf, off + cuhl, &cudie_mem);
if (cudie == NULL)
continue;
+ if (0)
+ printf("2 diename=%s module_name=%s probe_type=%d probe_arg=%#Lx\n",dwarf_diename(&cudie_mem),module_name.c_str(), (int)probe_type, (long long)probe_arg);
if (probe_type == no_debuginfo)
{
if (strncmp (dwarf_diename(&cudie_mem), "sduprobes", 9) == 0)
break;
}
}
- else
- {
- Dwarf_Line *dwarf_line = dwarf_getsrc_die (cudie, probe_arg);
- if (dwarf_line == NULL)
- continue;
- dwarf_lineno (dwarf_line, &probe_line);
- probe_file = (dwarf_diename(&cudie_mem) ?: "<unknown>");
- break;
- }
}
location->components[1]->functor = TOK_STATEMENT;
if (probe_type == no_debuginfo)
}
else
{
- char *pline;
- if (asprintf (&pline, "*@%s:%d", probe_file, probe_line + 1) < 0)
- return;
- location->components[1]->arg = new literal_string(pline);
+ location->components[1]->arg = new literal_number((int)probe_arg);
}
+
((literal_map_t&)parameters)[TOK_STATEMENT] = location->components[1]->arg;
dw->module = 0;
}
set fp [open $sup_srcpath "w"]
puts $fp "
#include <stdlib.h>
+#define USE_STAP_PROBE 1
#include \"sduprobes.h\"
foo ()
baz (int i, char* s)
{
+ STAP_PROBE1(tstlabel,label0,i);
if (i == 0)
i = 1000;
STAP_PROBE2(tstlabel,label3,i,s);
}
-buz ()
+buz (int parm)
{
}
foo();
bar(2);
baz(3,\"abc\");
+ buz(4);
}
"
close $fp
pass "compiling static_uprobes.c"
}
+set fp [open "[pwd]/static_uprobes.stp" "w"]
+puts $fp "
+probe process(\"static_uprobes.x\").mark(\"label0\")
+{
+ printf(\"In label0 probe %#x\\n\", \$arg1)
+}
+probe process(\"static_uprobes.x\").mark(\"label1\")
+{
+ printf(\"In label1 probe\\n\")
+}
+probe process(\"static_uprobes.x\").mark(\"label2\")
+{
+ printf(\"In label2 probe %#x\\n\", \$arg1)
+}
+probe process(\"static_uprobes.x\").mark(\"label3\")
+{
+ printf(\"In label3 probe %#x %#x\\n\", \$arg1, \$arg2)
+}
+"
+close $fp
+
set ok 0
-spawn stap -c $sup_exepath $srcdir/$subdir/static_uprobes.stp
+verbose -log "spawn stap -c $sup_exepath [pwd]/static_uprobes.stp"
+spawn stap -c $sup_exepath [pwd]/static_uprobes.stp
expect {
-timeout 180
-re {In label1 probe} { incr ok; exp_continue }
-re {In label2 probe 0x2} { incr ok; exp_continue }
+ -re {In label0 probe 0x3} { incr ok; exp_continue }
-re {In label3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue }
timeout { fail "$test (timeout)" }
eof { }
}
+if {$ok == 4} { pass "$test" } { fail "$test ($ok)" }
+set ok 0
+
# Now do a debuginfo style probe of the above test
set fp [open "[pwd]/static_uprobes.sh" "w"]
puts $fp "
ed $sup_srcpath <<HERE
-1a
-#define USE_STAP_DEBUGINFO_PROBE 1
+/USE_STAP_PROBE/d
+/buz/+1
+a
+ DTRACE_PROBE1(tstlabel,label4,parm);
.
w
q
-HERE
"
close $fp
spawn sh [pwd]/static_uprobes.sh
-set sup_flags "additional_flags=-iquote$env(SYSTEMTAP_RUNTIME) additional_flags=-g additional_flags=$env(SYSTEMTAP_RUNTIME)/sduprobes.c"
+set fp [open "[pwd]/static_uprobes.stp" "w"]
+puts $fp "
+probe process(\"static_uprobes.x\").mark(\"label0\")
+{
+ printf(\"In label0 probe %#x\\n\", \$label0_arg1)
+}
+probe process(\"static_uprobes.x\").mark(\"label1\")
+{
+ printf(\"In label1 probe\\n\")
+}
+probe process(\"static_uprobes.x\").mark(\"label2\")
+{
+ printf(\"In label2 probe %#x\\n\", \$label2_arg1)
+}
+probe process(\"static_uprobes.x\").mark(\"label3\")
+{
+ printf(\"In label3 probe %#x %#x\\n\", \$label3_arg1, \$label3_arg2)
+}
+probe process(\"static_uprobes.x\").mark(\"label4\")
+{
+ printf(\"In label4 dtrace probe %#x\\n\", \$label4_arg1)
+}
+"
+close $fp
+
+set sup_flags "additional_flags=-iquote$env(SYSTEMTAP_RUNTIME) additional_flags=-g additional_flags=-O additional_flags=$env(SYSTEMTAP_RUNTIME)/sduprobes.c"
set res [target_compile $sup_srcpath $sup_exepath executable $sup_flags]
if { $res != "" } {
verbose "target_compile failed: $res" 2
pass "compiling sduprobes.c -g"
}
-spawn stap -c $sup_exepath $srcdir/$subdir/static_uprobes.stp
+verbose -log "spawn stap -c $sup_exepath [pwd]/static_uprobes.stp"
+spawn stap -c $sup_exepath [pwd]/static_uprobes.stp
expect {
-timeout 180
-re {In label1 probe} { incr ok; exp_continue }
-re {In label2 probe 0x2} { incr ok; exp_continue }
+ -re {In label0 probe 0x3} { incr ok; exp_continue }
-re {In label3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue }
+ -re {In label4 dtrace probe 0x4} { incr ok; exp_continue }
timeout { fail "$test (timeout)" }
eof { }
}
wait
-if {$ok == 6} { pass "$test" } { fail "$test ($ok)" }
+if {$ok == 5} { pass "$test" } { fail "$test ($ok)" }