diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-03-20 09:35:44 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-03-20 09:35:44 +0100 |
commit | 9ba817408c6eb81d9ed470314cff1d2d412c4b68 (patch) | |
tree | 81cdd381dc4a9c8007102ce4465a7a2c6c016a4e | |
parent | 5e94ef56760c087784e485c35521a6e438cfc3e5 (diff) | |
parent | 0cf9ea606eb7677a1241595f7568dd4a6c243ef2 (diff) | |
download | systemtap-steved-9ba817408c6eb81d9ed470314cff1d2d412c4b68.tar.gz systemtap-steved-9ba817408c6eb81d9ed470314cff1d2d412c4b68.tar.xz systemtap-steved-9ba817408c6eb81d9ed470314cff1d2d412c4b68.zip |
Merge branch 'master' into pr6866
-rw-r--r-- | Makefile.in | 1 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | buildrun.cxx | 1 | ||||
-rw-r--r-- | doc/Makefile.in | 1 | ||||
-rw-r--r-- | doc/SystemTap_Tapset_Reference/Makefile.am | 6 | ||||
-rw-r--r-- | doc/SystemTap_Tapset_Reference/Makefile.in | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | doc/Tapset_Reference_Guide/manpager.sh | 0 | ||||
-rw-r--r-- | parse.cxx | 6 | ||||
-rw-r--r-- | runtime/autoconf-find-task-pid.c | 6 | ||||
-rw-r--r-- | runtime/itrace.c | 50 | ||||
-rw-r--r-- | runtime/task_finder.c | 6 | ||||
-rw-r--r-- | runtime/utrace_compatibility.h | 9 | ||||
-rwxr-xr-x | scripts/kernel-doc | 4 | ||||
-rw-r--r-- | stapprobes.5.in | 13 | ||||
-rw-r--r-- | systemtap.spec | 9 | ||||
-rw-r--r-- | tapset/aux_syscalls.stp | 7 | ||||
-rw-r--r-- | tapsets.cxx | 128 | ||||
-rw-r--r-- | testsuite/systemtap.base/itrace.exp | 7 |
18 files changed, 187 insertions, 79 deletions
diff --git a/Makefile.in b/Makefile.in index 73ef5bac..12a5e6ea 100644 --- a/Makefile.in +++ b/Makefile.in @@ -288,6 +288,7 @@ staplog_CPPFLAGS = @staplog_CPPFLAGS@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @@ -1,5 +1,10 @@ * What's new +- In guru mode (-g), the kernel probing blacklist is disabled, leaving + only a subset - the kernel's own internal kprobe blacklist - to attempt + to filter out areas unsafe to probe. The differences may be enough to + probe more interrupt handlers. + - Variables unavailable in current context may be skipped by setting a session level flag with command line option --skip-badvars now available. This will simply substitute the otherwise error causing variable with a diff --git a/buildrun.cxx b/buildrun.cxx index b9d648ef..0e9e0e17 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -148,6 +148,7 @@ compile_pass (systemtap_session& s) output_autoconf(s, o, "autoconf-vm-area.c", "STAPCONF_VM_AREA", NULL); output_autoconf(s, o, "autoconf-procfs-owner.c", "STAPCONF_PROCFS_OWNER", NULL); output_autoconf(s, o, "autoconf-alloc-percpu-align.c", "STAPCONF_ALLOC_PERCPU_ALIGN", NULL); + output_autoconf(s, o, "autoconf-find-task-pid.c", "STAPCONF_FIND_TASK_PID", NULL); #if 0 /* NB: For now, the performance hit of probe_kernel_read/write (vs. our diff --git a/doc/Makefile.in b/doc/Makefile.in index 93753666..e23a6699 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -163,6 +163,7 @@ staplog_CPPFLAGS = @staplog_CPPFLAGS@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ PDF_FILES = tutorial.pdf langref.pdf diff --git a/doc/SystemTap_Tapset_Reference/Makefile.am b/doc/SystemTap_Tapset_Reference/Makefile.am index 9e7d2069..68dfd971 100644 --- a/doc/SystemTap_Tapset_Reference/Makefile.am +++ b/doc/SystemTap_Tapset_Reference/Makefile.am @@ -2,7 +2,7 @@ ## process this file with automake to produce Makefile.in DOC_INSTALL_DIR = $(DESTDIR)$(datadir)/doc/systemtap -MAN_INSTALL_DIR = $(DESTDIR)$(mandir)/man5 +MAN_INSTALL_DIR = $(DESTDIR)$(mandir)/man3stap HTML_INSTALL_DIR = $(DESTDIR)$(datadir)/doc/systemtap/tapsets @@ -36,7 +36,7 @@ tapsets.pdf: tapsets.xml xmlto pdf tapsets.xml stamp-mandocs: tapsets.xml - xmlto man -o man5 tapsets.xml + xmlto man -o man3stap tapsets.xml touch stamp-mandocs #FIXME need to figure out where to install things appropriately @@ -45,7 +45,7 @@ install-data-hook: $(MKDIR_P) $(DOC_INSTALL_DIR) $(INSTALL_DATA) tapsets.pdf $(DOC_INSTALL_DIR) $(MKDIR_P) $(MAN_INSTALL_DIR) - $(INSTALL_DATA) man5/* $(MAN_INSTALL_DIR) + $(INSTALL_DATA) man3stap/* $(MAN_INSTALL_DIR) $(MKDIR_P) $(HTML_INSTALL_DIR) $(INSTALL_DATA) tapsets/* $(HTML_INSTALL_DIR) endif diff --git a/doc/SystemTap_Tapset_Reference/Makefile.in b/doc/SystemTap_Tapset_Reference/Makefile.in index 84d2114c..2f8a5294 100644 --- a/doc/SystemTap_Tapset_Reference/Makefile.in +++ b/doc/SystemTap_Tapset_Reference/Makefile.in @@ -166,10 +166,11 @@ staplog_CPPFLAGS = @staplog_CPPFLAGS@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DOC_INSTALL_DIR = $(DESTDIR)$(datadir)/doc/systemtap -MAN_INSTALL_DIR = $(DESTDIR)$(mandir)/man5 +MAN_INSTALL_DIR = $(DESTDIR)$(mandir)/man3stap HTML_INSTALL_DIR = $(DESTDIR)$(datadir)/doc/systemtap/tapsets SRCTREE = $(abs_top_srcdir)/ DOCPROC = $(abs_builddir)/docproc @@ -429,7 +430,7 @@ uninstall-am: @BUILD_REFDOCS_TRUE@ xmlto pdf tapsets.xml @BUILD_REFDOCS_TRUE@stamp-mandocs: tapsets.xml -@BUILD_REFDOCS_TRUE@ xmlto man -o man5 tapsets.xml +@BUILD_REFDOCS_TRUE@ xmlto man -o man3stap tapsets.xml @BUILD_REFDOCS_TRUE@ touch stamp-mandocs #FIXME need to figure out where to install things appropriately @@ -438,7 +439,7 @@ uninstall-am: @BUILD_REFDOCS_TRUE@ $(MKDIR_P) $(DOC_INSTALL_DIR) @BUILD_REFDOCS_TRUE@ $(INSTALL_DATA) tapsets.pdf $(DOC_INSTALL_DIR) @BUILD_REFDOCS_TRUE@ $(MKDIR_P) $(MAN_INSTALL_DIR) -@BUILD_REFDOCS_TRUE@ $(INSTALL_DATA) man5/* $(MAN_INSTALL_DIR) +@BUILD_REFDOCS_TRUE@ $(INSTALL_DATA) man3stap/* $(MAN_INSTALL_DIR) @BUILD_REFDOCS_TRUE@ $(MKDIR_P) $(HTML_INSTALL_DIR) @BUILD_REFDOCS_TRUE@ $(INSTALL_DATA) tapsets/* $(HTML_INSTALL_DIR) # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/doc/Tapset_Reference_Guide/manpager.sh b/doc/Tapset_Reference_Guide/manpager.sh index 0051d208..0051d208 100644..100755 --- a/doc/Tapset_Reference_Guide/manpager.sh +++ b/doc/Tapset_Reference_Guide/manpager.sh @@ -2341,6 +2341,12 @@ parser::parse_symbol () cop->operand = parse_expression (); expect_op(","); expect_unknown(tok_string, cop->type); + // types never start with "struct<space>" or "union<space>", + // so gobble it up. + if (cop->type.compare(0, 7, "struct ") == 0) + cop->type = cop->type.substr(7); + if (cop->type.compare(0, 6, "union ") == 0) + cop->type = cop->type.substr(6); if (peek_op (",")) { next(); diff --git a/runtime/autoconf-find-task-pid.c b/runtime/autoconf-find-task-pid.c new file mode 100644 index 00000000..549d5ac3 --- /dev/null +++ b/runtime/autoconf-find-task-pid.c @@ -0,0 +1,6 @@ +#include <linux/sched.h> + +void foo (pid_t k) { + struct task_struct *tsk = find_task_by_pid (k); + (void) tsk; +} diff --git a/runtime/itrace.c b/runtime/itrace.c index ed32b0bc..3d9ded2f 100644 --- a/runtime/itrace.c +++ b/runtime/itrace.c @@ -1,6 +1,7 @@ /* * user space instruction tracing * Copyright (C) 2005, 2006, 2007, 2008, 2009 IBM Corp. + * Copyright (C) 2009 Red Hat Inc. * * 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 @@ -19,6 +20,7 @@ #include <linux/utrace.h> #include <asm/string.h> #include "uprobes/uprobes.h" +#include "utrace_compatibility.h" #ifndef put_task_struct #define put_task_struct(t) \ @@ -55,7 +57,7 @@ struct itrace_info { struct list_head link; }; -static u32 debug = 1; +static u32 debug = 0 /* 1 */; static LIST_HEAD(usr_itrace_info); static spinlock_t itrace_lock; @@ -118,10 +120,15 @@ static int __access_process_vm(struct task_struct *tsk, unsigned long addr, void return buf - old_buf; } +#ifdef UTRACE_ORIG_VERSION +static u32 usr_itrace_report_quiesce(struct utrace_attached_engine *engine, + struct task_struct *tsk) +#else static u32 usr_itrace_report_quiesce(enum utrace_resume_action action, struct utrace_attached_engine *engine, struct task_struct *tsk, unsigned long event) +#endif { int status; struct itrace_info *ui; @@ -129,10 +136,23 @@ static u32 usr_itrace_report_quiesce(enum utrace_resume_action action, ui = rcu_dereference(engine->data); WARN_ON(!ui); +#ifdef UTRACE_ORIG_VERSION + return (ui->step_flag); // XXX XXX XXX +#else return (event == 0 ? ui->step_flag : UTRACE_RESUME); +#endif } +#ifdef UTRACE_ORIG_VERSION +static u32 usr_itrace_report_signal( + struct utrace_attached_engine *engine, + struct task_struct *tsk, + struct pt_regs *regs, + u32 action, siginfo_t *info, + const struct k_sigaction *orig_ka, + struct k_sigaction *return_ka) +#else static u32 usr_itrace_report_signal(u32 action, struct utrace_attached_engine *engine, struct task_struct *tsk, @@ -140,6 +160,7 @@ static u32 usr_itrace_report_signal(u32 action, siginfo_t *info, const struct k_sigaction *orig_ka, struct k_sigaction *return_ka) +#endif { struct itrace_info *ui; u32 return_flags; @@ -174,16 +195,31 @@ static u32 usr_itrace_report_signal(u32 action, return return_flags; } + + +#ifdef UTRACE_ORIG_VERSION +static u32 usr_itrace_report_clone( + struct utrace_attached_engine *engine, + struct task_struct *parent, + unsigned long clone_flags, + struct task_struct *child) +#else static u32 usr_itrace_report_clone(enum utrace_resume_action action, struct utrace_attached_engine *engine, struct task_struct *parent, unsigned long clone_flags, struct task_struct *child) +#endif { return UTRACE_RESUME; } +#ifdef UTRACE_ORIG_VERSION +static u32 usr_itrace_report_death(struct utrace_attached_engine *e, + struct task_struct *tsk) +#else static u32 usr_itrace_report_death(struct utrace_attached_engine *e, struct task_struct *tsk, bool group_dead, int signal) +#endif { struct itrace_info *ui = rcu_dereference(e->data); WARN_ON(!ui); @@ -275,8 +311,13 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe struct itrace_info *ui; struct task_struct *tsk; + spin_lock_init(&itrace_lock); rcu_read_lock(); +#ifdef STAPCONF_FIND_TASK_PID + tsk = find_task_by_pid(tid); +#else tsk = find_task_by_vpid(tid); +#endif if (!tsk) { printk(KERN_ERR "usr_itrace_init: Cannot find process %d\n", tid); rcu_read_unlock(); @@ -293,11 +334,6 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe put_task_struct(tsk); rcu_read_unlock(); - spin_lock_init(&itrace_lock); - - /* set initial state */ - spin_lock(&itrace_lock); - spin_unlock(&itrace_lock); printk(KERN_INFO "usr_itrace_init: completed for tid = %d\n", tid); return 0; @@ -314,7 +350,6 @@ void static remove_usr_itrace_info(struct itrace_info *ui) if (debug) printk(KERN_INFO "remove_usr_itrace_info: tid=%d\n", ui->tid); - spin_lock(&itrace_lock); if (ui->tsk && ui->engine) { status = utrace_control(ui->tsk, ui->engine, UTRACE_DETACH); if (status < 0 && status != -ESRCH && status != -EALREADY) @@ -322,6 +357,7 @@ void static remove_usr_itrace_info(struct itrace_info *ui) "utrace_control(UTRACE_DETACH) returns %d\n", status); } + spin_lock(&itrace_lock); list_del(&ui->link); spin_unlock(&itrace_lock); kfree(ui); diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 1db2bc2a..cc24dc10 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -992,6 +992,7 @@ __stp_utrace_task_finder_target_syscall_entry(enum utrace_resume_action action, static void __stp_call_vm_callbacks_with_vma(struct stap_task_finder_target *tgt, struct task_struct *tsk, + int map_p, struct vm_area_struct *vma) { char *mmpath_buf; @@ -1018,7 +1019,7 @@ __stp_call_vm_callbacks_with_vma(struct stap_task_finder_target *tgt, rc, (int)tsk->pid); } else { - __stp_call_vm_callbacks(tgt, tsk, 1, mmpath, + __stp_call_vm_callbacks(tgt, tsk, map_p, mmpath, vma->vm_start, vma->vm_end, (vma->vm_pgoff << PAGE_SHIFT)); } @@ -1111,7 +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_call_vm_callbacks_with_vma(tgt, tsk, vma); + __stp_call_vm_callbacks_with_vma(tgt, tsk, 0, vma); } up_read(&mm->mmap_sem); mmput(mm); @@ -1184,6 +1185,7 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, && vma->vm_end <= entry->vm_end) { __stp_call_vm_callbacks_with_vma(tgt, tsk, + 1, vma); if (vma->vm_end >= entry->vm_end) break; diff --git a/runtime/utrace_compatibility.h b/runtime/utrace_compatibility.h index 00b841d2..4a70da42 100644 --- a/runtime/utrace_compatibility.h +++ b/runtime/utrace_compatibility.h @@ -1,6 +1,6 @@ /* * utrace compatibility defines and inlines - * Copyright (C) 2008 Red Hat Inc. + * Copyright (C) 2008-2009 Red Hat Inc. * * 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 @@ -28,6 +28,8 @@ enum utrace_resume_action { UTRACE_STOP = UTRACE_ACTION_QUIESCE, UTRACE_RESUME = UTRACE_ACTION_RESUME, UTRACE_DETACH = UTRACE_ACTION_DETACH, + UTRACE_SINGLESTEP = UTRACE_ACTION_SINGLESTEP, + UTRACE_BLOCKSTEP = UTRACE_ACTION_BLOCKSTEP, }; static inline struct utrace_attached_engine * @@ -48,6 +50,11 @@ utrace_control(struct task_struct *target, case UTRACE_STOP: return utrace_set_flags(target, engine, (engine->flags | UTRACE_ACTION_QUIESCE)); + case UTRACE_SINGLESTEP: + case UTRACE_BLOCKSTEP: + return utrace_set_flags(target, engine, + engine->flags | action); + default: return -EINVAL; } diff --git a/scripts/kernel-doc b/scripts/kernel-doc index add4ba3c..9947882d 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -981,7 +981,7 @@ sub output_probe_xml(%) { print "</refentryinfo>\n"; print "<refmeta>\n"; print " <refentrytitle><phrase>".$args{'probe'}."</phrase></refentrytitle>\n"; - print " <manvolnum>5</manvolnum>\n"; + print " <manvolnum>3stap</manvolnum>\n"; # print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; print "</refmeta>\n"; print "<refnamediv>\n"; @@ -1039,7 +1039,7 @@ sub output_sfunction_xml(%) { print "</refentryinfo>\n"; print "<refmeta>\n"; print " <refentrytitle><phrase>".$args{'sfunction'}."</phrase></refentrytitle>\n"; - print " <manvolnum>5</manvolnum>\n"; + print " <manvolnum>3stap</manvolnum>\n"; # print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; print "</refmeta>\n"; print "<refnamediv>\n"; diff --git a/stapprobes.5.in b/stapprobes.5.in index 70d045c4..f4a872cb 100644 --- a/stapprobes.5.in +++ b/stapprobes.5.in @@ -407,8 +407,10 @@ process.syscall process(PID).syscall.return process("PATH").syscall.return process.syscall.return -process(PID).itrace -process("PATH").itrace +process(PID).insn +process("PATH").insn +process(PID).insn.block +process("PATH").insn.block process("PATH").mark("LABEL") .ESAMPLE .PP @@ -443,8 +445,11 @@ in the .BR $return context variable. A -.B .itrace -probe gets called for every single step of the process described by PID or PATH. +.B .insn +probe gets called for every single-stepped instruction of the process described by PID or PATH. +A +.B .insn.block +probe gets called for every block-stepped instruction of the process described by PID or PATH. A .B .mark probe gets called via a static probe which is defined in the diff --git a/systemtap.spec b/systemtap.spec index 7277f92a..540a9d93 100644 --- a/systemtap.spec +++ b/systemtap.spec @@ -1,4 +1,3 @@ -%{!?release: %define release 1} %{!?with_sqlite: %define with_sqlite 1} %{!?with_docs: %define with_docs 1} %{!?with_crash: %define with_crash 0} @@ -6,9 +5,9 @@ %{!?elfutils_version: %define elfutils_version 0.127} Name: systemtap -# for version, see also configure.ac Version: 0.9 -Release: %{release}%{?dist} +Release: 3%{?dist} +# for version, see also configure.ac Summary: Instrumentation System Group: Development/System License: GPLv2+ @@ -246,6 +245,7 @@ exit 0 %if %{with_docs} %doc docs.installed/*.pdf %doc docs.installed/tapsets +%{_mandir}/man3stap/* %endif %{_bindir}/stap @@ -317,6 +317,9 @@ exit 0 %changelog +* Wed Mar 18 2009 Will Cohen <wcohen@redhat.com> - 0.9-2 +- Add location of man pages. + * Tue Feb 17 2009 Frank Ch. Eigler <fche@redhat.com> - 0.9-1 - Upstream release. diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index d2e43903..87ea4e04 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -322,17 +322,10 @@ function _struct_sockaddr_u:string(uaddr:long, len:long) } else if ((sa->sa_family == AF_PACKET)&&(len == sizeof(struct sockaddr_ll))) { - /* FIXME. This needs tested */ struct sockaddr_ll *sll = (struct sockaddr_ll *)buf; -#if defined(__powerpc__) || defined(__ia64__) || defined(__s390x__) - snprintf(str, strlen, "{AF_PACKET, proto=%d, ind=%d, hatype=%d, pkttype=%d, halen=%d, addr=0x%lx}", - (int)sll->sll_protocol, sll->sll_ifindex, (int)sll->sll_hatype, (int)sll->sll_pkttype, - (int)sll->sll_halen, *(uint64_t *)sll->sll_addr); -#else snprintf(str, strlen, "{AF_PACKET, proto=%d, ind=%d, hatype=%d, pkttype=%d, halen=%d, addr=0x%llx}", (int)sll->sll_protocol, sll->sll_ifindex, (int)sll->sll_hatype, (int)sll->sll_pkttype, (int)sll->sll_halen, *(uint64_t *)sll->sll_addr); -#endif } else { diff --git a/tapsets.cxx b/tapsets.cxx index 89e011c4..d7b55e33 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3521,9 +3521,17 @@ dwarf_query::blacklisted_p(const string& funcname, if (! (goodfn && goodfile)) { - if (sess.verbose>1) - clog << " skipping - blacklisted"; - return true; + if (sess.guru_mode) + { + if (sess.verbose>1) + clog << " guru mode enabled - ignoring blacklist"; + } + else + { + if (sess.verbose>1) + clog << " skipping - blacklisted"; + return true; + } } // This probe point is not blacklisted. @@ -5059,7 +5067,8 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) // cast_op to the next pass. We hope that this value ends // up not being referenced after all, so it can be optimized out // quietly. - semantic_error* er = new semantic_error ("type definition not found", e->tok); + string msg = "type definition '" + e->type + "' not found"; + semantic_error* er = new semantic_error (msg, e->tok); // NB: we can have multiple errors, since a @cast // may be expanded in several different contexts: // function ("*") { @cast(...) } @@ -6240,6 +6249,9 @@ task_finder_derived_probe_group::emit_module_exit (systemtap_session& s) // ------------------------------------------------------------------------ +static string TOK_INSN("insn"); +static string TOK_BLOCK("block"); + struct itrace_derived_probe: public derived_probe { bool has_path; @@ -6314,7 +6326,7 @@ struct itrace_builder: public derived_probe_builder // XXX: PR 6445 needs !has_path && !has_pid support assert (has_path || has_pid); - single_step = 1; + single_step = ! has_null_param (parameters, TOK_BLOCK); // If we have a path, we need to validate it. if (has_path) @@ -9269,10 +9281,10 @@ mark_builder::build(systemtap_session & sess, struct tracepoint_arg { - string name, c_type; - bool used, isptr; + string name, c_type, typecast; + bool usable, used, isptr; Dwarf_Die type_die; - tracepoint_arg(): used(false), isptr(false) {} + tracepoint_arg(): usable(false), used(false), isptr(false) {} }; struct tracepoint_derived_probe: public derived_probe @@ -9324,7 +9336,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) // search for a tracepoint parameter matching this name tracepoint_arg *arg = NULL; for (unsigned i = 0; i < args.size(); ++i) - if (args[i].name == argname) + if (args[i].usable && args[i].name == argname) { arg = &args[i]; arg->used = true; @@ -9372,6 +9384,9 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) if (lvalue && (!dw.sess.guru_mode || e->components.empty())) throw semantic_error("write to tracepoint variable '" + e->base_name + "' not permitted", e->tok); + // XXX: if a struct/union arg is passed by value, then writing to its fields + // is also meaningless until you dereference past a pointer member. It's + // harder to detect and prevent that though... if (e->components.empty()) { @@ -9543,6 +9558,8 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) for (unsigned i = 0; i < args.size(); ++i) { + if (!args[i].usable) + continue; if (i > 0) pf->raw_components += " "; pf->raw_components += args[i].name; @@ -9625,32 +9642,39 @@ tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s, static bool dwarf_type_name(Dwarf_Die& type_die, string& c_type) { - // if this die has a direct name, then we're done - const char *diename = dwarf_diename_integrate(&type_die); - if (diename != NULL) + // if we've gotten down to a basic type, then we're done + bool done = true; + switch (dwarf_tag(&type_die)) { - switch (dwarf_tag(&type_die)) - { - case DW_TAG_structure_type: - c_type.append("struct "); - break; - case DW_TAG_union_type: - c_type.append("union "); - break; - } - c_type.append(diename); + case DW_TAG_structure_type: + c_type.append("struct "); + break; + case DW_TAG_union_type: + c_type.append("union "); + break; + case DW_TAG_typedef: + case DW_TAG_base_type: + break; + default: + done = false; + break; + } + if (done) + { + c_type.append(dwarf_diename_integrate(&type_die)); return true; } // otherwise, this die is a type modifier. // recurse into the referent type + // if it can't be named, just call it "void" Dwarf_Attribute subtype_attr; Dwarf_Die subtype_die; if (!dwarf_attr_integrate(&type_die, DW_AT_type, &subtype_attr) || !dwarf_formref_die(&subtype_attr, &subtype_die) || !dwarf_type_name(subtype_die, c_type)) - return false; + c_type = "void"; const char *suffix = NULL; switch (dwarf_tag(&type_die)) @@ -9671,33 +9695,47 @@ dwarf_type_name(Dwarf_Die& type_die, string& c_type) return false; } c_type.append(suffix); + + // XXX HACK! The va_list isn't usable as found in the debuginfo... + if (c_type == "struct __va_list_tag*") + c_type = "va_list"; + return true; } static bool -resolve_tracepoint_arg_type(Dwarf_Die& type_die, bool& isptr) +resolve_tracepoint_arg_type(tracepoint_arg& arg) { Dwarf_Attribute type_attr; - switch (dwarf_tag(&type_die)) + switch (dwarf_tag(&arg.type_die)) { case DW_TAG_typedef: case DW_TAG_const_type: case DW_TAG_volatile_type: // iterate on the referent type - return (dwarf_attr_integrate(&type_die, DW_AT_type, &type_attr) - && dwarf_formref_die(&type_attr, &type_die) - && resolve_tracepoint_arg_type(type_die, isptr)); + return (dwarf_attr_integrate(&arg.type_die, DW_AT_type, &type_attr) + && dwarf_formref_die(&type_attr, &arg.type_die) + && resolve_tracepoint_arg_type(arg)); case DW_TAG_base_type: // base types will simply be treated as script longs - isptr = false; + arg.isptr = false; return true; case DW_TAG_pointer_type: - // pointers can be either script longs, - // or dereferenced with their referent type - isptr = true; - return (dwarf_attr_integrate(&type_die, DW_AT_type, &type_attr) - && dwarf_formref_die(&type_attr, &type_die)); + // pointers can be treated as script longs, + // and if we know their type, they can also be dereferenced + if (dwarf_attr_integrate(&arg.type_die, DW_AT_type, &type_attr) + && dwarf_formref_die(&type_attr, &arg.type_die)) + arg.isptr = true; + arg.typecast = "(intptr_t)"; + return true; + case DW_TAG_structure_type: + case DW_TAG_union_type: + // for structs/unions which are passed by value, we turn it into + // a pointer that can be dereferenced. + arg.isptr = true; + arg.typecast = "(intptr_t)&"; + return true; default: // should we consider other types too? return false; @@ -9721,12 +9759,12 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) Dwarf_Attribute type_attr; if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) || !dwarf_formref_die (&type_attr, &tparg.type_die) - || !dwarf_type_name(tparg.type_die, tparg.c_type) - || !resolve_tracepoint_arg_type(tparg.type_die, tparg.isptr)) + || !dwarf_type_name(tparg.type_die, tparg.c_type)) throw semantic_error ("cannot get type of tracepoint '" + tracepoint_name + "' parameter '" + tparg.name + "'"); + tparg.usable = resolve_tracepoint_arg_type(tparg); args.push_back(tparg); if (sess.verbose > 4) clog << "found parameter for tracepoint '" << tracepoint_name @@ -9739,8 +9777,9 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) void tracepoint_derived_probe::printargs(std::ostream &o) const { - for (unsigned i = 0; i < args.size(); ++i) - o << " $" << args[i].name << ":" << args[i].c_type; + for (unsigned i = 0; i < args.size(); ++i) + if (args[i].usable) + o << " $" << args[i].name << ":" << args[i].c_type; } void @@ -9778,6 +9817,8 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) // don't provide any sort of context pointer. s.op->newline() << "#include <" << p->header << ">"; s.op->newline() << "static void enter_tracepoint_probe_" << i << "("; + if (p->args.size() == 0) + s.op->line() << "void"; for (unsigned j = 0; j < p->args.size(); ++j) { if (j > 0) @@ -9796,8 +9837,7 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) { s.op->newline() << "c->locals[0]." << p->name << ".__tracepoint_arg_" << p->args[j].name << " = (int64_t)"; - if (p->args[j].isptr) - s.op->line() << "(intptr_t)"; + s.op->line() << p->args[j].typecast; s.op->line() << "__tracepoint_arg_" << p->args[j].name << ";"; } s.op->newline() << p->name << " (c);"; @@ -10812,9 +10852,13 @@ register_standard_tapsets(systemtap_session & s) ->bind(new utrace_builder ()); // itrace user-space probes - s.pattern_root->bind_str(TOK_PROCESS)->bind("itrace") + s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_INSN) + ->bind(new itrace_builder ()); + s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_INSN) + ->bind(new itrace_builder ()); + s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_INSN)->bind(TOK_BLOCK) ->bind(new itrace_builder ()); - s.pattern_root->bind_num(TOK_PROCESS)->bind("itrace") + s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_INSN)->bind(TOK_BLOCK) ->bind(new itrace_builder ()); // marker-based parts diff --git a/testsuite/systemtap.base/itrace.exp b/testsuite/systemtap.base/itrace.exp index f19af977..e215bfe7 100644 --- a/testsuite/systemtap.base/itrace.exp +++ b/testsuite/systemtap.base/itrace.exp @@ -1,8 +1,5 @@ # itrace test -# temporarily disabled -return - # Initialize variables set utrace_support_found 0 @@ -11,7 +8,7 @@ set exepath "[pwd]/ls_[pid]" set itrace1_script { global instrs = 0 probe begin { printf("systemtap starting probe\n") } - probe process("%s").itrace + probe process("%s").insn { instrs += 1 if (instrs == 5) @@ -28,7 +25,7 @@ set itrace1_script_output "itraced = 5\r\n" set itrace2_script { global instrs = 0, itrace_on = 0, start_timer = 0 probe begin { start_timer = 1; printf("systemtap starting probe\n") } - probe process("%s").itrace if (itrace_on) + probe process("%s").insn if (itrace_on) { instrs += 1 if (instrs == 5) |