diff --git a/Makefile.in b/Makefile.in index 41d5cb7..c1b6d28 100644 --- a/Makefile.in +++ b/Makefile.in @@ -537,6 +537,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ python = @python@ +runstatedir = @runstatedir@ sbindir = @sbindir@ selinux_CFLAGS = @selinux_CFLAGS@ selinux_LIBS = @selinux_LIBS@ diff --git a/build_android.sh b/build_android.sh new file mode 100755 index 0000000..877ee68 --- /dev/null +++ b/build_android.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +BUILD_PREFIX="/data/data/com.systemtap.android/stap/" +OUTPUT_DIR="android_binaries" +STAPIO_BIN="staprun/stapio" +STAPRUN_BIN="staprun/staprun" +COMPILER_PREFIX_LIST=("arm-none-linux-gnueabi" "arm-unknown-linux-gnueabi") + + +function checkCompiler() +{ + for cur_compiler_prefix in ${COMPILER_PREFIX_LIST[@]} + do + RET=`${cur_compiler_prefix}-gcc --version 2>&1` + if [ $? -eq 0 ]; + then + COMPILER_PREFIX=${cur_compiler_prefix} + return + fi + done; + + echo "No suitable compiler found. Check your PATH" >&2 + exit 1 +} + +checkCompiler + +ac_cv_with_java=no ac_cv_prog_have_jar=no ac_cv_prog_have_javac=no ac_cv_with_java=no ac_cv_file__usr_include_avahi_common=no ac_cv_file__usr_include_avahi_client=no ac_cv_file__usr_include_nspr=no ac_cv_file__usr_include_nspr4=no ac_cv_file__usr_include_nss=no ac_cv_file__usr_include_nss3=no ac_cv_func_malloc_0_nonnull=yes ./configure --prefix=$BUILD_PREFIX --host=$COMPILER_PREFIX --disable-translator --disable-docs --disable-refdocs --disable-grapher --without-rpm --without-nss --with-android + +if [ $? -ne 0 ]; then + echo "Error configuring the workspace" >&2 + exit 1 +fi + +make + +if [ $? -ne 0 ]; then + echo "Error building stap{run,io}" >&2 + exit 1 +fi + +if [ -e $STAPRUN_BIN ] && [ -e $STAPIO_RUN ]; then + if [ ! -d $OUTPUT_DIR ]; then + mkdir $OUTPUT_DIR + fi + cp $STAPRUN_BIN $OUTPUT_DIR + cp $STAPIO_BIN $OUTPUT_DIR +else + rm ${OUTPUT_DIR}/${STAPRUN_BIN} + rm ${OUTPUT_DIR}/${STAPIO_BIN} + echo "Some binaries were not created." + exit 1 +fi diff --git a/buildrun.cxx b/buildrun.cxx index 76139b4..ea5e273 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -780,6 +780,12 @@ make_run_command (systemtap_session& s, const string& remotedir, staprun_cmd.push_back("-v"); if (s.suppress_warnings) staprun_cmd.push_back("-w"); + + if (!s.pid_file.empty()) + { + staprun_cmd.push_back("-M"); + staprun_cmd.push_back(s.pid_file); + } if (!s.output_file.empty()) { diff --git a/cmdline.h b/cmdline.h index c5d64f4..bc93058 100644 --- a/cmdline.h +++ b/cmdline.h @@ -66,7 +66,7 @@ enum { // NB: when adding new options, consider very carefully whether they // should be restricted from stap clients (after --client-options)! -#define STAP_SHORT_OPTIONS "hVvtp:I:e:E:o:R:r:a:m:kgPc:x:D:bs:uqiwl:d:L:FS:B:J:jWG:" +#define STAP_SHORT_OPTIONS "hVvtp:I:e:E:o:R:r:a:m:kgPc:x:D:bs:uqiwl:d:L:FS:B:J:jWG:K:" extern struct option stap_long_options[]; diff --git a/config.in b/config.in index 9c50cf9..20d2b3f 100644 --- a/config.in +++ b/config.in @@ -13,6 +13,9 @@ /* Define to 1 to enable process.mark probes in stap, staprun, stapio. */ #undef ENABLE_SDT_PROBES +/* Define to 1 if you compile for Android. */ +#undef HAVE_ANDROID + /* Define to 1 if you have the avahi libraries. */ #undef HAVE_AVAHI diff --git a/configure b/configure index 51fe5fd..fbc1ccc 100755 --- a/configure +++ b/configure @@ -670,6 +670,8 @@ stap_LIBS elfutils_abs_srcdir BUILD_ELFUTILS_FALSE BUILD_ELFUTILS_TRUE +HAVE_ANDROID_FALSE +HAVE_ANDROID_TRUE python HAVE_LIBREADLINE_FALSE HAVE_LIBREADLINE_TRUE @@ -821,6 +823,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -868,6 +871,7 @@ enable_server with_avahi with_rpm with_python3 +with_android with_elfutils with_dyninst enable_virt @@ -943,6 +947,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1195,6 +1200,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1332,7 +1346,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1485,6 +1499,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1570,6 +1585,7 @@ Optional Packages: --without-avahi Do not use Avahi even if present --with-rpm query rpm database for missing debuginfos --with-python3 prefer /usr/bin/python3 + --with-android --with-elfutils=DIRECTORY find elfutils source code in DIRECTORY --with-dyninst=DIRECTORY @@ -7044,7 +7060,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7090,7 +7106,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7114,7 +7130,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7159,7 +7175,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -7183,7 +7199,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -10527,6 +10543,29 @@ else fi + +# Check whether --with-android was given. +if test "${with_android+set}" = set; then : + withval=$with_android; +fi + +if test "x$with_android" = "xyes"; then : + have_android=yes + +$as_echo "#define HAVE_ANDROID 1" >>confdefs.h + +else + have_android=no +fi + if test "${have_android}" == "yes"; then + HAVE_ANDROID_TRUE= + HAVE_ANDROID_FALSE='#' +else + HAVE_ANDROID_TRUE='#' + HAVE_ANDROID_FALSE= +fi + + build_elfutils=no # Check whether --with-elfutils was given. @@ -10715,7 +10754,8 @@ $as_echo "$as_me: stap will link $stap_LIBS" >&6;} # staprun has more modest libelf needs if test $build_elfutils = no; then save_LIBS="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for elf_getshdrstrndx in -lelf" >&5 + if test "${have_android}" == "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for elf_getshdrstrndx in -lelf" >&5 $as_echo_n "checking for elf_getshdrstrndx in -lelf... " >&6; } if ${ac_cv_lib_elf_elf_getshdrstrndx+:} false; then : $as_echo_n "(cached) " >&6 @@ -10758,16 +10798,57 @@ _ACEOF LIBS="-lelf $LIBS" +fi + + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for elf_getshdrstrndx in -lelf" >&5 +$as_echo_n "checking for elf_getshdrstrndx in -lelf... " >&6; } +if ${ac_cv_lib_elf_elf_getshdrstrndx+:} false; then : + $as_echo_n "(cached) " >&6 else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lelf $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char elf_getshdrstrndx (); +int +main () +{ +return elf_getshdrstrndx (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_elf_elf_getshdrstrndx=yes +else + ac_cv_lib_elf_elf_getshdrstrndx=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_elf_elf_getshdrstrndx" >&5 +$as_echo "$ac_cv_lib_elf_elf_getshdrstrndx" >&6; } +if test "x$ac_cv_lib_elf_elf_getshdrstrndx" = xyes; then : + staprun_LIBS="$staprun_LIBS -lelf" + LIBS="$save_LIBS" +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "libelf too old, need 0.142+ See \`config.log' for more details" "$LINENO" 5; } fi - staprun_LIBS="$staprun_LIBS -lelf" - LIBS="$save_LIBS" + fi else # We built our own and staprun_LDFLAGS points at the install. staprun_LIBS="$staprun_LIBS -lelf" @@ -11507,6 +11588,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext --exec-prefix="$exec_prefix" \ --prefix="$prefix" \ --enable-dwz \ + --host=${host_alias} \ ${need_maintainer_option} \ CFLAGS="${CFLAGS/-Wall/} $gnu89_inline_flag -fexceptions" \ LDFLAGS="$LDFLAGS $elfutils_rpath" && @@ -12067,6 +12149,10 @@ if test -z "${HAVE_LIBREADLINE_TRUE}" && test -z "${HAVE_LIBREADLINE_FALSE}"; th as_fn_error $? "conditional \"HAVE_LIBREADLINE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_ANDROID_TRUE}" && test -z "${HAVE_ANDROID_FALSE}"; then + as_fn_error $? "conditional \"HAVE_ANDROID\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${BUILD_ELFUTILS_TRUE}" && test -z "${BUILD_ELFUTILS_FALSE}"; then as_fn_error $? "conditional \"BUILD_ELFUTILS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/configure.ac b/configure.ac index cd781a2..f32ad68 100644 --- a/configure.ac +++ b/configure.ac @@ -422,7 +422,15 @@ AC_ARG_WITH([python3], AS_IF([test "x$with_python3" = "xyes"], [AC_SUBST(python,[python3])], [AC_SUBST(python,[python])]) - + +AC_ARG_WITH([android], + AS_HELP_STRING([--with-android],[])) +AS_IF([test "x$with_android" = "xyes"], + [have_android=yes + AC_DEFINE([HAVE_ANDROID], [1], [Define to 1 if you compile for Android.])], + [have_android=no]) +AM_CONDITIONAL([HAVE_ANDROID], [test "${have_android}" == "yes"]) + dnl Handle elfutils. If '--with-elfutils=DIR' wasn't specified, used dnl the system's elfutils. build_elfutils=no @@ -471,10 +479,15 @@ AC_MSG_NOTICE([stap will link $stap_LIBS]) if test $build_elfutils = no; then save_LIBS="$LIBS" dnl this will only succeed with elfutils 0.142+ - AC_CHECK_LIB(elf,elf_getshdrstrndx,[],[ - AC_MSG_FAILURE([libelf too old, need 0.142+])]) - staprun_LIBS="$staprun_LIBS -lelf" - LIBS="$save_LIBS" + if test "${have_android}" == "yes"; then + AC_CHECK_LIB(elf,elf_getshdrstrndx,[],[]) + + else + AC_CHECK_LIB(elf,elf_getshdrstrndx, + [staprun_LIBS="$staprun_LIBS -lelf" + LIBS="$save_LIBS"], + [AC_MSG_FAILURE([libelf too old, need 0.142+])]) + fi else # We built our own and staprun_LDFLAGS points at the install. staprun_LIBS="$staprun_LIBS -lelf" @@ -643,6 +656,7 @@ if test $build_elfutils = yes -a $enable_translator = yes; then --exec-prefix="$exec_prefix" \ --prefix="$prefix" \ --enable-dwz \ + --host=${host_alias} \ ${need_maintainer_option} \ CFLAGS="${CFLAGS/-Wall/} $gnu89_inline_flag -fexceptions" \ LDFLAGS="$LDFLAGS $elfutils_rpath" && diff --git a/doc/Makefile.in b/doc/Makefile.in index 1b4f10e..355dbc3 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -309,6 +309,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ python = @python@ +runstatedir = @runstatedir@ sbindir = @sbindir@ selinux_CFLAGS = @selinux_CFLAGS@ selinux_LIBS = @selinux_LIBS@ diff --git a/doc/SystemTap_Tapset_Reference/Makefile.in b/doc/SystemTap_Tapset_Reference/Makefile.in index 8426075..ecf46ec 100644 --- a/doc/SystemTap_Tapset_Reference/Makefile.in +++ b/doc/SystemTap_Tapset_Reference/Makefile.in @@ -316,6 +316,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ python = @python@ +runstatedir = @runstatedir@ sbindir = @sbindir@ selinux_CFLAGS = @selinux_CFLAGS@ selinux_LIBS = @selinux_LIBS@ diff --git a/doc/SystemTap_Tapset_Reference/tapsets.pdf b/doc/SystemTap_Tapset_Reference/tapsets.pdf deleted file mode 100644 index 9649e6d..0000000 Binary files a/doc/SystemTap_Tapset_Reference/tapsets.pdf and /dev/null differ diff --git a/doc/beginners/Makefile.in b/doc/beginners/Makefile.in index e584f13..337e743 100644 --- a/doc/beginners/Makefile.in +++ b/doc/beginners/Makefile.in @@ -275,6 +275,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ python = @python@ +runstatedir = @runstatedir@ sbindir = @sbindir@ selinux_CFLAGS = @selinux_CFLAGS@ selinux_LIBS = @selinux_LIBS@ @@ -370,8 +371,8 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -@BUILD_DOCS_FALSE@uninstall-local: @BUILD_DOCS_FALSE@clean-local: +@BUILD_DOCS_FALSE@uninstall-local: @BUILD_DOCS_FALSE@install-data-hook: clean: clean-am diff --git a/java/Makefile.in b/java/Makefile.in index d878b4b..b3437f1 100644 --- a/java/Makefile.in +++ b/java/Makefile.in @@ -363,6 +363,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ python = @python@ +runstatedir = @runstatedir@ sbindir = @sbindir@ selinux_CFLAGS = @selinux_CFLAGS@ selinux_LIBS = @selinux_LIBS@ @@ -640,9 +641,9 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +@HAVE_JAVA_FALSE@install-exec-local: @HAVE_JAVA_FALSE@uninstall-local: @HAVE_JAVA_FALSE@install-data-local: -@HAVE_JAVA_FALSE@install-exec-local: clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ diff --git a/man/Makefile.in b/man/Makefile.in index e6bed42..2cc06b9 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -347,6 +347,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ python = @python@ +runstatedir = @runstatedir@ sbindir = @sbindir@ selinux_CFLAGS = @selinux_CFLAGS@ selinux_LIBS = @selinux_LIBS@ diff --git a/man/cs/Makefile.in b/man/cs/Makefile.in index 3bedbf6..9036c6d 100644 --- a/man/cs/Makefile.in +++ b/man/cs/Makefile.in @@ -311,6 +311,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ python = @python@ +runstatedir = @runstatedir@ sbindir = @sbindir@ selinux_CFLAGS = @selinux_CFLAGS@ selinux_LIBS = @selinux_LIBS@ diff --git a/runtime/linux/autoconf-asm-syscall.c b/runtime/linux/autoconf-asm-syscall.c index bf7a273..6bfcd55 100644 --- a/runtime/linux/autoconf-asm-syscall.c +++ b/runtime/linux/autoconf-asm-syscall.c @@ -1,2 +1,8 @@ +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,200) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +#include +#include +#include +#else #include - +#endif diff --git a/runtime/linux/task_finder_stubs.c b/runtime/linux/task_finder_stubs.c index 700bb3d..39f9ec2 100644 --- a/runtime/linux/task_finder_stubs.c +++ b/runtime/linux/task_finder_stubs.c @@ -1,6 +1,7 @@ #ifndef TASK_FINDER_STUBS_C #define TASK_FINDER_STUBS_C +#include "syscall.h" /* Stubs of last resort for when utrace type functionality is not available. Nothing should actually work, but things compile properly, and silently return dummy data or noisily fail as diff --git a/runtime/syscall.h b/runtime/syscall.h index b959d46..b652946 100644 --- a/runtime/syscall.h +++ b/runtime/syscall.h @@ -7,7 +7,6 @@ * Public License (GPL); either version 2, or (at your option) any * later version. */ - #ifndef _SYSCALL_H_ /* -*- linux-c -*- */ #define _SYSCALL_H_ @@ -110,7 +109,14 @@ #ifdef STAPCONF_ASM_SYSCALL_H /* If the system has asm/syscall.h, use defines from it. */ +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,200) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +#include +#include +#include +#else #include +#endif #if defined(__arm__) /* The syscall_get_nr() function on 3.17.1-302.fc21.armv7hl always diff --git a/session.cxx b/session.cxx index fd3d680..deb82aa 100644 --- a/session.cxx +++ b/session.cxx @@ -132,6 +132,7 @@ systemtap_session::systemtap_session (): last_pass = 5; module_name = "stap_" + lex_cast(getpid()); stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h"; + pid_file = ""; output_file = ""; // -o FILE tmpdir_opt_set = false; monitor = false; @@ -165,6 +166,7 @@ systemtap_session::systemtap_session (): try_server_status = try_server_unset; use_remote_prefix = false; systemtap_v_check = false; + excl_include_path = false; download_dbinfo = 0; suppress_handler_errors = false; native_build = true; // presumed @@ -319,6 +321,7 @@ systemtap_session::systemtap_session (const systemtap_session& other, last_pass = other.last_pass; module_name = other.module_name; stapconf_name = other.stapconf_name; + pid_file = other.pid_file; output_file = other.output_file; // XXX how should multiple remotes work? tmpdir_opt_set = false; monitor = other.monitor; @@ -568,7 +571,8 @@ systemtap_session::usage (int exitcode) for (unsigned i=0; i ../$(am__dirstamp) diff --git a/staprun/common.c b/staprun/common.c index f16e56a..7fbfa30 100644 --- a/staprun/common.c +++ b/staprun/common.c @@ -35,6 +35,7 @@ int target_namespaces_pid; unsigned int buffer_size; unsigned int reader_timeout_ms; char *target_cmd; +char *pidfile_name; char *outfile_name; int rename_mod; int attach_mod; @@ -120,6 +121,7 @@ void parse_args(int argc, char **argv) buffer_size = 0; reader_timeout_ms = 0; target_cmd = NULL; + pidfile_name = NULL; outfile_name = NULL; rename_mod = 0; attach_mod = 0; @@ -138,7 +140,7 @@ void parse_args(int argc, char **argv) color_errors = isatty(STDERR_FILENO) && strcmp(getenv("TERM") ?: "notdumb", "dumb"); - while ((c = getopt(argc, argv, "ALu::vhb:t:dc:o:x:N:S:DwRr:VT:C:M:" + while ((c = getopt(argc, argv, "ALu::vhb:t:dc:o:x:N:S:DwRr:VT:M:C:U:" #ifdef HAVE_OPENAT "F:" #endif @@ -181,6 +183,9 @@ void parse_args(int argc, char **argv) case 'c': target_cmd = optarg; break; + case 'U': + pidfile_name = optarg; + break; case 'o': outfile_name = optarg; break; @@ -340,7 +345,7 @@ void parse_args(int argc, char **argv) void usage(char *prog, int rc) { printf(_("\n%s [-v] [-w] [-V] [-h] [-u] [-c cmd ] [-x pid] [-u user] [-A|-L|-d] [-C WHEN]\n" - "\t[-b bufsize] [-R] [-r N:URI] [-o FILE [-D] [-S size[,N]]] MODULE [module-options]\n"), prog); + "\t[-b bufsize] [-R] [-r N:URI] [-o FILE [-D] [-S size[,N]]] [-U PID_FILE] MODULE [module-options]\n"), prog); printf(_("-v Increase verbosity.\n" "-V Print version number and exit.\n" "-h Print this help text and exit.\n" @@ -350,7 +355,8 @@ void usage(char *prog, int rc) " exit when it does. The '_stp_target' variable\n" " will contain the pid for the command.\n" "-x pid Sets the '_stp_target' variable to pid.\n" - "-N pid Sets the '_stp_namespaces_pid' variable to pid.\n" + "-U PIDFILE Create a pid file while running\n" + "-N pid Sets the '_stp_namespaces_pid' variable to pid.\n" "-o FILE Send output to FILE. This supports strftime(3)\n" " formats for FILE.\n" "-b buffer size The systemtap module specifies a buffer size.\n" @@ -751,6 +757,37 @@ char *parse_stap_color(const char *type) return NULL; /* key not found */ } +void create_pidfile(const char *pidfile_name) +{ + int fd = 0, printed = 0; + char pid_text[15]; + pid_t pid = getpid(); + + fd = open(pidfile_name,O_CREAT|O_WRONLY|O_TRUNC,0644); + if (fd < 0) + { + err("Could not open pidfile:%s\n",strerror(errno)); + exit(1); + return; + } + + printed = sprintf((char*)&pid_text,"%d\n",pid); + if (write(fd,&pid_text,printed) < 0) + { + err("Could not write pid to pidfile:%s\n",strerror(errno)); + exit(1); + } + close(fd); +} + +void delete_pidfile(const char *pidfile_name) +{ + if (unlink(pidfile_name) < 0) + { + err("Could not delete pidfile:%s\n",strerror(errno)); + } +} + void closefrom(int lowfd) { diff --git a/staprun/mainloop.c b/staprun/mainloop.c index 82c0c74..006783f 100644 --- a/staprun/mainloop.c +++ b/staprun/mainloop.c @@ -20,6 +20,12 @@ #define WORKAROUND_BZ467568 1 /* PR 6964; XXX: autoconf when able */ +#ifdef HAVE_ANDROID +#define SYSTEM_SHELL "/system/bin/sh" +#else +#define SYSTEM_SHELL "sh" +#endif + /* globals */ int ncpus; @@ -548,6 +554,9 @@ void cleanup_and_exit(int detach, int rc) sa.sa_handler = SIG_DFL; sigaction(SIGCHLD, &sa, NULL); + if (pidfile_name) + delete_pidfile(pidfile_name); + pid = fork(); if (pid < 0) { _perr("fork"); @@ -564,7 +573,7 @@ void cleanup_and_exit(int detach, int rc) : color_mode == color_auto ? "auto" : "never", modname); if (rc >= 1) { - execlp("sh", "sh", "-c", cmd, NULL); + execlp(SYSTEM_SHELL, SYSTEM_SHELL, "-c", cmd, NULL); /* should not return */ perror(staprun); _exit(-1); diff --git a/staprun/stapio.c b/staprun/stapio.c index 664896d..d61d30e 100644 --- a/staprun/stapio.c +++ b/staprun/stapio.c @@ -70,10 +70,18 @@ int main(int argc, char **argv) if (init_stapio()) exit(1); + if (pidfile_name) + create_pidfile(pidfile_name); + if (stp_main_loop()) { err(_("Couldn't enter main loop. Exiting.\n")); + if (pidfile_name) + delete_pidfile(pidfile_name); + exit(1); } + if (pidfile_name) + delete_pidfile(pidfile_name); return 0; } diff --git a/staprun/staprun.c b/staprun/staprun.c index 89e6d8b..3159210 100644 --- a/staprun/staprun.c +++ b/staprun/staprun.c @@ -350,8 +350,10 @@ int init_staprun(void) disable_kprobes_optimization(); if (insert_stap_module(& user_credentials) < 0) { +#ifdef HAVE_ANDROID if(!rename_mod && errno == EEXIST) err("Rerun with staprun option '-R' to rename this module.\n"); +#endif return -1; } rc = init_ctl_channel (modname, 0); diff --git a/staprun/staprun.h b/staprun/staprun.h index 8e0c664..7df0969 100644 --- a/staprun/staprun.h +++ b/staprun/staprun.h @@ -220,6 +220,8 @@ void usage(char *prog, int rc); void parse_modpath(const char *); void setup_signals(void); int set_clexec(int fd); +void create_pidfile(const char *pidfile_name); +void delete_pidfile(const char *pidfile_name); int open_cloexec(const char *pathname, int flags, mode_t mode); #ifdef HAVE_OPENAT int openat_cloexec(int dirfd, const char *pathname, int flags, mode_t mode); @@ -258,6 +260,7 @@ extern char *modpath; extern char *modoptions[MAXMODOPTIONS]; extern int target_pid; extern char *target_cmd; +extern char *pidfile_name; extern int target_namespaces_pid; extern char *outfile_name; extern int rename_mod; diff --git a/staprun/staprun_funcs.c b/staprun/staprun_funcs.c index 16d3bed..c30d4d9 100644 --- a/staprun/staprun_funcs.c +++ b/staprun/staprun_funcs.c @@ -19,10 +19,12 @@ #include #include +#ifndef HAVE_ANDROID /* The module-renaming facility only works with new enough elfutils: 0.142+. */ #include #include +#endif #include @@ -198,6 +200,7 @@ int insert_module( return 0; } +#ifndef HAVE_ANDROID static Elf_Scn * find_section_in_module(const void* module_file, const __off_t st_size, const char *section_name) { @@ -236,10 +239,12 @@ find_section_in_module(const void* module_file, const __off_t st_size, const cha } return scn; } +#endif /* HAVE_ANDROID */ int rename_module(void* module_file, const __off_t st_size) { +#ifndef HAVE_ANDROID int length_to_replace; char newname[MODULE_NAME_LEN]; char *p; @@ -297,6 +302,14 @@ rename_module(void* module_file, const __off_t st_size) } _err("Could not find old name to replace!\n"); return -1; +#else + /* Old or no elfutils? Pretend to have renamed. This means a + greater likelihood for module-name collisions, but so be + it. */ + (void) module_file; + (void) st_size; + return 0; +#endif /* HAVE_ANDROID */ } @@ -574,6 +587,22 @@ static privilege_t get_module_required_credentials ( const __off_t st_size __attribute__ ((unused)) ) { +#ifdef HAVE_ANDROID + /* Without the proper ELF support, we can't determine the credentials required to run this + module. However, we know that it has been correctly signed (we only check privilege + credentials for correctly signed modules). It is therefore either + a) a dual-privilege-level era module compiled with stapusr privileges enforced or, + b) a multi-privilege-level era module with built-in privilege level checking. + In either case, we can load it for stapusr level users and above. In case a, it requires + exactly that privilege level. In case b, the module will self check against the user's + actual privilege level. + */ + if (verbose >= 1) { + err ("Unable to determine the privilege level required for the module %s. Assuming %s.\n", + module_path, pr_name (pr_stapusr)); + } + return pr_stapusr; +#else Elf_Scn *scn = 0; Elf_Data *data = 0; GElf_Shdr shdr; @@ -658,6 +687,7 @@ static privilege_t get_module_required_credentials ( /* ALl is ok. Return the extracted privilege data. */ return privilege; +#endif /* HAVE_ANDROID */ } /* diff --git a/tapset/linux/task_time.stp b/tapset/linux/task_time.stp index f86f984..f3c276c 100644 --- a/tapset/linux/task_time.stp +++ b/tapset/linux/task_time.stp @@ -27,8 +27,12 @@ * Yet note some kernels (RHEL6) may already have both... */ #if defined(cputime_to_usecs) #if !defined(cputime_to_msecs) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,200) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +#define cputime_to_msecs(__ct) _stp_div64(NULL, ({cputime_to_usecs(__ct)}), 1000ULL) +#else #define cputime_to_msecs(__ct) _stp_div64(NULL, cputime_to_usecs(__ct), 1000ULL) #endif +#endif /* Kernels before 2.6.37 have cputime_to_msecs, but not usecs. */ #elif defined(cputime_to_msecs)