From f28a8c28ce2ceed97bc4f4a19ffe8880bceb0682 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Mon, 17 Nov 2008 11:34:50 -0500 Subject: [PATCH] Add static uprobe support (static library variant) --- ChangeLog | 8 ++ Makefile.am | 5 + Makefile.in | 115 ++++++++++++++++---- runtime/ChangeLog | 5 + runtime/sduprobes.c | 69 ++++++++++++ runtime/sduprobes.h | 56 ++++++++++ stapprobes.5.in | 13 +++ tapsets.cxx | 104 +++++++++++++++++- testsuite/ChangeLog | 5 + testsuite/systemtap.base/static_uprobes.exp | 70 ++++++++++++ testsuite/systemtap.base/static_uprobes.stp | 17 +++ 11 files changed, 445 insertions(+), 22 deletions(-) create mode 100644 runtime/sduprobes.c create mode 100644 runtime/sduprobes.h create mode 100644 testsuite/systemtap.base/static_uprobes.exp create mode 100644 testsuite/systemtap.base/static_uprobes.stp diff --git a/ChangeLog b/ChangeLog index 338c53820..9bd35d764 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-11-11 Stan Cox + + * Makefile.am (pkglib_LIBRARIES): New. + * Makefile.in: Regenerated + * stapprobes.5.in (process.mark): New. + * tapsets.cxx (register_patterns): Add process.mark. + (dwarf_builder::build): Likewise. + 2008-11-14 Frank Ch. Eigler * tapsets.cxx (common_probe_entryfn_{pro,epi}logue): diff --git a/Makefile.am b/Makefile.am index 0b21231a3..db77456c4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -87,6 +87,11 @@ stamp-elfutils: config.status stap_DEPENDENCIES = lib-elfutils/libdw.so lib-elfutils/libdw.so: stamp-elfutils ; +pkglib_LIBRARIES = libsduprobes.a +libsduprobes_a_SOURCES = runtime/sduprobes.c +sduprobes.o: runtime/sduprobes.c + $(CC) -g -O0 -c -o $@ $< + PHONIES += install-elfutils install-elfutils: mkdir -p $(DESTDIR)$(pkglibdir) diff --git a/Makefile.in b/Makefile.in index d802d9540..de6d48e10 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,6 +17,7 @@ # Makefile.am --- automake input file for systemtap + VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -80,9 +81,24 @@ CONFIG_CLEAN_FILES = stap.1 stapprobes.5 stapfuncs.5 stapvars.5 \ man/stapprobes.scsi.5 man/stapprobes.signal.5 \ man/stapprobes.socket.5 man/stapprobes.tcp.5 \ man/stapprobes.udp.5 -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" \ - "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ - "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ + "$(DESTDIR)$(man8dir)" +pkglibLIBRARIES_INSTALL = $(INSTALL_DATA) +LIBRARIES = $(pkglib_LIBRARIES) +AR = ar +ARFLAGS = cru +libsduprobes_a_AR = $(AR) $(ARFLAGS) +libsduprobes_a_LIBADD = +@BUILD_ELFUTILS_TRUE@am_libsduprobes_a_OBJECTS = sduprobes.$(OBJEXT) +libsduprobes_a_OBJECTS = $(am_libsduprobes_a_OBJECTS) binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) pkglibexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(pkglibexec_PROGRAMS) @@ -131,8 +147,8 @@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ -SOURCES = $(loc2c_test_SOURCES) $(stap_SOURCES) $(stapio_SOURCES) \ - $(staprun_SOURCES) +SOURCES = $(libsduprobes_a_SOURCES) $(loc2c_test_SOURCES) \ + $(stap_SOURCES) $(stapio_SOURCES) $(staprun_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ @@ -288,6 +304,8 @@ stapio_CPPFLAGS = $(AM_CPPFLAGS) stapio_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ PHONIES = $(am__append_5) dist-gzip @BUILD_ELFUTILS_TRUE@stap_DEPENDENCIES = lib-elfutils/libdw.so +@BUILD_ELFUTILS_TRUE@pkglib_LIBRARIES = libsduprobes.a +@BUILD_ELFUTILS_TRUE@libsduprobes_a_SOURCES = runtime/sduprobes.c staprun_SOURCES = runtime/staprun/staprun.c runtime/staprun/staprun_funcs.c\ runtime/staprun/ctl.c runtime/staprun/common.c @@ -414,6 +432,39 @@ man/stapprobes.tcp.5: $(top_builddir)/config.status $(top_srcdir)/man/stapprobes cd $(top_builddir) && $(SHELL) ./config.status $@ man/stapprobes.udp.5: $(top_builddir)/config.status $(top_srcdir)/man/stapprobes.udp.5.in cd $(top_builddir) && $(SHELL) ./config.status $@ +install-pkglibLIBRARIES: $(pkglib_LIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(pkglibLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(pkglibLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(pkglib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + p=$(am__strip_dir) \ + echo " $(RANLIB) '$(DESTDIR)$(pkglibdir)/$$p'"; \ + $(RANLIB) "$(DESTDIR)$(pkglibdir)/$$p"; \ + else :; fi; \ + done + +uninstall-pkglibLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkglibdir)/$$p'"; \ + rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \ + done + +clean-pkglibLIBRARIES: + -test -z "$(pkglib_LIBRARIES)" || rm -f $(pkglib_LIBRARIES) +libsduprobes.a: $(libsduprobes_a_OBJECTS) $(libsduprobes_a_DEPENDENCIES) + -rm -f libsduprobes.a + $(libsduprobes_a_AR) libsduprobes.a $(libsduprobes_a_OBJECTS) $(libsduprobes_a_LIBADD) + $(RANLIB) libsduprobes.a install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -503,6 +554,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loc2c_test-loc2c-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loc2c_test-loc2c.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sduprobes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-buildrun.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-coveragedb.Po@am__quote@ @@ -542,6 +594,20 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@BUILD_ELFUTILS_FALSE@sduprobes.o: runtime/sduprobes.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sduprobes.o -MD -MP -MF $(DEPDIR)/sduprobes.Tpo -c -o sduprobes.o `test -f 'runtime/sduprobes.c' || echo '$(srcdir)/'`runtime/sduprobes.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sduprobes.Tpo $(DEPDIR)/sduprobes.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sduprobes.c' object='sduprobes.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sduprobes.o `test -f 'runtime/sduprobes.c' || echo '$(srcdir)/'`runtime/sduprobes.c + +sduprobes.obj: runtime/sduprobes.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sduprobes.obj -MD -MP -MF $(DEPDIR)/sduprobes.Tpo -c -o sduprobes.obj `if test -f 'runtime/sduprobes.c'; then $(CYGPATH_W) 'runtime/sduprobes.c'; else $(CYGPATH_W) '$(srcdir)/runtime/sduprobes.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sduprobes.Tpo $(DEPDIR)/sduprobes.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sduprobes.c' object='sduprobes.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sduprobes.obj `if test -f 'runtime/sduprobes.c'; then $(CYGPATH_W) 'runtime/sduprobes.c'; else $(CYGPATH_W) '$(srcdir)/runtime/sduprobes.c'; fi` + loc2c_test-loc2c-test.o: loc2c-test.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(loc2c_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT loc2c_test-loc2c-test.o -MD -MP -MF $(DEPDIR)/loc2c_test-loc2c-test.Tpo -c -o loc2c_test-loc2c-test.o `test -f 'loc2c-test.c' || echo '$(srcdir)/'`loc2c-test.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/loc2c_test-loc2c-test.Tpo $(DEPDIR)/loc2c_test-loc2c-test.Po @@ -1187,10 +1253,11 @@ distclean-tags: check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive -all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) config.h all-local +all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) config.h \ + all-local installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \ + for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1222,7 +1289,8 @@ maintainer-clean-generic: clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-local \ - clean-noinstPROGRAMS clean-pkglibexecPROGRAMS mostlyclean-am + clean-noinstPROGRAMS clean-pkglibLIBRARIES \ + clean-pkglibexecPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -1246,7 +1314,8 @@ install-data-am: install-data-local install-man install-dvi: install-dvi-recursive install-exec-am: install-binPROGRAMS install-binSCRIPTS \ - install-exec-local install-pkglibexecPROGRAMS + install-exec-local install-pkglibLIBRARIES \ + install-pkglibexecPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook @@ -1282,7 +1351,8 @@ ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ - uninstall-local uninstall-man uninstall-pkglibexecPROGRAMS + uninstall-local uninstall-man uninstall-pkglibLIBRARIES \ + uninstall-pkglibexecPROGRAMS uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 @@ -1292,16 +1362,17 @@ uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am all-local am--refresh check check-am clean \ clean-binPROGRAMS clean-generic clean-local \ - clean-noinstPROGRAMS clean-pkglibexecPROGRAMS ctags \ - ctags-recursive distclean distclean-compile distclean-generic \ - distclean-hdr distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-binPROGRAMS \ - install-binSCRIPTS install-data install-data-am \ - install-data-local install-dvi install-dvi-am install-exec \ - install-exec-am install-exec-hook install-exec-local \ - install-html install-html-am install-info install-info-am \ - install-man install-man1 install-man5 install-man8 install-pdf \ - install-pdf-am install-pkglibexecPROGRAMS install-ps \ + clean-noinstPROGRAMS clean-pkglibLIBRARIES \ + clean-pkglibexecPROGRAMS ctags ctags-recursive distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-tags dvi dvi-am html html-am info info-am install \ + install-am install-binPROGRAMS install-binSCRIPTS install-data \ + install-data-am install-data-local install-dvi install-dvi-am \ + install-exec install-exec-am install-exec-hook \ + install-exec-local install-html install-html-am install-info \ + install-info-am install-man install-man1 install-man5 \ + install-man8 install-pdf install-pdf-am \ + install-pkglibLIBRARIES install-pkglibexecPROGRAMS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ @@ -1309,7 +1380,7 @@ uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-binSCRIPTS uninstall-local uninstall-man \ uninstall-man1 uninstall-man5 uninstall-man8 \ - uninstall-pkglibexecPROGRAMS + uninstall-pkglibLIBRARIES uninstall-pkglibexecPROGRAMS git_version.stamp: @if test -f "$(srcdir)/git_version.h"; then \ @@ -1342,6 +1413,8 @@ cscope: @BUILD_ELFUTILS_TRUE@ done @BUILD_ELFUTILS_TRUE@ touch $@ @BUILD_ELFUTILS_TRUE@lib-elfutils/libdw.so: stamp-elfutils ; +@BUILD_ELFUTILS_TRUE@sduprobes.o: runtime/sduprobes.c +@BUILD_ELFUTILS_TRUE@ $(CC) -g -O0 -c -o $@ $< @BUILD_ELFUTILS_TRUE@install-elfutils: @BUILD_ELFUTILS_TRUE@ mkdir -p $(DESTDIR)$(pkglibdir) @BUILD_ELFUTILS_TRUE@ for file in lib-elfutils/*.so* lib-elfutils/${PACKAGE_NAME}/*.so*; do \ diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 3b935e3a1..f940ad381 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,8 @@ +2008-11-11 Stan Cox + + * sduprobes.c: New file. + * sduprobes.h: New file. + 2008-11-17 Wenji Huang * runtime.h: Rename for_each_cpu to stp_for_each_cpu for 2.6.28. diff --git a/runtime/sduprobes.c b/runtime/sduprobes.c new file mode 100644 index 000000000..4bee3bd7b --- /dev/null +++ b/runtime/sduprobes.c @@ -0,0 +1,69 @@ +// 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 +#define unused __attribute__ ((unused)) + +int _stap_probe_sentinel = 0; + +void +_stap_probe_start() +{ + _stap_probe_sentinel = 1; +} + +int +_stap_probe_0 (char* probe unused) +{ + return 1; +} + +int +_stap_probe_1 (char* probe unused, + size_t arg1 unused) +{ + return 1; +} + +int +_stap_probe_2 (char* probe unused , + size_t arg1 unused, + size_t arg2 unused) +{ + return 1; +} + +int +_stap_probe_3 (char* probe unused, + size_t arg1 unused, + size_t arg2 unused, + size_t arg3 unused) +{ + return 1; +} + +int +_stap_probe_4 (char* probe unused, + size_t arg1 unused, + size_t arg2 unused, + size_t arg3 unused, + size_t arg4 unused) +{ + return 1; +} + +int +_stap_probe_5 (char* probe unused, + size_t arg1 unused, + size_t arg2 unused, + size_t arg3 unused, + size_t arg4 unused, + size_t arg5 unused) +{ + return 1; +} diff --git a/runtime/sduprobes.h b/runtime/sduprobes.h new file mode 100644 index 000000000..b2c32e43f --- /dev/null +++ b/runtime/sduprobes.h @@ -0,0 +1,56 @@ +// 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 +#include +extern int _stap_probe_sentinel; + +#define STAP_PROBE_START() \ + char *stap_sdt = getenv("SYSTEMTAP_SDT"); \ + if (stap_sdt != NULL) \ + _stap_probe_start () + +#define STAP_PROBE_STRUCT(probe,argc) \ +struct _probe_ ## probe \ +{ \ + char probe_name [strlen(#probe)+1]; \ + int arg_count; \ +}; \ +static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {#probe,argc}; + +#define STAP_PROBE(provider,probe) \ +STAP_PROBE_STRUCT(probe,0) \ + if (__builtin_expect(_stap_probe_sentinel, 0)) \ + _stap_probe_0 (_probe_ ## probe.probe_name); + + +#define STAP_PROBE1(provider,probe,arg1) \ +STAP_PROBE_STRUCT(probe,1) \ + if (__builtin_expect(_stap_probe_sentinel, 0)) \ + _stap_probe_1 (_probe_ ## probe.probe_name,(size_t)arg1); + + +#define STAP_PROBE2(provider,probe,arg1,arg2) \ +STAP_PROBE_STRUCT(probe,2) \ + if (__builtin_expect(_stap_probe_sentinel, 0)) \ + _stap_probe_2 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2); + +#define STAP_PROBE3(provider,probe,arg1,arg2,arg3) \ +STAP_PROBE_STRUCT(probe,3) \ + if (__builtin_expect(_stap_probe_sentinel, 0)) \ + _stap_probe_3 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3); + +#define STAP_PROBE4(provider,probe,arg1,arg2,arg3,arg4) \ +STAP_PROBE_STRUCT(probe,4) \ + if (__builtin_expect(_stap_probe_sentinel, 0)) \ + _stap_probe_4 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4); + +#define STAP_PROBE5(provider,probe,arg1,arg2,arg3,arg4,arg5) \ +STAP_PROBE_STRUCT(probe,5) \ + if (__builtin_expect(_stap_probe_sentinel, 0)) \ + _stap_probe_5 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5); diff --git a/stapprobes.5.in b/stapprobes.5.in index 361dc0007..b50adc9d9 100644 --- a/stapprobes.5.in +++ b/stapprobes.5.in @@ -405,6 +405,7 @@ process("PATH").syscall.return process.syscall.return process(PID).itrace process("PATH").itrace +process("PATH").mark("LABEL") .ESAMPLE .PP A @@ -440,6 +441,18 @@ context variable. A .B .itrace probe gets called for every single step of the process described by PID or PATH. +A +.B .mark +probe gets called via a static probe which is defined in the +application by +STAP_PROBE1(handle,LABEL,arg1). The handle is an application handle, +LABEL corresponds to the .mark argument, and arg1 is the argument. +STAP_PROBE1 is used for probes with 1 argument, STAP_PROBE2 is used +for probes with 2 arguments, and so on. +The arguments of the probe are available in the context variables +$arg1, $arg2, ... +The application should be compiled with ../share/systemtap/runtime/sduprobes.h +and should be linked with libsduprobes.a. .PP Note that .I PATH diff --git a/tapsets.cxx b/tapsets.cxx index f35fe3f9c..601668d07 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -460,6 +460,7 @@ static string TOK_MAXACTIVE("maxactive"); static string TOK_STATEMENT("statement"); static string TOK_ABSOLUTE("absolute"); static string TOK_PROCESS("process"); +static string TOK_MARK("mark"); // Can we handle this query with just symbol-table info? enum dbinfo_reqt @@ -976,6 +977,9 @@ struct dwflpp string(" debuginfo"), mod); + if (!module) + module = mod; + // NB: the result of an _offline call is the assignment of // virtualized addresses to relocatable objects such as // modules. These have to be converted to real addresses at @@ -4862,6 +4866,8 @@ dwarf_derived_probe::register_patterns(match_node * root) root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw); register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw); + root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK)->bind(dw); + root->bind_str(TOK_PROCESS)->bind_num(TOK_MARK)->bind(dw); } void @@ -5192,6 +5198,47 @@ dwarf_builder::build(systemtap_session & sess, if (! sess.module_cache) sess.module_cache = new module_cache (); + if (((probe_point::component*)(location->components[1]))->functor == TOK_MARK) + { + // 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); + + location->components[0]->arg = new literal_string(sess.cmd); + ((literal_map_t&)parameters)[location->components[0]->functor] = location->components[0]->arg; + } + string module_name; if (has_null_param (parameters, TOK_KERNEL) || get_param (parameters, TOK_MODULE, module_name)) @@ -5222,6 +5269,62 @@ dwarf_builder::build(systemtap_session & sess, dw = user_dw[module_name]; } + if (((probe_point::component*)(location->components[1]))->functor == TOK_MARK) + { + Dwarf_Addr bias; + Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (dw->module, &bias)) + ?: dwfl_module_getelf (dw->module, &bias)); + size_t shstrndx; + + Elf_Scn *probe_scn = NULL; + dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx)); + int argc = 0; + // Find the .probes section where the static probe label and arg count are stored + while ((probe_scn = elf_nextscn (elf, probe_scn))) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (probe_scn, &shdr_mem); + assert (shdr != NULL); + + if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".probes") != 0) + continue; + Elf_Data *pdata = elf_getdata (probe_scn, NULL); + 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 += 4 - (probe_scn_offset % 4); + argc = *(((char*)pdata->d_buf + probe_scn_offset)); + probe_scn_offset += sizeof(int); + if (strcmp (location->components[1]->arg->tok->content.c_str(), probe_name) == 0) + break; + } + } + + Dwarf *dwarf = dwfl_module_getdwarf(dw->module, &dw->module_bias); + Dwarf_Off off; + size_t cuhl; + Dwarf_Off noff = 0; + const char *probe_cudie = ""; + // 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 (strncmp (dwarf_diename(&cudie_mem), "sduprobes", 9) == 0) + probe_cudie = dwarf_diename(&cudie_mem); + } + location->components[1]->functor = TOK_STATEMENT; + string argc_str = string(1,'0' + argc); + location->components[1]->arg = new literal_string("_stap_probe_" + (argc_str) + + "@sduprobes.c+1"); + ((literal_map_t&)parameters)[TOK_STATEMENT] = location->components[1]->arg; + dw->module = 0; + } dwarf_query q(sess, base, location, *dw, parameters, finished_results); @@ -7932,7 +8035,6 @@ procfs_builder::build(systemtap_session & sess, // statically inserted macro-based derived probes // ------------------------------------------------------------------------ -static string TOK_MARK("mark"); static string TOK_FORMAT("format"); struct mark_arg diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 8a9c14c4f..517df1533 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-11-11 Stan Cox + + * systemtap.base/static_uprobes.exp: New file. + * systemtap.base/static_uprobes.stp: New file. + 2008-11-13 Mark Wielaard * systemtap.base/bz6850.exp: Pick up the stap being tested when diff --git a/testsuite/systemtap.base/static_uprobes.exp b/testsuite/systemtap.base/static_uprobes.exp new file mode 100644 index 000000000..75e8fd217 --- /dev/null +++ b/testsuite/systemtap.base/static_uprobes.exp @@ -0,0 +1,70 @@ +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 +#include \"sduprobes.h\" + +foo () +{ + STAP_PROBE(tstlabel,label1); +} + +bar (int i) +{ + if (i == 0) + i = 1000; + STAP_PROBE1(tstlabel,label2,i); +} + +baz (int i, char* s) +{ + if (i == 0) + i = 1000; + STAP_PROBE2(tstlabel,label3,i,s); +} + +buz () +{ +} + +main () +{ + sleep(5); + STAP_PROBE_START(); + _stap_probe_start (); // in lieu of setting SYSTEM_SDT + foo(); + bar(2); + baz(3,\"abc\"); +} +" +close $fp + +set res [target_compile $sup_srcpath $sup_exepath executable $sup_flags] +if { $res != "" } { + verbose "target_compile failed: $res" 2 + fail "unable to compile $sup_srcpath" + return +} else { + pass "compiling $sup_srcpath" +} + +set ok 0 +set env(SYSTEMTAP_SDT) 1 +spawn stap -c $sup_exepath $srcdir/$subdir/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 label3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue } + timeout { fail "$test (timeout)" } + eof { } +} +wait + +if {$ok == 3} { pass "$test" } { fail "$test (Got $ok Expected 3)" } diff --git a/testsuite/systemtap.base/static_uprobes.stp b/testsuite/systemtap.base/static_uprobes.stp new file mode 100644 index 000000000..25e64a376 --- /dev/null +++ b/testsuite/systemtap.base/static_uprobes.stp @@ -0,0 +1,17 @@ +probe process("tstlabel.x").mark("label1") +{ + probe_str=user_string($probe) + printf("In %s probe\n", probe_str) +} + +probe process("tstlabel.x").mark("label2") +{ + probe_str=user_string($probe) + printf("In %s probe %#x\n", probe_str, $arg1) +} + +probe process("tstlabel.x").mark("label3") +{ + probe_str=user_string($probe) + printf("In %s probe %#x %#x\n", probe_str, $arg1, $arg2) +} -- 2.43.5