diff options
author | Stan Cox <scox@redhat.com> | 2009-02-15 22:23:54 -0500 |
---|---|---|
committer | Stan Cox <scox@redhat.com> | 2009-02-15 22:23:54 -0500 |
commit | 7b534f489ed3567d8a59e00eb4ba954697a97059 (patch) | |
tree | 7a2d6cd79233c82b0fa0efc7018cd3e87aabf07e | |
parent | 1751e667fdd363e936d1a6698b12f150caf0c93c (diff) | |
download | systemtap-steved-7b534f489ed3567d8a59e00eb4ba954697a97059.tar.gz systemtap-steved-7b534f489ed3567d8a59e00eb4ba954697a97059.tar.xz systemtap-steved-7b534f489ed3567d8a59e00eb4ba954697a97059.zip |
Handle c++ static user probes via .probe, c via .label.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | runtime/ChangeLog | 4 | ||||
-rw-r--r-- | runtime/sdt.h | 146 | ||||
-rw-r--r-- | tapsets.cxx | 149 | ||||
-rw-r--r-- | testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | testsuite/systemtap.base/static_uprobes.exp | 114 |
6 files changed, 157 insertions, 265 deletions
@@ -1,3 +1,8 @@ +2009-02-15 Stan Cox <scox@redhat.com> + + * tapsets.cxx (dwflpp::iterate_over_cu_labels): Handle missing DW_AT_low_pc + * (dwarf_builder::build): Handle c++ via .probe, c via .label. + 2009-02-13 Frank Ch. Eigler <fche@elastic.org> * translate.cxx (dump_unwindsyms): Use \n instead of endl throughout diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 2d5f2537..24de840c 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,7 @@ +2009-02-15 Stan Cox <scox@redhat.com> + + * sdt.h (STAP_PROBE): Handle c++ via .probe, c via .label. + 2009-02-13 David Smith <dsmith@redhat.com> * stack.c: Fixed compile problems on systems with older kernels diff --git a/runtime/sdt.h b/runtime/sdt.h index 905074ad..f09d4346 100644 --- a/runtime/sdt.h +++ b/runtime/sdt.h @@ -18,7 +18,9 @@ #define STAP_SENTINEL 0x31425250 -#define STAP_PROBE_STRUCT(probe,type,argc) \ +// g++ 4.3.2 doesn't emit DW_TAG_label +#ifdef __cplusplus +#define STAP_PROBE_STRUCT(probe,argc) \ struct _probe_ ## probe \ { \ int probe_type; \ @@ -29,92 +31,68 @@ static char probe ## _ ## probe_name [strlen(#probe)+1] \ __attribute__ ((section (".probes"))) \ = #probe; \ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc}; +#else +#define STAP_PROBE_STRUCT(probe,argc) +#endif + +#ifdef __cplusplus +#define STAP_LABEL_REF(probe) \ + if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ + goto STAP_LABEL(probe,__LINE__); +#else +#define STAP_LABEL_REF(probe) \ + volatile static int sentinel_ ## probe = 0; \ + if (__builtin_expect(sentinel_ ## probe < 0, 0)) \ + goto STAP_LABEL(probe,__LINE__); +#endif #define STAP_CONCAT(a,b) a ## b #define STAP_LABEL(p,n) \ STAP_CONCAT(_stapprobe1_ ## p ## _, n) // 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) \ -STAP_LABEL(probe,__LINE__): \ + { \ +STAP_LABEL(probe,__LINE__): \ asm volatile ("nop"); \ - 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 + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(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)) arg1 __attribute__ ((unused)) = parm1; \ STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1)); \ - 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 + asm volatile ("nop /* %0 */" :: "g"( arg1)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(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)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2)); \ - 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 + asm volatile ("nop /* %0 %1 */" :: "g"(arg1), "g"(arg2)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(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)) 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" :: "g"(arg1), "g"(arg2), "g"(arg3)); \ - 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 + asm volatile ("nop /* %0 %1 %2 */" :: "g"(arg1), "g"(arg2), "g"(arg3)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(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,parm4) \ {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" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4)); \ - 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 + asm volatile ("nop /* %0 %1 %2 %3 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(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)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ @@ -122,17 +100,10 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(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 + asm volatile ("nop /* %0 %1 %2 %3 %4 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(probe);} -#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; \ @@ -142,16 +113,9 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ STAP_LABEL(probe,__LINE__): \ asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6)); \ - 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 + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(probe);} -#ifdef USE_STAP_PROBE -#define STAP_PROBE7(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ - STAP_PROBE_STRUCT(probe,0,7) \ - _stap_probe_7 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6,(size_t)arg7); -#else #define STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ @@ -162,16 +126,9 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ STAP_LABEL(probe,__LINE__): \ asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7)); \ - 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 + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(probe);} -#ifdef USE_STAP_PROBE -#define STAP_PROBE8(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \ - STAP_PROBE_STRUCT(probe,0,8) \ - _stap_probe_8 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6,(size_t)arg7,(size_t)arg8); -#else #define STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ @@ -183,16 +140,9 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm8)) arg8 __attribute__ ((unused)) = parm8; \ STAP_LABEL(probe,__LINE__): \ asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7), "g"(arg8)); \ - 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 + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(probe);} -#ifdef USE_STAP_PROBE -#define STAP_PROBE9(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \ - STAP_PROBE_STRUCT(probe,0,9) \ - _stap_probe_9 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6,(size_t)arg7,(size_t)arg8,(size_t)arg9); -#else #define STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ @@ -202,15 +152,13 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ volatile typeof((parm8)) arg8 __attribute__ ((unused)) = parm8; \ - volatile typeof((parm9)) arg9 __attribute__ ((unused)) = parm9; \ + volatile typeof((parm9)) arg9 __attribute__ ((unused() = parm9; \ STAP_LABEL(probe,__LINE__): \ asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7), "g"(arg8), "g"(arg9)); \ - 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 + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(probe);} -#define DTRACE_PROBE(provider,probe) \ +#define DTRACE_PROBE(__LINE__) \ STAP_PROBE(provider,probe) #define DTRACE_PROBE1(provider,probe,parm1) \ STAP_PROBE1(provider,probe,parm1) diff --git a/tapsets.cxx b/tapsets.cxx index 9b375f06..45a63e6f 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1346,22 +1346,42 @@ struct dwflpp function_name = name; } else if (tag == DW_TAG_label - && ((strncmp(name, sym, sizeof(sym)) == 0) + && ((strncmp(name, sym, strlen(sym)) == 0) || (name_has_wildcard (sym) && function_name_matches_pattern (name, sym)))) { const char *file = dwarf_decl_file (&die); - int line; - line = dwarf_decl_line (&die, &line); + // Get the line number for this label + Dwarf_Attribute attr; + dwarf_attr (&die,DW_AT_decl_line, &attr); + Dwarf_Sword dline; + dwarf_formsdata (&attr, &dline); Dwarf_Addr stmt_addr; if (dwarf_lowpc (&die, &stmt_addr) != 0) - continue; + { + // There is no lowpc so figure out the address + // Get the real die for this cu + Dwarf_Die cudie; + dwarf_diecu (cu, &cudie, NULL, NULL); + size_t nlines = 0; + // Get the line for this label + Dwarf_Line **aline; + dwarf_getsrc_file (module_dwarf, file, (int)dline, 0, &aline, &nlines); + // Get the address + for (size_t i = 0; i < nlines; i++) + { + dwarf_lineaddr (*aline, &stmt_addr); + if ((dwarf_haspc (&die, stmt_addr))) + break; + } + } + Dwarf_Die *scopes; int nscopes = 0; nscopes = dwarf_getscopes_die (&die, &scopes); if (nscopes > 1) callback(function_name.c_str(), file, - line, &scopes[1], stmt_addr, q); + (int)dline, &scopes[1], stmt_addr, q); } if (dwarf_haschildren (&die) && tag != DW_TAG_structure_type && tag != DW_TAG_union_type) @@ -5368,30 +5388,38 @@ dwarf_builder::build(systemtap_session & sess, { enum probe_types { - no_debuginfo = 0, - use_debuginfo = 1 + probes_and_dwarf = 0, // Use statement address + dwarf_no_probes = 1, // Use label name + probes_no_dwarf = 2 }; -// location->components[0]->arg = new literal_string(sess.cmd); -// ((literal_map_t&)parameters)[location->components[0]->functor] = location->components[0]->arg; + int probe_type = dwarf_no_probes; + string probe_name = (char*) location->components[1]->arg->tok->content.c_str(); + __uint64_t probe_arg = 0; Dwarf_Addr 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 + GElf_Shdr *shdr = NULL; + + // Is there a .probes section? while ((probe_scn = elf_nextscn (elf, probe_scn))) { GElf_Shdr shdr_mem; - GElf_Shdr *shdr = gelf_getshdr (probe_scn, &shdr_mem); + shdr = gelf_getshdr (probe_scn, &shdr_mem); assert (shdr != NULL); - if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".probes") != 0) - continue; + if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".probes") == 0) + { + probe_type = probes_and_dwarf; + break; + } + } + + if (probe_type == probes_and_dwarf) + { 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; @@ -5414,89 +5442,26 @@ dwarf_builder::build(systemtap_session & sess, 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) + if (strcmp (location->components[1]->arg->tok->content.c_str(), probe_name.c_str()) == 0) break; 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)); } - if (probe_scn_offset < pdata->d_size) - break; - } - - if (probe_type == no_debuginfo) - { - // Many probe labels correspond to _stap_probe_N - // Generate: _probe_string = user_string($probe); - block *b = ((block*)(base->body)); - assignment *as = new assignment; - symbol* lsym = new symbol; - lsym->type = pe_string; - lsym->name = "_probe_string"; - lsym->tok = base->body->tok; - as->left = lsym; - as->op = "="; - functioncall *fc = new functioncall; - fc->function = "user_string"; - fc->tok = base->body->tok; - target_symbol* rsym = new target_symbol; - rsym->base_name = "$probe"; - rsym->tok = base->body->tok; - fc->args.push_back(rsym); - as->right = fc; - expr_statement* es = new expr_statement; - es->value = as; - - // Generate: if (_probe_string != mark("label")) next; - if_statement *is = new if_statement; - is->thenblock = new next_statement; - is->elseblock = NULL; - is->tok = base->body->tok; - comparison *be = new comparison; - be->op = "!="; - be->tok = base->body->tok; - be->left = lsym; - be->right = new literal_string(location->components[1]->arg->tok->content);; - is->condition = be; - - b->statements.insert(b->statements.begin(),(statement*) is); - b->statements.insert(b->statements.begin(),(statement*) es); - } - - Dwarf *dwarf = dwfl_module_getdwarf(dw->module, &dw->module_bias); - Dwarf_Off off; - size_t cuhl; - Dwarf_Off noff = 0; - const char *probe_file = "@sduprobes.c"; - // Find where the probe instrumentation landing points are defined - while (dwarf_nextcu (dwarf, off = noff, &noff, &cuhl, NULL, NULL, NULL) == 0) - { - Dwarf_Die cudie_mem; - Dwarf_Die *cudie = dwarf_offdie (dwarf, off + cuhl, &cudie_mem); - if (cudie == NULL) - continue; - if (probe_type == no_debuginfo) - { - if (strncmp (dwarf_diename(&cudie_mem), "sduprobes", 9) == 0) - { - break; - } - } - } - location->components[1]->functor = TOK_STATEMENT; - if (probe_type == no_debuginfo) - { - string probe_arg_str = string(1,'0' + probe_arg); - location->components[1]->arg - = new literal_string("_stap_probe_" - + (probe_arg_str) - + probe_file + "+1"); + location->components[1]->functor = TOK_STATEMENT; + location->components[1]->arg = new literal_number((int)probe_arg); + ((literal_map_t&)parameters)[TOK_STATEMENT] = location->components[1]->arg; } - else + else if (probe_type == dwarf_no_probes) { - location->components[1]->arg = new literal_number((int)probe_arg); + location->components[1]->functor = TOK_FUNCTION; + location->components[1]->arg = new literal_string("*"); + ((literal_map_t&)parameters)[TOK_FUNCTION] = location->components[1]->arg; + location->components.push_back(new probe_point::component(TOK_LABEL)); + location->components[2]->arg = new literal_string("_stapprobe1_" + probe_name); + ((literal_map_t&)parameters).erase(TOK_MARK); + ((literal_map_t&)parameters).insert(pair<string,literal*>(TOK_LABEL, location->components[2]->arg)); } - ((literal_map_t&)parameters)[TOK_STATEMENT] = location->components[1]->arg; dw->module = 0; } diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 4a934e81..89e59075 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-02-15 Stan Cox <scox@redhat.com> + + * systemtap.base/static_uprobes.exp: Test with both c++ and c. + 2009-02-10 Will Cohen <wcohen@redhat.com> * systemtap.examples/memory/kmalloc-top.meta: Correct testing commands. diff --git a/testsuite/systemtap.base/static_uprobes.exp b/testsuite/systemtap.base/static_uprobes.exp index eb0d1c6e..34e230ac 100644 --- a/testsuite/systemtap.base/static_uprobes.exp +++ b/testsuite/systemtap.base/static_uprobes.exp @@ -1,21 +1,17 @@ + set test "sduprobes" if {![installtest_p]} {untested $test; return} # Compile a C program to use as the user-space probing target set sup_srcpath "[pwd]/static_uprobes.c" set sup_exepath "[pwd]/static_uprobes.x" -set sup_flags "additional_flags=-iquote$env(SYSTEMTAP_RUNTIME) additional_flags=-L$env(CRASH_LIBDIR) additional_flags=-lsduprobes" set fp [open $sup_srcpath "w"] puts $fp " #include <stdlib.h> #define USE_STAP_PROBE 1 #include \"static_uprobes.h\" -foo () -{ - STAP_PROBE(static_uprobes,test_probe_1); -} - +void bar (int i) { if (i == 0) @@ -23,6 +19,7 @@ bar (int i) STAP_PROBE1(static_uprobes,test_probe_2,i); } +void baz (int i, char* s) { STAP_PROBE1(static_uprobes,test_probe_0,i); @@ -31,51 +28,24 @@ baz (int i, char* s) STATIC_UPROBES_TEST_PROBE_3(i,s); } +void buz (int parm) { + if (parm == 0) + parm = 1000; + DTRACE_PROBE1(static_uprobes,test_probe_4,parm); } +int main () { - sleep(5); - foo(); bar(2); - baz(3,\"abc\"); + baz(3,(char*)\"abc\"); buz(4); } " close $fp -# set res [target_compile $sup_srcpath $sup_exepath executable $sup_flags] -# if { $res != "" } { -# verbose "target_compile failed: $res" 2 -# fail "compiling static_uprobes.c" -# return -# } else { -# pass "compiling static_uprobes.c" -# } - -set fp [open "[pwd]/static_uprobes.stp" "w"] -puts $fp " -probe process(\"static_uprobes.x\").mark(\"test_probe_0\") -{ - printf(\"In test_probe_0 probe %#x\\n\", \$arg1) -} -probe process(\"static_uprobes.x\").mark(\"test_probe_1\") -{ - printf(\"In test_probe_1 probe\\n\") -} -probe process(\"static_uprobes.x\").mark(\"test_probe_2\") -{ - printf(\"In test_probe_2 probe %#x\\n\", \$arg1) -} -probe process(\"static_uprobes.x\").mark(\"test_probe_3\") -{ - printf(\"In test_probe_3 probe %#x %#x\\n\", \$arg1, \$arg2) -} -" -close $fp - # Try to find utrace_attach symbol in /proc/kallsyms # copy from utrace_p5.exp set utrace_support_found 0 @@ -86,36 +56,6 @@ if {! [catch {exec grep -q utrace_attach $path} dummy]} { if {$utrace_support_found == 0} { untested "$test"; return } set ok 0 -# 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 test_probe_1 probe} { incr ok; exp_continue } -# -re {In test_probe_2 probe 0x2} { incr ok; exp_continue } -# -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } -# -re {In test_probe_3 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 -/USE_STAP_PROBE/d -/buz/+1 -a - DTRACE_PROBE1(static_uprobes,test_probe_4,parm); -. -w -q -" -close $fp -spawn sh [pwd]/static_uprobes.sh set fp [open "[pwd]/static_uprobes.stp" "w"] puts $fp " @@ -123,10 +63,6 @@ probe process(\"static_uprobes.x\").mark(\"test_probe_0\") { printf(\"In test_probe_0 probe %#x\\n\", \$arg1) } -probe process(\"static_uprobes.x\").mark(\"test_probe_1\") -{ - printf(\"In test_probe_1 probe\\n\") -} probe process(\"static_uprobes.x\").mark(\"test_probe_2\") { printf(\"In test_probe_2 probe %#x\\n\", \$arg1) @@ -168,6 +104,35 @@ 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 test_probe_2 probe 0x2} { incr ok; exp_continue } + -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } + -re {In test_probe_3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue } + -re {In test_probe_4 dtrace probe 0x4} { incr ok; exp_continue } + timeout { fail "$test (timeout)" } + eof { } +} + +wait + +if {$ok == 4} { pass "$test" } { fail "$test ($ok)" } + +spawn mv $sup_srcpath "[pwd]/static_uprobes.cc" +set sup_flags "$sup_flags c++" +set res [target_compile "[pwd]/static_uprobes.cc" $sup_exepath executable $sup_flags] +if { $res != "" } { + verbose "target_compile failed: $res" 2 + fail "compiling sduprobes.c -g" + return +} else { + pass "compiling sduprobes.c -g" +} + +set ok 0 + +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 test_probe_1 probe} { incr ok; exp_continue } -re {In test_probe_2 probe 0x2} { incr ok; exp_continue } -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } @@ -179,4 +144,5 @@ expect { wait -if {$ok == 5} { pass "$test" } { fail "$test ($ok)" } +if {$ok == 4} { pass "$test" } { fail "$test ($ok)" } + |