From 4176d5b1f4bf25adb8e44eaae9e6ab1de5a2c806 Mon Sep 17 00:00:00 2001 From: Eugeniy Meshcheryakov Date: Mon, 23 Feb 2009 14:53:24 +0100 Subject: Don't include unused libebl.h --- tapsets.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/tapsets.cxx b/tapsets.cxx index 78d5a5b3..959aa56b 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -41,7 +41,6 @@ extern "C" { #include #include #include -#include #include #include #include -- cgit From 0e4c80225fc77cfa5b830ddac3f60a28d47ce7bb Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Tue, 24 Feb 2009 21:36:32 -0500 Subject: Skip generating empty struct global Impact: trivial cleanup. Avoid emitting empty struct global code that is harmless. Signed-off-by: Wenji Huang --- translate.cxx | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/translate.cxx b/translate.cxx index 135830df..655937d7 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4954,21 +4954,23 @@ translate_pass (systemtap_session& s) s.op->newline() << s.embeds[i]->code << "\n"; } - s.op->newline() << "static struct {"; - s.op->indent(1); - for (unsigned i=0; iemit_global (s.globals[i]); - } - s.op->newline(-1) << "} global = {"; - s.op->newline(1); - for (unsigned i=0; iemit_global_init (s.globals[i]); - } - s.op->newline(-1) << "};"; - s.op->assert_0_indent(); + if (s.globals.size()>0) { + s.op->newline() << "static struct {"; + s.op->indent(1); + for (unsigned i=0; iemit_global (s.globals[i]); + } + s.op->newline(-1) << "} global = {"; + s.op->newline(1); + for (unsigned i=0; iemit_global_init (s.globals[i]); + } + s.op->newline(-1) << "};"; + s.op->assert_0_indent(); + } for (map::iterator it = s.functions.begin(); it != s.functions.end(); it++) { -- cgit From bec508deffdb39affbd6e93a7ce1d2c92d653a12 Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Wed, 25 Feb 2009 15:48:50 +0530 Subject: PR9896: Fix SystemTap build on Ubuntu Intrepid. The gcc on Ubuntu doesn't like fprintf() without format arguments --- tapsets.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 77e2efcc..b2419b62 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2297,9 +2297,9 @@ struct dwflpp assert(memstream); fprintf(memstream, "{\n"); - fprintf(memstream, prelude.c_str()); + fprintf(memstream, "%s", prelude.c_str()); bool deref = c_emit_location (memstream, head, 1); - fprintf(memstream, postlude.c_str()); + fprintf(memstream, "%s", postlude.c_str()); fprintf(memstream, " goto out;\n"); // dummy use of deref_fault label, to disable warning if deref() not used -- cgit From a8394af5f2db2bbb57414ffa4d4fc260e2aac3e9 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 25 Feb 2009 17:11:51 +0100 Subject: Guard _struct_sigaction32_u with ifdef CONFIG_COMPAT. * tapset/aux_syscalls.stp (_struct_sigaction_u): Only needed and compiles when CONFIG_COMPAT defined. --- tapset/aux_syscalls.stp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index 42b2abf8..d2e43903 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -1790,6 +1790,7 @@ function _struct_sigaction_u:string(uaddr:long) function _struct_sigaction32_u:string(uaddr:long) %{ /* pure */ +#ifdef CONFIG_COMPAT #include // There seems to be no public cross arch header that defines this. @@ -1831,4 +1832,5 @@ function _struct_sigaction32_u:string(uaddr:long) else strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN); } +#endif %} -- cgit From 2dc53f24ad2470750a04f869e9cbf5f167e9eb31 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 27 Feb 2009 13:31:25 +0100 Subject: Remove unnecessary embedded C include. * tapset/networking.stp: Remove include. --- tapset/networking.stp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tapset/networking.stp b/tapset/networking.stp index d6e90259..a147441a 100644 --- a/tapset/networking.stp +++ b/tapset/networking.stp @@ -6,10 +6,6 @@ // Public License (GPL); either version 2, or (at your option) any // later version. -%{ -#include -%} - /** * probe netdev.receive - Data recieved from network device. * @dev_name: The name of the device. e.g: eth0, ath1. -- cgit From 820e7ac7a68952d88cc8ff702f18e8c4b7eae822 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 27 Feb 2009 15:16:52 +0100 Subject: Use @cast where possible for examining inet_sock. * tapset/inet_sock.stp: Remove includes. (inet_get_local_port): No embedded C, use @cast. (inet_get_ip_source): Likewise. (daddr_to_string): New function, still some embedded C used. --- tapset/inet_sock.stp | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tapset/inet_sock.stp b/tapset/inet_sock.stp index 59ce7fea..f889ccd7 100644 --- a/tapset/inet_sock.stp +++ b/tapset/inet_sock.stp @@ -1,42 +1,42 @@ // inet_sock information tapset // Copyright (C) 2006 IBM Corp. // Copyright (C) 2006 Intel Corporation. +// 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 // Public License (GPL); either version 2, or (at your option) any // later version. -%{ -#include -#include -#include -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -#define LPORT (inet->inet.num) -#define DADDR (&inet->inet.daddr) -#else -#define LPORT (inet->num) -#define DADDR (&inet->daddr) -#endif -%} - -// Get local port number +// Get local port number given a pointer to a kernel socket, +// as for example kernel.function("tcp_accept").return will +// return. function inet_get_local_port:long(sock:long) -%{ /* pure */ - struct inet_sock *inet = (struct inet_sock *) (long) THIS->sock; - THIS->__retvalue = kread(&(LPORT)); - CATCH_DEREF_FAULT(); -%} +{ +%(kernel_v < "2.6.21" %? + port = @cast(sock, "inet_sock", "kernel")->inet->num; +%: + port = @cast(sock, "inet_sock", "kernel")->num; +%) + return port; +} -// Get IP source address string +// Get IP source address string given a pointer to a kernel socket. function inet_get_ip_source:string(sock:long) +{ +%(kernel_v < "2.6.21" %? + daddr = @cast(sock, "inet_sock", "kernel")->inet->daddr; +%: + daddr = @cast(sock, "inet_sock", "kernel")->daddr; +%) + return daddr_to_string(daddr); +} + +// Turns a daddr as found in an inet_sock into a dotted ip string. +function daddr_to_string:string(daddr:long) %{ /* pure */ - struct inet_sock *inet = (struct inet_sock *) (long) THIS->sock; union { __u32 d; unsigned char addr[4]; } u; - u.d = kread(DADDR); + u.d = THIS->daddr; sprintf(THIS->__retvalue, "%d.%d.%d.%d", u.addr[0], u.addr[1], u.addr[2], u.addr[3]); - CATCH_DEREF_FAULT(); %} -- cgit From 2a8f97d92bd86a464a8fc64b09ebb3a6ded772e9 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Mon, 2 Mar 2009 11:40:44 +1000 Subject: minor revision, added tag --- tapset/context-symbols.stp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tapset/context-symbols.stp b/tapset/context-symbols.stp index 79645f4f..46eab841 100644 --- a/tapset/context-symbols.stp +++ b/tapset/context-symbols.stp @@ -12,14 +12,14 @@ #define STP_NEED_SYMBOL_DATA 1 #endif %} - +// weirdness with print_stack, argument appears in build as undescribed /** * sfunction print_stack - Print out stack from string * @stk: String with list of hexidecimal addresses. (FIXME) * * Perform a symbolic lookup of the addresses in the given string, * which is assumed to be the result of a prior call to - * backtrace(). + * backtrace(). * Print one line per address, including the address, the * name of the function containing the address, and an estimate of * its position within that function. Return nothing. -- cgit From 684570b0277ce771fc66bcfdbe352eeaa541786d Mon Sep 17 00:00:00 2001 From: ddomingo Date: Mon, 2 Mar 2009 11:54:01 +1000 Subject: added publicanizer for langref --- doc/Language_Reference_Guide/README | 16 + .../en-US/Author_Group.xml | 16 + doc/Language_Reference_Guide/en-US/Book_Info.xml | 63 + .../en-US/Language_Reference_Guide.ent | 2 + doc/Language_Reference_Guide/en-US/Preface.xml | 13 + .../en-US/Revision_History.xml | 26 + doc/Language_Reference_Guide/en-US/images/icon.svg | 3936 ++++++++++++++++++++ .../publicanize-langref.sh | 157 + 8 files changed, 4229 insertions(+) create mode 100644 doc/Language_Reference_Guide/README create mode 100644 doc/Language_Reference_Guide/en-US/Author_Group.xml create mode 100644 doc/Language_Reference_Guide/en-US/Book_Info.xml create mode 100644 doc/Language_Reference_Guide/en-US/Language_Reference_Guide.ent create mode 100644 doc/Language_Reference_Guide/en-US/Preface.xml create mode 100644 doc/Language_Reference_Guide/en-US/Revision_History.xml create mode 100644 doc/Language_Reference_Guide/en-US/images/icon.svg create mode 100755 doc/Language_Reference_Guide/publicanize-langref.sh diff --git a/doc/Language_Reference_Guide/README b/doc/Language_Reference_Guide/README new file mode 100644 index 00000000..d3175ae3 --- /dev/null +++ b/doc/Language_Reference_Guide/README @@ -0,0 +1,16 @@ +This is an automated source build of the Language Reference Guide, +used to build it in Publican. + +To build the source, run: + + bash publicanize-langref.sh + +This will copy the LaTeX source of the Language Reference Guide and +convert it to DocBook XML. You can now build it in pdf, html, etc +using Publican. + +The main source of the Language Reference Guide is in: + ../langref.tex + +As such, any revisions to this document should be applied to ../langref.tex, +not to the source in this directory. diff --git a/doc/Language_Reference_Guide/en-US/Author_Group.xml b/doc/Language_Reference_Guide/en-US/Author_Group.xml new file mode 100644 index 00000000..00df1c7d --- /dev/null +++ b/doc/Language_Reference_Guide/en-US/Author_Group.xml @@ -0,0 +1,16 @@ + + + + + + + Robb + Romans + + IBM + Documentation + + robb@linux.vnet.ibm.com + + diff --git a/doc/Language_Reference_Guide/en-US/Book_Info.xml b/doc/Language_Reference_Guide/en-US/Book_Info.xml new file mode 100644 index 00000000..14a34093 --- /dev/null +++ b/doc/Language_Reference_Guide/en-US/Book_Info.xml @@ -0,0 +1,63 @@ + + + + + Language Reference Guide + A guide to the constructs and syntax used in SystemTap scripts + Fedora + 10 + 1 + 1 + + + The SystemTap Language Reference Guide is a + comprehensive reference of the language constructs and syntax used in + SystemTap scripts. It is suitable for users who have intermediate to + advanced knowledge of SystemTap. For other available SystemTap documentation, + refer to . + + + + + + + + Logo + + + + + + + Copyright © 2007 Red Hat Inc., Copyright © 2007 IBM Corp., Copyright © 2007 Intel Corporation. + + + + This document was derived from other documents contributed to the SystemTap project by employees of Red Hat, IBM and Intel. + + + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + + + The GNU Free Documentation License is available from + or by writing to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + + + + + + + + + diff --git a/doc/Language_Reference_Guide/en-US/Language_Reference_Guide.ent b/doc/Language_Reference_Guide/en-US/Language_Reference_Guide.ent new file mode 100644 index 00000000..e44f36cb --- /dev/null +++ b/doc/Language_Reference_Guide/en-US/Language_Reference_Guide.ent @@ -0,0 +1,2 @@ + + diff --git a/doc/Language_Reference_Guide/en-US/Preface.xml b/doc/Language_Reference_Guide/en-US/Preface.xml new file mode 100644 index 00000000..9e8995e3 --- /dev/null +++ b/doc/Language_Reference_Guide/en-US/Preface.xml @@ -0,0 +1,13 @@ + + + + + Preface + + + + + + + diff --git a/doc/Language_Reference_Guide/en-US/Revision_History.xml b/doc/Language_Reference_Guide/en-US/Revision_History.xml new file mode 100644 index 00000000..68432a02 --- /dev/null +++ b/doc/Language_Reference_Guide/en-US/Revision_History.xml @@ -0,0 +1,26 @@ + + + + + Revision History + + + + 1.0 + + + + + + + + + + + + + + + + diff --git a/doc/Language_Reference_Guide/en-US/images/icon.svg b/doc/Language_Reference_Guide/en-US/images/icon.svg new file mode 100644 index 00000000..c471a607 --- /dev/null +++ b/doc/Language_Reference_Guide/en-US/images/icon.svg @@ -0,0 +1,3936 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id="path2858" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/Language_Reference_Guide/publicanize-langref.sh b/doc/Language_Reference_Guide/publicanize-langref.sh new file mode 100755 index 00000000..fd4edf6a --- /dev/null +++ b/doc/Language_Reference_Guide/publicanize-langref.sh @@ -0,0 +1,157 @@ +#!/bin/bash +#this script converts the langref.tex source for the Language Reference Guide into +#DocBook XML. the conversion is done thru latexml, a utility that comes with dblatex-0.2.7. +#the output xml file of latexml is pretty dirty, so this script is needed to further clean it up. + +#copy latex file to here +cp ../langref.tex . + +#convert it to raw xml +latexml langref.tex --dest=Language_Reference_Guide.xml + +#remove excess whitespace +sed -i -e 's/^\s*//g' Language_Reference_Guide.xml + +sed -i -e 's///g' Language_Reference_Guide.xml + +cat Language_Reference_Guide.xml | +perl -p -e 'undef $/;s|\n<\?latexml options="twoside,english" class="article"\?>\n<\?latexml package="geometry"\?>\n<\?latexml RelaxNGSchema="LaTeXML"\?>\n<\?latexml RelaxNGSchema="LaTeXML"\?>\n\nSystemTap Language Reference|<\!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +]>\n\n|msg' | +perl -p -e 'undef $/;s|\n

This document was derived from other documents contributed to the SystemTap project by employees of Red Hat, IBM and Intel.

\n
\n\n

Copyright © 2007 Red Hat Inc.\nCopyright © 2007 IBM Corp.\nCopyright © 2007 Intel Corporation.

\n
\n\n

Permission is granted to copy, distribute and/or modify this document\nunder the terms of the GNU Free Documentation License, Version 1.2\nor any later version published by the Free Software Foundation;\nwith no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

\n
\n\n

The GNU Free Documentation License is available from\nhttp://www.gnu.org/licenses/fdl.html or by writing to\nthe Free Software Foundation, Inc., 51 Franklin Street,\nFifth Floor, Boston, MA 02110-1301, USA.

\n
||msg' | +#fix up screens +perl -p -e 'undef $/;s|\n\n||msg' | +perl -p -e 'undef $/;s|\n\n\n||msg' | +perl -p -e 'undef $/;s|\n\n||msg' | +perl -p -e 'undef $/;s|\n\n\n||msg' | +#fix up index tags +perl -p -e 'undef $/;s|\nIndex\n||msg' | +#needed later, for TABLES! +perl -p -e 'undef $/;s|\n||msg' > clean.xml + +#further fix up headers! +perl -p -i -e 's|<\?latexml searchpaths="[^>]*>\n||g' clean.xml + + +#change main tags +sed -i -e 's/<\/document>/<\/book>/g' clean.xml + +#more fixup for screen tags +perl -p -i -e 's|||g' clean.xml +perl -p -i -e 's|||g' clean.xml + +#clean section tags +sed -i -e 's/
/<\/chapter>/g' clean.xml + +#change subsection and subsubsection tags to section +sed -i -e 's//<\/section>/g' clean.xml +sed -i -e 's//<\/section>/g' clean.xml + +#remove with +sed -i -e 's///g' clean.xml +sed -i -e 's/<\/para>//g' clean.xml +sed -i -e 's/

//g' clean.xml +sed -i -e 's/<\/p>/<\/para>/g' clean.xml + +#properly convert xrefs +sed -i -e 's//indexterm>/g' clean.xml +perl -p -i -e 's///g' clean.xml +sed -i -e 's///g' clean.xml +sed -i -e 's/<\/indexphrase>/<\/primary>/g' clean.xml + +#convert s +sed -i -e 's/emph>/emphasis>/g' clean.xml + +#convert itemizedlists and listitems, dependent on successful exec of "fix up screens" perl routines +sed -i -e 's///g' clean.xml +sed -i -e 's///g' clean.xml +sed -i -e 's/<\/itemize>/<\/itemizedlist>/g' clean.xml +sed -i -e 's/<\/item>/<\/listitem>/g' clean.xml + +#convert orderedlists and their respective listitems +perl -p -i -e 's|||g' clean.xml +perl -p -i -e 's|||g' clean.xml +perl -p -i -e 's|||g' clean.xml + +#TRICKY: this perl expression takes all occurences of +# http://sourceware.org/systemtap/wiki/HomePage +# and replaces the string with "/>". from jfearn +# note: [^"]* means "any number of occurences of characters that are NOT quotes +# note: () groups strings/an expression together, which can be called later as $1 when replacing +perl -p -i -e 's|([^<]*|$1/>|g' clean.xml + +#now, convert s +sed -i -e 's/ accordingly; bold is , typewriter is +perl -p -i -e 's|([^<]*)|$1|g' clean.xml +sed -i -e 's///g' clean.xml +perl -p -i -e 's|([^<]*)|$1|g' clean.xml +sed -i -e 's///g' clean.xml + +#weird remainders, defaulting them to command +perl -p -i -e 's|([^<]*)|$1|g' clean.xml +sed -i -e 's///g' clean.xml +perl -p -i -e 's|([^<]*)|$1|g' clean.xml +sed -i -e 's///g' clean.xml + +#TABLES! +#the first expression is quite dirty, since it assumes that all tables have 3 columns. dunno yet how to +#automagicize this, since the orig XML doesn't have any attribute that specifies columns per table +sed -i -e 's///g' clean.xml +sed -i -e 's/tabular>/tgroup>/g' clean.xml +perl -p -i -e 's|)|
]*>||g' clean.xml +perl -p -i -e 's|]*>||g' clean.xml +perl -p -i -e 's|||g' clean.xml +perl -p -i -e 's|||g' clean.xml +perl -p -i -e 's|||g' clean.xml +perl -p -i -e 's|||g' clean.xml + +#remove "About this guide" section +#perl -p -i -e 'undef $/;s|
\nAbout this guide||msg' clean.xml + +#finalize: copy clean.xml to en-US, then deletes it +cp clean.xml en-US/Language_Reference_Guide.xml + +#delete excess files +rm langref.tex +rm clean.xml +rm Language_Reference_Guide.xml -- cgit From e85c70f82c134bf18ae845e3b1bfc15415591225 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Mon, 2 Mar 2009 21:38:26 -0500 Subject: Allow the same static user probe to be used multiple times per line. * dtrace (provider): Add STAP_PROBE10. * includes/sys/sdt.h: Likewise. Convert labels to __label__ --- dtrace | 9 +++++++++ includes/sys/sdt.h | 56 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/dtrace b/dtrace index d6d5ce21..7966e1f2 100755 --- a/dtrace +++ b/dtrace @@ -73,6 +73,15 @@ class provider: self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 5): self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6)\n' % (this_probe_canon, c+1, this_probe)) + elif (c == 6): + self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7)\n' % (this_probe_canon, c+1, this_probe)) + elif (c == 7): + self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)\n' % (this_probe_canon, c+1, this_probe)) + elif (c == 8): + self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)\n' % (this_probe_canon, c+1, this_probe)) + elif (c == 9): + self.h.write('// X %d %s\n' % (c+1,this_probe_canon)) + self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10)\n' % (this_probe_canon, c+1, this_probe)) self.h.write ('#define %s_ENABLED() 1\n' % this_probe_canon) def get(self, arg): diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index d68fed6c..ef0977ea 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -43,30 +43,33 @@ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section // The goto _probe_ prevents the label from "drifting" #define STAP_PROBE(provider,probe) \ - { \ -STAP_LABEL(probe,__LINE__): \ + {__label__ STAP_LABEL(probe,__LINE__); \ +STAP_LABEL(probe,__LINE__): \ asm volatile ("nop"); \ STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ STAP_LABEL_REF(probe) \ } #define STAP_PROBE1(provider,probe,parm1) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ -STAP_LABEL(probe,__LINE__): \ + {__label__ STAP_LABEL(probe,__LINE__); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ +STAP_LABEL(probe,__LINE__): \ asm volatile ("nop /* %0 */" :: "g"( arg1)); \ STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ STAP_LABEL_REF(probe);} #define STAP_PROBE2(provider,probe,parm1,parm2) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ STAP_LABEL(probe,__LINE__): \ asm volatile ("nop /* %0 %1 */" :: "g"(arg1), "g"(arg2)); \ STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ STAP_LABEL_REF(probe);} #define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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__): \ @@ -75,17 +78,19 @@ STAP_LABEL(probe,__LINE__): \ STAP_LABEL_REF(probe);} #define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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 /* %0 %1 %2 %3 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ STAP_LABEL_REF(probe);} #define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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; \ @@ -96,7 +101,8 @@ STAP_LABEL(probe,__LINE__): \ STAP_LABEL_REF(probe);} #define STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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; \ @@ -108,7 +114,8 @@ STAP_LABEL(probe,__LINE__): \ STAP_LABEL_REF(probe);} #define STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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; \ @@ -121,7 +128,8 @@ STAP_LABEL(probe,__LINE__): \ STAP_LABEL_REF(probe);} #define STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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; \ @@ -135,7 +143,8 @@ STAP_LABEL(probe,__LINE__): \ STAP_LABEL_REF(probe);} #define STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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; \ @@ -149,6 +158,23 @@ STAP_LABEL(probe,__LINE__): \ STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ STAP_LABEL_REF(probe);} +#define STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ + {__label__ STAP_LABEL(probe,__LINE__); \ + 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; \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ + 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((parm10)) arg10 __attribute__ ((unused)) = parm9; \ +STAP_LABEL(probe,__LINE__): \ + asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9), "X"(arg10)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ + STAP_LABEL_REF(probe);} + #define DTRACE_PROBE(provider,probe) \ STAP_PROBE(provider,probe) #define DTRACE_PROBE1(provider,probe,parm1) \ @@ -169,5 +195,5 @@ STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) #define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) - #endif /* sys/sdt.h */ + -- cgit From 34309209f7b8f957125f34c263dcea870ea76c8e Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Tue, 3 Mar 2009 02:58:37 -0500 Subject: PR9875: Remove sduprobes Impact: cleanup Since sdt.h is in git tree, sduprobes is no longer needed. * Makefile.am: Remove sduprobes. * Makefile.in: Regenerated. * doc/Makefile.in: Ditto. * runtime/sduprobes.c: Removed. Signed-off-by: Wenji Huang --- Makefile.am | 5 -- Makefile.in | 130 +++++++++++++--------------------------------------- doc/Makefile.in | 1 - runtime/sduprobes.c | 61 ------------------------ 4 files changed, 31 insertions(+), 166 deletions(-) delete mode 100644 runtime/sduprobes.c diff --git a/Makefile.am b/Makefile.am index 4c84309c..9681381d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -101,11 +101,6 @@ 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 000b6b89..73ef5bac 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,6 @@ - VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -90,26 +89,12 @@ 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 initscript/systemtap run-stap -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)" "$(DESTDIR)$(oldincludedir)" -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) @BUILD_SERVER_TRUE@am__EXEEXT_1 = stap-client-connect$(EXEEXT) \ @BUILD_SERVER_TRUE@ stap-server-connect$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \ + "$(DESTDIR)$(oldincludedir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) pkglibexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(pkglibexec_PROGRAMS) @@ -168,10 +153,9 @@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ -SOURCES = $(libsduprobes_a_SOURCES) $(loc2c_test_SOURCES) \ - $(stap_SOURCES) $(stap_client_connect_SOURCES) \ - $(stap_server_connect_SOURCES) $(stapio_SOURCES) \ - $(staprun_SOURCES) +SOURCES = $(loc2c_test_SOURCES) $(stap_SOURCES) \ + $(stap_client_connect_SOURCES) $(stap_server_connect_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 \ @@ -184,6 +168,12 @@ man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) +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|^.*/||'`; oldincludeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(oldinclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ @@ -298,7 +288,6 @@ 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@ @@ -343,8 +332,6 @@ stap_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ $(am__append_5) @BUILD_SERVER_TRUE@stap_client_connect_LDFLAGS = $(AM_LDFLAGS) @BUILD_SERVER_TRUE@stap_server_connect_LDFLAGS = $(AM_LDFLAGS) PHONIES = $(am__append_9) $(am__append_10) dist-gzip -@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 @@ -485,39 +472,6 @@ initscript/systemtap: $(top_builddir)/config.status $(top_srcdir)/initscript/sys cd $(top_builddir) && $(SHELL) ./config.status $@ run-stap: $(top_builddir)/config.status $(srcdir)/run-stap.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)" @@ -613,7 +567,6 @@ 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@ @@ -655,20 +608,6 @@ 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) $(loc2c_test_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 @@ -1360,11 +1299,11 @@ check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive -all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) \ - $(HEADERS) config.h all-local +all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) $(HEADERS) config.h \ + all-local installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(oldincludedir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(oldincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1396,8 +1335,7 @@ maintainer-clean-generic: clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-local \ - clean-noinstPROGRAMS clean-pkglibLIBRARIES \ - clean-pkglibexecPROGRAMS mostlyclean-am + clean-noinstPROGRAMS clean-pkglibexecPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -1422,8 +1360,7 @@ install-data-am: install-data-local install-man \ install-dvi: install-dvi-recursive install-exec-am: install-binPROGRAMS install-binSCRIPTS \ - install-exec-local install-pkglibLIBRARIES \ - install-pkglibexecPROGRAMS + install-exec-local install-pkglibexecPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook @@ -1460,7 +1397,7 @@ ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-local uninstall-man uninstall-oldincludeHEADERS \ - uninstall-pkglibLIBRARIES uninstall-pkglibexecPROGRAMS + uninstall-pkglibexecPROGRAMS uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 @@ -1470,27 +1407,24 @@ 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 check-local \ clean clean-binPROGRAMS clean-generic clean-local \ - clean-noinstPROGRAMS clean-pkglibLIBRARIES \ - clean-pkglibexecPROGRAMS ctags ctags-recursive distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-local distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-binPROGRAMS \ + clean-noinstPROGRAMS clean-pkglibexecPROGRAMS ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-hdr distclean-local 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-oldincludeHEADERS 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 \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am uninstall-binPROGRAMS \ - uninstall-binSCRIPTS uninstall-local uninstall-man \ - uninstall-man1 uninstall-man5 uninstall-man8 \ - uninstall-oldincludeHEADERS uninstall-pkglibLIBRARIES \ - uninstall-pkglibexecPROGRAMS + install-pkglibexecPROGRAMS install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-binSCRIPTS uninstall-local \ + uninstall-man uninstall-man1 uninstall-man5 uninstall-man8 \ + uninstall-oldincludeHEADERS uninstall-pkglibexecPROGRAMS git_version.stamp: @if test -f "$(srcdir)/git_version.h"; then \ @@ -1523,8 +1457,6 @@ 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/doc/Makefile.in b/doc/Makefile.in index e23a6699..93753666 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -163,7 +163,6 @@ 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/runtime/sduprobes.c b/runtime/sduprobes.c deleted file mode 100644 index 83bc8e72..00000000 --- a/runtime/sduprobes.c +++ /dev/null @@ -1,61 +0,0 @@ -// 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_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; -} -- cgit From 1324cc8267f44de856daa6aedd76d157e4259d28 Mon Sep 17 00:00:00 2001 From: Maynard Johnson Date: Tue, 3 Mar 2009 16:41:48 -0600 Subject: This patch updates the itrace code to support the new utrace interface. It also adds a private copy of access_process_vm to runtime/itrace.c since that function is not consistently exported by all distros. --- runtime/itrace.c | 146 ++++++++++++++++++++++++++++++++++++++++++++----------- tapsets.cxx | 1 + 2 files changed, 118 insertions(+), 29 deletions(-) diff --git a/runtime/itrace.c b/runtime/itrace.c index df18a400..ed32b0bc 100644 --- a/runtime/itrace.c +++ b/runtime/itrace.c @@ -1,6 +1,6 @@ /* * user space instruction tracing - * Copyright (C) 2005, 2006, 2007, 2008 IBM Corp. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 IBM Corp. * * 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 @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include "uprobes/uprobes.h" #ifndef put_task_struct @@ -65,10 +63,81 @@ static struct itrace_info *create_itrace_info( struct task_struct *tsk, u32 step_flag, struct stap_itrace_probe *itrace_probe); -static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine, +/* + * The kernel's access_process_vm is not exported in kernel.org kernels, although + * some distros export it on some architectures. To workaround this inconsistency, + * we copied and pasted it here. Fortunately, everything it calls is exported. + */ +#include +#include +static int __access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) +{ + struct mm_struct *mm; + struct vm_area_struct *vma; + struct page *page; + void *old_buf = buf; + + mm = get_task_mm(tsk); + if (!mm) + return 0; + + down_read(&mm->mmap_sem); + /* ignore errors, just check how much was sucessfully transfered */ + while (len) { + int bytes, ret, offset; + void *maddr; + + ret = get_user_pages(tsk, mm, addr, 1, + write, 1, &page, &vma); + if (ret <= 0) + break; + + bytes = len; + offset = addr & (PAGE_SIZE-1); + if (bytes > PAGE_SIZE-offset) + bytes = PAGE_SIZE-offset; + + maddr = kmap(page); + if (write) { + copy_to_user_page(vma, page, addr, + maddr + offset, buf, bytes); + set_page_dirty_lock(page); + } else { + copy_from_user_page(vma, page, addr, + buf, maddr + offset, bytes); + } + kunmap(page); + page_cache_release(page); + len -= bytes; + buf += bytes; + addr += bytes; + } + up_read(&mm->mmap_sem); + mmput(mm); + + return buf - old_buf; +} + +static u32 usr_itrace_report_quiesce(enum utrace_resume_action action, + struct utrace_attached_engine *engine, + struct task_struct *tsk, + unsigned long event) +{ + int status; + struct itrace_info *ui; + + ui = rcu_dereference(engine->data); + WARN_ON(!ui); + + return (event == 0 ? ui->step_flag : UTRACE_RESUME); +} + + +static u32 usr_itrace_report_signal(u32 action, + struct utrace_attached_engine *engine, struct task_struct *tsk, struct pt_regs *regs, - u32 action, siginfo_t *info, + siginfo_t *info, const struct k_sigaction *orig_ka, struct k_sigaction *return_ka) { @@ -83,12 +152,10 @@ static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine, WARN_ON(!ui); if (info->si_signo != SIGTRAP || !ui) - return UTRACE_ACTION_RESUME; - - /* normal case: continue stepping, hide this trap from other engines */ - return_flags = ui->step_flag | UTRACE_ACTION_HIDE | UTRACE_SIGNAL_IGN | - UTRACE_ACTION_NEWSTATE; + return UTRACE_RESUME; + /* normal case: continue stepping */ + return_flags = ui->step_flag | UTRACE_SIGNAL_IGN; #ifdef CONFIG_PPC if (ui->ppc_atomic_ss.step_over_atomic) { remove_atomic_ss_breakpoint(tsk, &ui->ppc_atomic_ss.end_bpt); @@ -99,8 +166,7 @@ static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine, } if (handle_ppc_atomic_seq(tsk, regs, &ui->ppc_atomic_ss)) - return_flags = UTRACE_ACTION_RESUME | UTRACE_ACTION_NEWSTATE | - UTRACE_SIGNAL_IGN; + return_flags = UTRACE_RESUME | UTRACE_SIGNAL_IGN; #endif enter_itrace_probe(ui->itrace_probe, regs, (void *)&data); @@ -108,24 +174,26 @@ static u32 usr_itrace_report_signal(struct utrace_attached_engine *engine, return return_flags; } -static u32 usr_itrace_report_clone(struct utrace_attached_engine *engine, +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) { - return UTRACE_ACTION_RESUME; + return UTRACE_RESUME; } static u32 usr_itrace_report_death(struct utrace_attached_engine *e, - struct task_struct *tsk) + struct task_struct *tsk, bool group_dead, int signal) { struct itrace_info *ui = rcu_dereference(e->data); WARN_ON(!ui); - return (UTRACE_ACTION_NEWSTATE | UTRACE_ACTION_DETACH); + return (UTRACE_DETACH); } static const struct utrace_engine_ops utrace_ops = { + .report_quiesce = usr_itrace_report_quiesce, .report_signal = usr_itrace_report_signal, .report_clone = usr_itrace_report_clone, .report_death = usr_itrace_report_death @@ -137,6 +205,7 @@ static struct itrace_info *create_itrace_info( struct stap_itrace_probe *itrace_probe) { struct itrace_info *ui; + int status; if (debug) printk(KERN_INFO "create_itrace_info: tid=%d\n", tsk->pid); @@ -154,20 +223,34 @@ static struct itrace_info *create_itrace_info( /* push ui onto usr_itrace_info */ spin_lock(&itrace_lock); list_add(&ui->link, &usr_itrace_info); + spin_unlock(&itrace_lock); /* attach a single stepping engine */ - ui->engine = utrace_attach(ui->tsk, UTRACE_ATTACH_CREATE, &utrace_ops, ui); + ui->engine = utrace_attach_task(ui->tsk, UTRACE_ATTACH_CREATE, &utrace_ops, ui); if (IS_ERR(ui->engine)) { printk(KERN_ERR "utrace_attach returns %ld\n", PTR_ERR(ui->engine)); - ui = NULL; - } else { - utrace_set_flags(tsk, ui->engine, ui->engine->flags | - ui->step_flag | - UTRACE_EVENT(CLONE) | UTRACE_EVENT_SIGNAL_ALL | - UTRACE_EVENT(DEATH)); + return NULL; } - spin_unlock(&itrace_lock); + status = utrace_set_events(tsk, ui->engine, ui->engine->flags | + UTRACE_EVENT(QUIESCE) | + UTRACE_EVENT(CLONE) | UTRACE_EVENT_SIGNAL_ALL | + UTRACE_EVENT(DEATH)); + if (status < 0) { + printk(KERN_ERR "utrace_attach returns %d\n", status); + return NULL; + } + + status = utrace_control(tsk, ui->engine, UTRACE_STOP); + if (status == 0) { + status = utrace_control(tsk, ui->engine, step_flag); + if (status < 0) { + printk(KERN_ERR "utrace_control(%d) returns %d\n", + step_flag, status); + return NULL; + } + } + return ui; } @@ -193,7 +276,7 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe struct task_struct *tsk; rcu_read_lock(); - tsk = find_task_by_pid(tid); + tsk = find_task_by_vpid(tid); if (!tsk) { printk(KERN_ERR "usr_itrace_init: Cannot find process %d\n", tid); rcu_read_unlock(); @@ -203,7 +286,7 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe get_task_struct(tsk); ui = create_itrace_info(tsk, (single_step ? - UTRACE_ACTION_SINGLESTEP : UTRACE_ACTION_BLOCKSTEP), p); + UTRACE_SINGLESTEP : UTRACE_BLOCKSTEP), p); if (!ui) return 1; @@ -223,6 +306,7 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe void static remove_usr_itrace_info(struct itrace_info *ui) { struct itrace_info *tmp; + int status; if (!ui) return; @@ -232,7 +316,11 @@ void static remove_usr_itrace_info(struct itrace_info *ui) spin_lock(&itrace_lock); if (ui->tsk && ui->engine) { - (void) utrace_detach(ui->tsk, ui->engine); + status = utrace_control(ui->tsk, ui->engine, UTRACE_DETACH); + if (status < 0 && status != -ESRCH && status != -EALREADY) + printk(KERN_ERR + "utrace_control(UTRACE_DETACH) returns %d\n", + status); } list_del(&ui->link); spin_unlock(&itrace_lock); @@ -292,7 +380,7 @@ static void insert_atomic_ss_breakpoint (struct task_struct *tsk, cur_instr = get_instr(bpt->addr, "insert_atomic_ss_breakpoint"); if (cur_instr != BPT_TRAP) { bpt->instr = cur_instr; - WARN_ON(access_process_vm(tsk, bpt->addr, &bp_instr, INSTR_SZ, 1) != + WARN_ON(__access_process_vm(tsk, bpt->addr, &bp_instr, INSTR_SZ, 1) != INSTR_SZ); } } @@ -300,7 +388,7 @@ static void insert_atomic_ss_breakpoint (struct task_struct *tsk, static void remove_atomic_ss_breakpoint (struct task_struct *tsk, struct bpt_info *bpt) { - WARN_ON(access_process_vm(tsk, bpt->addr, &bpt->instr, INSTR_SZ, 1) != + WARN_ON(__access_process_vm(tsk, bpt->addr, &bpt->instr, INSTR_SZ, 1) != INSTR_SZ); } diff --git a/tapsets.cxx b/tapsets.cxx index 74a22480..046ef0c0 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -6362,6 +6362,7 @@ itrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(); s.op->newline() << "/* ---- itrace probes ---- */"; + s.op->newline() << "#include \"task_finder.c\""; s.op->newline() << "struct stap_itrace_probe {"; s.op->indent(1); s.op->newline() << "struct stap_task_finder_target tgt;"; -- cgit From 9b753edaf92d9e73455ccea4334ab340616c8f93 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 3 Mar 2009 17:55:37 -0500 Subject: Search for a label instead of an address for .so static probes. * tapsets.cxx (dwflpp::build): Use .label for .so instead of .statement(N) --- tapsets.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tapsets.cxx b/tapsets.cxx index 046ef0c0..1c098425 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -5706,6 +5706,7 @@ dwarf_builder::build(systemtap_session & sess, size_t shstrndx; Elf_Scn *probe_scn = NULL; bool probe_found = false; + bool dynamic = (dwfl_module_relocations (dw->module) == 1); dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx)); GElf_Shdr *shdr = NULL; @@ -5723,8 +5724,10 @@ dwarf_builder::build(systemtap_session & sess, break; } } + if (dynamic || sess.listing_mode) + probe_type = dwarf_no_probes; - if (probe_type == probes_and_dwarf && ! sess.listing_mode) + 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); -- cgit From 46cfaf7b18b1d8dfa3e827f3b32d0e8f66e8399f Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 3 Mar 2009 20:48:20 -0500 Subject: change stap-report to a plain /bin/sh script; support dkpg in addition to rpm --- stap-report | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/stap-report b/stap-report index 8551dc74..944609cf 100755 --- a/stap-report +++ b/stap-report @@ -1,26 +1,21 @@ -#!/usr/bin/python +#! /bin/sh -import sys -import time -import subprocess +run(){ + echo "== $1 ==" + sh -c "$@" +} -ofile = sys.stdout - -def run(command): - ofile.write("== " + command + " ==\n") - ofile.flush() - p = subprocess.Popen(command, shell=True, stdout=ofile, stderr=ofile) - p.wait() - ofile.write("\n") - -if __name__ == "__main__": - run("stap -V") - run("which stap") - run("ls -ald `locate -r '/stap$'` `locate -r '/staprun$'`") - run("printenv | egrep '^PATH=|^LD_LIBRARY_PATH=|^SYSTEMTAP_.*='") - run("gcc -v") - run("uname -a") - run("dmesg | egrep 'stap|systemtap' | tail -n 10") - run("cat /proc/cpuinfo | egrep 'processor|vendor_id|model name'") - run(r"rpm -qa --qf %{name}-%{version}-%{release}.%{arch}\\n | egrep 'systemtap|elfutils|kernel|gcc' | sort") - run(r"egrep 'PROBE|TRACE|MARKER|_DEBUG_' /lib/modules/`uname -r`/build/.config | grep -v not.set | sort | fmt -w 80") +run "stap -V" +run "which stap" +run "locate --regex '/stap(run)?$' | xargs ls -ald" +run "printenv | egrep '^PATH=|^LD_LIBRARY_PATH=|^SYSTEMTAP_.*='" +run "gcc -v" +run "uname -a" +run "dmesg | egrep 'stap|systemtap' | tail -n 10" +run "cat /proc/cpuinfo | egrep 'processor|vendor_id|model name'" +if [ -x /usr/bin/dpkg ]; then + run "dpkg --list | egrep 'systemtap|elfutils|kernel|gcc' | awk '{print \$2,\$3}' | sort" +else + run "rpm -qa --qf '%{name}-%{version} %{release}.%{arch}\\n' | egrep 'systemtap|elfutils|kernel|gcc' | sort" +fi +run "egrep 'PROBE|TRACE|MARKER|_DEBUG_' /lib/modules/`uname -r`/build/.config | grep -v not.set | sort | fmt -w 80" -- cgit From cd1db1dd034141535648a66d9896db6c5e74dd9e Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 4 Mar 2009 11:55:56 +0100 Subject: PR9919: Set last_stmt for array (scalar or statistical) assignments. * translate.cxx (visit_arrayindex): Update last_stmt. --- testsuite/systemtap.base/overflow_error.exp | 32 +++++++++++++++++++++++++++++ testsuite/systemtap.base/overflow_error.stp | 22 ++++++++++++++++++++ translate.cxx | 4 ++-- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 testsuite/systemtap.base/overflow_error.exp create mode 100644 testsuite/systemtap.base/overflow_error.stp diff --git a/testsuite/systemtap.base/overflow_error.exp b/testsuite/systemtap.base/overflow_error.exp new file mode 100644 index 00000000..33be90a7 --- /dev/null +++ b/testsuite/systemtap.base/overflow_error.exp @@ -0,0 +1,32 @@ +# Test overflow errors point to the correct thing. + +set test "overflow_error" +if {![installtest_p]} { untested $test; return } + +set error_msg1 "ERROR: Array overflow, check size limit (3) near identifier 'overflow1' at $srcdir/$subdir/$test.stp" +set error_msg2 "ERROR: Array overflow, check size limit (5) near identifier 'overflow2' at $srcdir/$subdir/$test.stp" +set exit_warning "WARNING: Number of errors: 2, skipped probes: 0" + +set pass 0 + +spawn stap -DMAXERRORS=1 $srcdir/$subdir/$test.stp +expect { + $error_msg1 {incr pass; exp_continue} + $error_msg2 {incr pass; exp_continue} + $exit_warning {incr pass; exp_continue} + timeout { + exec kill -INT -[exp_pid] + fail "$test timed out" + } + eof {} +} +catch { close } +wait + +if {$pass == 3} { + pass $test +} else { + fail "$test ($pass)" +} + + diff --git a/testsuite/systemtap.base/overflow_error.stp b/testsuite/systemtap.base/overflow_error.stp new file mode 100644 index 00000000..f5a3e917 --- /dev/null +++ b/testsuite/systemtap.base/overflow_error.stp @@ -0,0 +1,22 @@ +# overflow some stuff to see if error message point to the correct thing. +global count; +global overflow1[3]; +global overflow2[5]; + +probe timer.ms(10) +{ + if (count <= 3) + { + overflow1[count++] = gettimeofday_ns(); + } + else + { + overflow2[count++] <<< gettimeofday_ns(); + } +} + +probe timer.s(3) +{ + exit(); +} + diff --git a/translate.cxx b/translate.cxx index 655937d7..23a24100 100644 --- a/translate.cxx +++ b/translate.cxx @@ -3882,7 +3882,7 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e) assert (rvalue->type == pe_long); mapvar mvar = parent->getmap (array->referent, e->tok); - // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; + o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; o->newline() << mvar.add (idx, rvar) << ";"; res = rvar; // no need for these dummy assignments @@ -3892,7 +3892,7 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e) else { mapvar mvar = parent->getmap (array->referent, e->tok); - // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; + o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; if (op != "=") // don't bother fetch slot if we will just overwrite it parent->c_assign (lvar, mvar.get(idx), e->tok); c_assignop (res, lvar, rvar, e->tok); -- cgit From 8c5905d0b6c8206c5ed971a637077aa8ef5c1b02 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 4 Mar 2009 11:56:45 +0100 Subject: stap autoconf test for kernel stack trace support * buildrun.cxx (compile_pass): Add autoconf line for stack trace test, which defines STAPCONF_KERNEL_STACKTRACE. * runtime/autoconf-save-stack-trace.c: New file. * runtime/stack.c : Use STAPCONF_KERNEL_STACKTRACE instead of tests for kernel configuration and versions. * runtime/stack-i386.c : ditto * runtime/stack-x86_64.c : ditto --- buildrun.cxx | 2 ++ runtime/autoconf-save-stack-trace.c | 22 ++++++++++++++++++++++ runtime/stack-i386.c | 2 +- runtime/stack-x86_64.c | 2 +- runtime/stack.c | 7 +++---- 5 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 runtime/autoconf-save-stack-trace.c diff --git a/buildrun.cxx b/buildrun.cxx index fe060236..973343cd 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -153,6 +153,8 @@ compile_pass (systemtap_session& s) * this autoconf. */ output_autoconf(s, o, "autoconf-probe-kernel.c", "STAPCONF_PROBE_KERNEL", NULL); #endif + output_autoconf(s, o, "autoconf-save-stack-trace.c", + "STAPCONF_KERNEL_STACKTRACE", NULL); o << module_cflags << " += -include $(STAPCONF_HEADER)" << endl; diff --git a/runtime/autoconf-save-stack-trace.c b/runtime/autoconf-save-stack-trace.c new file mode 100644 index 00000000..39ded684 --- /dev/null +++ b/runtime/autoconf-save-stack-trace.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +void foo(struct task_struct *foo) +{ + struct stack_trace trace; + unsigned long backtrace[20]; + memset(&trace, 0, sizeof(trace)); + trace.entries = &backtrace[0]; + trace.max_entries = 20; + trace.skip = 0; + save_stack_trace_tsk(tsk, &trace); +} + +static const struct stacktrace_ops print_stack_ops; + +void dumper(struct task_struct *foo) +{ + dump_trace(foo, 0, 0, 0, &print_stack_ops, 0); +} diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index 206801d8..5a18c9d8 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -14,7 +14,7 @@ static int _stp_valid_stack_ptr(unsigned long context, unsigned long p) } /* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ -#if ! (defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#if !defined(STAPCONF_KERNEL_STACKTRACE) static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) { unsigned long addr; diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c index 183de0a0..03d88ef0 100644 --- a/runtime/stack-x86_64.c +++ b/runtime/stack-x86_64.c @@ -10,7 +10,7 @@ /* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ -#if ! (defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#if !defined(STAPCONF_KERNEL_STACKTRACE) static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) { unsigned long addr; diff --git a/runtime/stack.c b/runtime/stack.c index aa0e6d65..f6b1cd08 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -27,8 +27,7 @@ #define MAXBACKTRACE 20 -#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) -// XXX: PR9866: hacky temporarily restriction to recent kernels +#if defined(STAPCONF_KERNEL_STACKTRACE) #include #include #endif @@ -51,7 +50,7 @@ static void _stp_stack_print_fallback(unsigned long, int, int); #error "Unsupported architecture" #endif -#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) +#if defined(STAPCONF_KERNEL_STACKTRACE) struct print_stack_data { @@ -161,7 +160,7 @@ static void _stp_ustack_print(char *str) void _stp_stack_print_tsk(struct task_struct *tsk, int verbose, int levels) { -#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) +#if defined(STAPCONF_KERNEL_STACKTRACE) int i; unsigned long backtrace[MAXBACKTRACE]; struct stack_trace trace; -- cgit From 47c4cca23401c4fd42c3d3477e83317277af3aff Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 4 Mar 2009 14:23:40 +0100 Subject: Fix typo in kernel version check 2.6.21 -> 2.6.11 in inet_sock. * tapset/inet_sock.stp (inet_get_local_port): Fix kernel version check. (inet_get_ip_source): Likewise. --- tapset/inet_sock.stp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tapset/inet_sock.stp b/tapset/inet_sock.stp index f889ccd7..33de9775 100644 --- a/tapset/inet_sock.stp +++ b/tapset/inet_sock.stp @@ -13,7 +13,7 @@ // return. function inet_get_local_port:long(sock:long) { -%(kernel_v < "2.6.21" %? +%(kernel_v < "2.6.11" %? port = @cast(sock, "inet_sock", "kernel")->inet->num; %: port = @cast(sock, "inet_sock", "kernel")->num; @@ -24,7 +24,7 @@ function inet_get_local_port:long(sock:long) // Get IP source address string given a pointer to a kernel socket. function inet_get_ip_source:string(sock:long) { -%(kernel_v < "2.6.21" %? +%(kernel_v < "2.6.11" %? daddr = @cast(sock, "inet_sock", "kernel")->inet->daddr; %: daddr = @cast(sock, "inet_sock", "kernel")->daddr; -- cgit From fea1d5c12c09560db8c3996411e73a5148e11ba2 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 09:30:34 +1000 Subject: added other required files --- doc/Language_Reference_Guide/Makefile | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 doc/Language_Reference_Guide/Makefile diff --git a/doc/Language_Reference_Guide/Makefile b/doc/Language_Reference_Guide/Makefile new file mode 100644 index 00000000..e8dfb206 --- /dev/null +++ b/doc/Language_Reference_Guide/Makefile @@ -0,0 +1,17 @@ +#Makefile for Language_Reference_Guide + +XML_LANG = en-US +DOCNAME = Language_Reference_Guide +PRODUCT = Fedora +BRAND = fedora + +CHUNK_SECTION_DEPTH=1 + +#OTHER_LANGS = as-IN bn-IN de-DE es-ES fr-FR gu-IN hi-IN it-IT ja-JP kn-IN ko-KR ml-IN mr-IN or-IN pa-IN pt-BR ru-RU si-LK ta-IN te-IN zh-CN zh-TW + +# Extra Parameters start here + +# Extra Parameters stop here +COMMON_CONFIG = /usr/share/publican +include $(COMMON_CONFIG)/make/Makefile.common + -- cgit From 501f43617a8d33f24e07a3ccbbf7636cd72cb5fe Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 10:53:35 +1000 Subject: function instead of (sfunction) --- doc/Tapset_Reference_Guide/publicanize.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Tapset_Reference_Guide/publicanize.sh b/doc/Tapset_Reference_Guide/publicanize.sh index 96c20a11..1139b34d 100755 --- a/doc/Tapset_Reference_Guide/publicanize.sh +++ b/doc/Tapset_Reference_Guide/publicanize.sh @@ -22,7 +22,7 @@ perl -p -e 'undef $/;s|\nYou should have received a copy of the GNU Genera perl -p -e 'undef $/;s|\nFor more details see the file COPYING in the source\ndistribution of Linux.\n\n\n||msg' | perl -p -e 'undef $/;s|||msg' | perl -p -e 'undef $/;s|\n\n\n\n\n\n\n\n\n\n\n\n\n\n||msg' | -perl -p -e 'undef $/;s|\n|\n(sfunction) <\/emphasis>|msg' | +perl -p -e 'undef $/;s|\n|\nfunction <\/emphasis>|msg' | perl -p -e 'undef $/;s|\n||msg' | perl -p -e 'undef $/;s|\n\n||msg' | perl -p -e 'undef $/;s|\n||msg' | -- cgit From f72226cf3584bf8dfe3e8d3021b7780b3bd9ec46 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 10:54:46 +1000 Subject: add Makefile --- doc/Tapset_Reference_Guide/Makefile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doc/Tapset_Reference_Guide/Makefile diff --git a/doc/Tapset_Reference_Guide/Makefile b/doc/Tapset_Reference_Guide/Makefile new file mode 100644 index 00000000..05220405 --- /dev/null +++ b/doc/Tapset_Reference_Guide/Makefile @@ -0,0 +1,15 @@ +#Makefile for Tapset_Reference_Guide + +XML_LANG = en-US +DOCNAME = Tapset_Reference_Guide +#PRODUCT = FIX_ME! +BRAND = RedHat + +#OTHER_LANGS = as-IN bn-IN de-DE es-ES fr-FR gu-IN hi-IN it-IT ja-JP kn-IN ko-KR ml-IN mr-IN or-IN pa-IN pt-BR ru-RU si-LK ta-IN te-IN zh-CN zh-TW + +# Extra Parameters start here + +# Extra Parameters stop here +COMMON_CONFIG = /usr/share/publican +include $(COMMON_CONFIG)/make/Makefile.common + -- cgit From 9c9118af3062f3dc1e53ba8426993a24bbedaa97 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 10:56:39 +1000 Subject: add images --- doc/Tapset_Reference_Guide/en-US/images/icon.svg | 3936 ++++++++++++++++++++++ 1 file changed, 3936 insertions(+) create mode 100644 doc/Tapset_Reference_Guide/en-US/images/icon.svg diff --git a/doc/Tapset_Reference_Guide/en-US/images/icon.svg b/doc/Tapset_Reference_Guide/en-US/images/icon.svg new file mode 100644 index 00000000..c471a607 --- /dev/null +++ b/doc/Tapset_Reference_Guide/en-US/images/icon.svg @@ -0,0 +1,3936 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id="path2858" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From ff2349408bbbfe83487335ed2d34346f70c15588 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 10:58:01 +1000 Subject: add other required XMLs --- doc/Tapset_Reference_Guide/en-US/Book_Info.xml | 32 ++++++++++++++++++++++ doc/Tapset_Reference_Guide/en-US/Legal_Notice.xml | 30 ++++++++++++++++++++ doc/Tapset_Reference_Guide/en-US/Preface.xml | 15 ++++++++++ .../en-US/Tapset_Reference_Guide.ent | 5 ++++ 4 files changed, 82 insertions(+) create mode 100644 doc/Tapset_Reference_Guide/en-US/Book_Info.xml create mode 100644 doc/Tapset_Reference_Guide/en-US/Legal_Notice.xml create mode 100644 doc/Tapset_Reference_Guide/en-US/Preface.xml create mode 100644 doc/Tapset_Reference_Guide/en-US/Tapset_Reference_Guide.ent diff --git a/doc/Tapset_Reference_Guide/en-US/Book_Info.xml b/doc/Tapset_Reference_Guide/en-US/Book_Info.xml new file mode 100644 index 00000000..fc3d4273 --- /dev/null +++ b/doc/Tapset_Reference_Guide/en-US/Book_Info.xml @@ -0,0 +1,32 @@ + + + + + Tapset Reference Guide + For SystemTap in &RHEL;.3 + Red Hat Enterprise Linux + 5.2 + 1.0 + 0 + + The Tapset Reference Guide describes the most common tapset definitions users can apply to SystemTap scripts. All included tapsets documented in this guide are current as of &RHEL;.3. + + + + + + + Logo + + + + &YEAR; + &HOLDER; + + + + + + + diff --git a/doc/Tapset_Reference_Guide/en-US/Legal_Notice.xml b/doc/Tapset_Reference_Guide/en-US/Legal_Notice.xml new file mode 100644 index 00000000..1fcb7b99 --- /dev/null +++ b/doc/Tapset_Reference_Guide/en-US/Legal_Notice.xml @@ -0,0 +1,30 @@ + + + + + + This documentation is free software; you can redistribute + it and/or modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + + + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + + For more details see the file COPYING in the source + distribution of Linux. + + diff --git a/doc/Tapset_Reference_Guide/en-US/Preface.xml b/doc/Tapset_Reference_Guide/en-US/Preface.xml new file mode 100644 index 00000000..6acf0c3e --- /dev/null +++ b/doc/Tapset_Reference_Guide/en-US/Preface.xml @@ -0,0 +1,15 @@ + + + + + Preface + + + + + + + + + diff --git a/doc/Tapset_Reference_Guide/en-US/Tapset_Reference_Guide.ent b/doc/Tapset_Reference_Guide/en-US/Tapset_Reference_Guide.ent new file mode 100644 index 00000000..6638d812 --- /dev/null +++ b/doc/Tapset_Reference_Guide/en-US/Tapset_Reference_Guide.ent @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file -- cgit From a06948f6631daaeb1cf3f63d9ecd20795deebc21 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 11:22:27 +1000 Subject: change to fedora --- doc/Tapset_Reference_Guide/en-US/Book_Info.xml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/Tapset_Reference_Guide/en-US/Book_Info.xml b/doc/Tapset_Reference_Guide/en-US/Book_Info.xml index fc3d4273..ddf0f205 100644 --- a/doc/Tapset_Reference_Guide/en-US/Book_Info.xml +++ b/doc/Tapset_Reference_Guide/en-US/Book_Info.xml @@ -4,13 +4,17 @@ Tapset Reference Guide - For SystemTap in &RHEL;.3 - Red Hat Enterprise Linux - 5.2 + For SystemTap in Fedora 10 + Fedora + 10 1.0 0 - The Tapset Reference Guide describes the most common tapset definitions users can apply to SystemTap scripts. All included tapsets documented in this guide are current as of &RHEL;.3. + + The Tapset Reference Guide describes the most common tapset definitions + users can apply to SystemTap scripts. All included tapsets documented in this guide are current + as of Fedora 10 and the latest upstream version of SystemTap. + -- cgit From 345f6a4daad184385b7ee1dc3797f57a3be01452 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 11:23:00 +1000 Subject: change to fedora, add README for more info --- doc/Tapset_Reference_Guide/Makefile | 2 +- doc/Tapset_Reference_Guide/README | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 doc/Tapset_Reference_Guide/README diff --git a/doc/Tapset_Reference_Guide/Makefile b/doc/Tapset_Reference_Guide/Makefile index 05220405..87a1fb5f 100644 --- a/doc/Tapset_Reference_Guide/Makefile +++ b/doc/Tapset_Reference_Guide/Makefile @@ -3,7 +3,7 @@ XML_LANG = en-US DOCNAME = Tapset_Reference_Guide #PRODUCT = FIX_ME! -BRAND = RedHat +BRAND = fedora #OTHER_LANGS = as-IN bn-IN de-DE es-ES fr-FR gu-IN hi-IN it-IT ja-JP kn-IN ko-KR ml-IN mr-IN or-IN pa-IN pt-BR ru-RU si-LK ta-IN te-IN zh-CN zh-TW diff --git a/doc/Tapset_Reference_Guide/README b/doc/Tapset_Reference_Guide/README new file mode 100644 index 00000000..1f27abe7 --- /dev/null +++ b/doc/Tapset_Reference_Guide/README @@ -0,0 +1,35 @@ +This is an automated source build of the SystemTap_Tapset_Reference Guide, +used to build it in Publican. + +To build the DocBook XML source (required by Publican), run: + + bash publicanize.sh + +This will copy and clean the XML source of SystemTap_Tapset_Reference +created by kernel-doc. You can now build it in pdf, html, etc using +Publican. + +The main source of the Language Reference Guide is: + + ../SystemTap_Tapset_Reference/tapsets.xml + +This main source is generated by kernel-doc when you run 'make' in the +main git tree. The tapset documentation inside is collected from all +tapset files defined in the following template file: + + ../SystemTap_Tapset_Reference/tapsets.tmpl + +The tapset file definitions appear in tapsets.tmpl as: + + !Itapset/context.stp + !Itapset/context-symbols.stp + etc + +context.stp, context-symbols, and all the other tapset files are located in: + + ../../tapset + +All tapset documentation should be done inside their respective tapset files. +For more information about this project, refer to: + + http://sourceware.org/systemtap/wiki/ProjectTapsetReferenceGuide \ No newline at end of file -- cgit From fa0cada28f7a64ecd001d1f229ce1fe3453cb03b Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 13:26:46 +1000 Subject: added invisible marker for publican --- doc/SystemTap_Tapset_Reference/tapsets.tmpl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl index d6b3b309..8e459d9d 100644 --- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl +++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl @@ -98,7 +98,7 @@ the kernel. This is common among asynchronous events such as timers, exit functions, and print functions. - + Process Tapset -- cgit From 70a9a66e609c4068b368bfb3a6ae36d3ca9f14b1 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 15:20:24 +1000 Subject: removes marked range of strings (intro) and replaces with Intro and Tapset Dev Guide --- doc/Tapset_Reference_Guide/publicanize.sh | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/doc/Tapset_Reference_Guide/publicanize.sh b/doc/Tapset_Reference_Guide/publicanize.sh index 1139b34d..d4da6e02 100755 --- a/doc/Tapset_Reference_Guide/publicanize.sh +++ b/doc/Tapset_Reference_Guide/publicanize.sh @@ -1,10 +1,15 @@ #!/bin/bash #copy the automated tapsets.xml -cp ../SystemTap_Tapset_Reference/tapsets.xml en-US/Tapset_Reference_Guide.xml ; +cp ../SystemTap_Tapset_Reference/tapsets.xml temp.xml ; #remove all excess whitespace -sed -i -e 's/^\s*//g' en-US/Tapset_Reference_Guide.xml ; +sed -i -e 's/^\s*//g' temp.xml ; + +#remove marked Intro (starthere to endhere), then copy it to en-US +sed '/starthere/,/endhere/d' temp.xml > Tapset_Reference_Guide.xml +cp Tapset_Reference_Guide.xml en-US/Tapset_Reference_Guide.xml; +rm Tapset_Reference_Guide.xml #re-convert programlisting tags sed -i -e 's/<programlisting>//g' en-US/Tapset_Reference_Guide.xml; @@ -22,15 +27,24 @@ perl -p -e 'undef $/;s|\nYou should have received a copy of the GNU Genera perl -p -e 'undef $/;s|\nFor more details see the file COPYING in the source\ndistribution of Linux.\n\n\n||msg' | perl -p -e 'undef $/;s|||msg' | perl -p -e 'undef $/;s|\n\n\n\n\n\n\n\n\n\n\n\n\n\n||msg' | +perl -p -e 'undef $/;s|\n\n\n\n\n\n\n\n\n\n\n||msg' | perl -p -e 'undef $/;s|\n|\nfunction <\/emphasis>|msg' | perl -p -e 'undef $/;s|\n||msg' | perl -p -e 'undef $/;s|\n\n||msg' | perl -p -e 'undef $/;s|\n||msg' | perl -p -e 'undef $/;s|\n||msg' > clean.xml +#replace Intro with my own +perl -p -i -e 's||\n|g' clean.xml + +#for tapset name format section +#perl -p -i -e 'undef $/;s|\nname:return \(parameters\)\ndefinition\n|\nfunction/probe tapset_name:return \(parameters\)\n|msg' clean.xml +#perl -p -i -e 's|In this guide, tapset definitions appear in the following format:|In this guide, the synopsis of each tapset appears in the following format:|g' clean.xml +#perl -p -i -e 's||\n|g' clean.xml + cp clean.xml en-US/Tapset_Reference_Guide.xml rm clean.xml - + # statements change synopsis tags, as they are still currently unfixed in publican-redhat sed -i -e 's/refsynopsisdiv>/refsect1>/g' en-US/Tapset_Reference_Guide.xml; sed -i -e 's/refsect1>/refsection>/g' en-US/Tapset_Reference_Guide.xml; @@ -45,4 +59,7 @@ sed -i -e 's/<remark>//g' en-US/Tapset_Reference_Guide.xml; sed -i -e 's/<\/remark>/<\/remark>/g' en-US/Tapset_Reference_Guide.xml; sed -i -e 's/<command>//g' en-US/Tapset_Reference_Guide.xml; -sed -i -e 's/<\/command>/<\/command>/g' en-US/Tapset_Reference_Guide.xml; \ No newline at end of file +sed -i -e 's/<\/command>/<\/command>/g' en-US/Tapset_Reference_Guide.xml; + +#useful marker script; moves content between starthere and endhere to file target +#sed -n '/starthere/,/endhere/ s/.*/&/w target' Tapset_Reference_Guide.xml \ No newline at end of file -- cgit From dd22832afe6c337eb020001834266ad1e7678b2c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 18:32:54 -0800 Subject: Make session.module_cache init more consistently We used to check & init module_cache in a few inconsistent places. Now it is always handled in dwflpp::setup_user/setup_kernel. * tapsets.cxx (dwflpp::setup_user): add module_cache check (dwarf_builder::build): remove module_cache check (dwarf_cast_expanding_visitor::visit_cast_op): ditto --- tapsets.cxx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 1c098425..7a321dce 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -958,6 +958,9 @@ struct dwflpp void setup_user(string module_name, bool debuginfo_needed = true) { + if (! sess.module_cache) + sess.module_cache = new module_cache (); + static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build"; static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); // NB: kernel_build_tree doesn't enter into this, as it's for @@ -4993,9 +4996,6 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) if (e->module.empty()) e->module = "kernel"; // "*" may also be reasonable to search all kernel modules - if (! s.module_cache) - s.module_cache = new module_cache (); - string code; exp_type type = pe_long; try @@ -5655,10 +5655,6 @@ dwarf_builder::build(systemtap_session & sess, dwflpp* dw = 0; - if (! sess.module_cache) - sess.module_cache = new module_cache (); - - string module_name; if (has_null_param (parameters, TOK_KERNEL) || get_param (parameters, TOK_MODULE, module_name)) -- cgit From c08b296b08208a4406d80e12da6aac34df64bd8f Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 15:21:10 +1000 Subject: new intro, tapset dev guide --- doc/Tapset_Reference_Guide/en-US/Introduction.xml | 59 ++++++++++++++++++++++ .../en-US/Tapset_Dev_Guide.xml | 33 ++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 doc/Tapset_Reference_Guide/en-US/Introduction.xml create mode 100644 doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml diff --git a/doc/Tapset_Reference_Guide/en-US/Introduction.xml b/doc/Tapset_Reference_Guide/en-US/Introduction.xml new file mode 100644 index 00000000..633521e1 --- /dev/null +++ b/doc/Tapset_Reference_Guide/en-US/Introduction.xml @@ -0,0 +1,59 @@ + + + + + Introduction + + + SystemTap provides free software (GPL) infrastructure to simplify the + gathering of information about the running Linux system. This assists + diagnosis of a performance or functional problem. SystemTap eliminates the + need for the developer to go through the tedious and disruptive instrument, + recompile, install, and reboot sequence that may be otherwise required to + collect data. + + + + SystemTap provides a simple command line interface and scripting language + for writing instrumentation for a live, running kernel. This instrumentation + uses probe points and functions provided in the tapset library. + + + + Simply put, tapsets are scripts that encapsulate knowledge about a kernel subsystem + into pre-written probes and functions that can be used by other scripts. + Tapsets are analogous to libraries for C programs. They hide the + underlying details of a kernel area while exposing the key information + needed to manage and monitor that aspect of the kernel. They are typically + developed by kernel subject-matter experts. + + + + A tapset exposes the high-level data and state transitions of a + subsystem. For the most part, good tapset developers assume that + SystemTap users know little to nothing about the kernel subsystem's + low-level details. As such, tapset developers write tapsets that help + ordinary SystemTap users write meaningful and useful SystemTap scripts. + + + + +
+ Documentation Goals + + + This guide aims to document SystemTap's most useful and common tapset entries; it + also contains guidelines on proper tapset development and documentation. + The tapset definitions contained in this guide are extracted automatically from + properly-formatted comments in the code of each tapset file. As such, any revisions + to the definitions in this guide should be applied directly to their respective + tapset file. + + +add: "while users can read from code, it's easier to read from here!" +add: target audience, expected proficiency of readers + +
+ +
\ No newline at end of file diff --git a/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml b/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml new file mode 100644 index 00000000..be59d944 --- /dev/null +++ b/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml @@ -0,0 +1,33 @@ + + + + + Tapset Development Guidelines + + + This chapter describes the upstream guidelines on proper tapset documentation. It also contains + information on how to properly document your tapsets, to ensure that they are properly + defined in this guide. + + +
+ Writing Good Tapsets + + + The first step to writing good tapsets is to create a simple model of your subject area. For + example, a model of the process subsystem might include the following: + +info from here:http://sources.redhat.com/git/?p=systemtap.git;a=blob_plain;f=tapset/DEVGUIDE + +
+ +
+ Section 2 Test + + Test of a section + +
+ +
+ -- cgit From 5cb254a339f3b09fc79e1aacff073c45389efc1d Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 5 Mar 2009 15:21:29 +1000 Subject: added markers, for publicanization purposes --- doc/SystemTap_Tapset_Reference/tapsets.tmpl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl index 8e459d9d..798cfb3b 100644 --- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl +++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl @@ -51,9 +51,9 @@
- + - + Introduction @@ -98,7 +98,6 @@ the kernel. This is common among asynchronous events such as timers, exit functions, and print functions. - + + Context Functions -- cgit From 4a05792180ad1299f499b5dbd77d5d4e9c4970fb Mon Sep 17 00:00:00 2001 From: ddomingo Date: Fri, 6 Mar 2009 14:57:12 +1000 Subject: added more content for tapset dev --- .../en-US/Tapset_Dev_Guide.xml | 88 +++++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml b/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml index be59d944..26ea9896 100644 --- a/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml +++ b/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml @@ -18,16 +18,100 @@ The first step to writing good tapsets is to create a simple model of your subject area. For example, a model of the process subsystem might include the following: + + + Key Data + + + process ID + parent process ID + process group ID + + + + + + State Transitions + + + forked + exec'd + running + stopped + terminated + + + + + + Note + Both lists are examples, and are not meant to represent a complete list. + + + + Use your subsystem expertise to find probe points (function entries and + exits) that expose the elements of the model, then define probe aliases + for those points. Be aware that some state transitions can occur in more + than one place. In those cases, an alias can place a probe in multiple + locations. + + + + For example, process execs can occur in either the do_execve() or the + compat_do_execve() functions. The following alias inserts probes at the + beginning of those functions: + + + +probe process.exec = kernel.function("do_execve"), +kernel.function("compat_do_execve") +{probe body} + + + + Try to place probes on stable interfaces (i.e., functions + that are unlikely to change at the interface level) whenever possible. This will + make the tapset less likely to break due to kernel changes. Where + kernel version or architecture dependencies are unavoidable, use + preprocessor conditionals (see the stap(1) man page for details). + + + + + Fill in the probe bodies with the key data available at the probe points. + Function entry probes can access the entry parameters specified to + the function, while exit probes can access the entry parameters and the + return value. Convert the data into meaningful forms where appropriate + (e.g., bytes to kilobytes, state values to strings, etc). + + + + You may need to use auxiliary functions to access or convert some of the data. Auxiliary + functions often use embedded C to do things that cannot be done in the + SystemTap language, like access structure fields in some contexts, follow + linked lists, etc. You can use auxiliary functions defined in other tapsets + or write your own. + + + + In the following example, copy_process() returns a + pointer to the task_struct for the new process. Note + that the process ID of the new process is retrieved by calling + task_pid() and passing it the task_struct + pointer. In this case, the auxiliary function is an embedded C function + that's defined in the task tapset (task.stp). + + info from here:http://sources.redhat.com/git/?p=systemtap.git;a=blob_plain;f=tapset/DEVGUIDE
- + -- cgit From fb3b52a7346202fea1905ed680a3256d372a7b03 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Fri, 6 Mar 2009 00:16:50 -0500 Subject: PR9871: use @cast in tapset Rewrite some functions using type casting to get rid of embedded C code in nfs, scsi, signal, socket, rpc, task and vfs tapset. Signed-off-by: Wenji Huang --- tapset/nfs.stp | 165 ++++++++++++++++++++----------------------- tapset/rpc.stp | 94 +++++++++++------------- tapset/scsi.stp | 10 ++- tapset/signal.stp | 18 +++-- tapset/socket.stp | 68 ++++++++---------- tapset/task.stp | 54 ++++++-------- tapset/vfs.stp | 208 +++++++++++++++++++++++------------------------------- 7 files changed, 269 insertions(+), 348 deletions(-) diff --git a/tapset/nfs.stp b/tapset/nfs.stp index 474b091f..fe25eff2 100644 --- a/tapset/nfs.stp +++ b/tapset/nfs.stp @@ -135,69 +135,55 @@ function __nfs_wpages:long(inode:long) %{ /* pure */ %} /*Get struct inode from struct page*/ -function __p2i :long(page:long) %{ /* pure */ - struct page *page = (struct page *)((long)THIS->page); - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - - if (mapping == NULL) - THIS->__retvalue = 0; +function __p2i :long(page:long) +{ + mapping = page? @cast(page, "page", "kernel")->mapping : 0 + if (mapping == 0) + return 0 else - THIS->__retvalue = (long)kread(&(mapping->host)); - CATCH_DEREF_FAULT(); -%} + return @cast(mapping, "address_space", "kernel")->host +} /*Get i_flags from struct page*/ -function __p2i_flag : long (page:long) %{ /* pure */ - struct page *page = (struct page *)((long)THIS->page); - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - struct inode *host = mapping? kread(&(mapping->host)) : NULL; - - if (host == NULL) - THIS->__retvalue = -1; +function __p2i_flag : long (page:long) +{ + host = __p2i(page) + if (host == 0) + return -1 else - THIS->__retvalue = kread(&(host->i_flags)); - CATCH_DEREF_FAULT(); -%} + return @cast(host, "inode", "kernel")->i_flags +} /*Get i_state from struct page*/ -function __p2i_state :long (page:long) %{ /* pure */ - struct page *page = (struct page *)((long)THIS->page); - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - struct inode *host = mapping? kread(&(mapping->host)) : NULL; - - if (host == NULL) - THIS->__retvalue = -1; +function __p2i_state :long (page:long) +{ + host = __p2i(page) + if (host == 0) + return -1 else - THIS->__retvalue = kread(&(host->i_state)); - CATCH_DEREF_FAULT(); -%} + return @cast(host, "inode", "kernel")->i_state +} /*Get i_size from struct page*/ -function __p2i_size :long (page:long) %{ /* pure */ - struct page *page = (struct page *)((long)THIS->page); - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - struct inode *host = mapping? kread(&(mapping->host)) : NULL; - - if (host == NULL) - THIS->__retvalue = -1; +function __p2i_size :long (page:long) +{ + host = __p2i(page) + if (host == 0) + return -1 else - THIS->__retvalue = kread(&(host->i_size)); - CATCH_DEREF_FAULT(); -%} + return @cast(host, "inode", "kernel")->i_size +} /*Get s_flags from struct page*/ -function __p2sb_flag:long (page:long) %{ /* pure */ - struct page *page = (struct page *)((long)THIS->page); - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - struct inode *host = mapping? kread(&(mapping->host)) : NULL; - struct super_block *i_sb = host? kread(&(host->i_sb)) : NULL; - - if (i_sb == NULL) - THIS->__retvalue = -1; +function __p2sb_flag:long (page:long) +{ + host = __p2i(page) + i_sb = host? @cast(host, "inode", "kernel")->i_sb : 0 + if (i_sb == 0) + return -1 else - THIS->__retvalue = kread(&(i_sb->s_flags)); - CATCH_DEREF_FAULT(); -%} + return @cast(i_sb, "super_block", "kernel")->s_flags +} function __d_loff_t :long (ppos :long) %{ /* pure */ loff_t * ppos = (loff_t *) ((long)THIS->ppos); @@ -209,53 +195,54 @@ function __d_loff_t :long (ppos :long) %{ /* pure */ CATCH_DEREF_FAULT(); %} -function __file_inode:long (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - if (dentry == NULL) - THIS->__retvalue = 0; +function __file_inode:long (file:long) +{ +%( kernel_v >= "2.6.20" %? + dentry = file? @cast(file, "file", "kernel")->f_path->dentry : 0 +%: + dentry = file? @cast(file, "file", "kernel")->f_dentry : 0 +%) + if (dentry == 0) + return 0 else - THIS->__retvalue = (long)kread(&(dentry->d_inode)); - CATCH_DEREF_FAULT(); -%} + return @cast(dentry, "dentry", "kernel")->d_inode +} -function __file_id:long (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - if (dentry == NULL) - THIS->__retvalue = 0; +function __file_id:long (file:long) +{ + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 else { - struct inode *d_inode = kread(&(dentry->d_inode)); - struct super_block *i_sb = kread(&(d_inode->i_sb)); - THIS->__retvalue = (long)&(i_sb->s_id); + i_sb = @cast(d_inode, "inode", "kernel")->i_sb + return @cast(i_sb, "super_block", "kernel")->s_id } - CATCH_DEREF_FAULT(); -%} +} -function __file_mode:long (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - if (dentry == NULL) - THIS->__retvalue = 0; - else { - struct inode *d_inode = kread(&(dentry->d_inode)); - THIS->__retvalue = kread(&(d_inode->i_mode)); - } - CATCH_DEREF_FAULT(); -%} +function __file_mode:long (file:long) +{ + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + else + return @cast(d_inode, "inode", "kernel")->i_mode +} -function __file_parentname:string (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - struct dentry *d_parent = dentry? kread(&(dentry->d_parent)) : NULL; - if (d_parent == NULL) - strlcpy(THIS->__retvalue, "NULL", MAXSTRINGLEN); +function __file_parentname:string (file:long) +{ +%( kernel_v >= "2.6.20" %? + dentry = file? @cast(file, "file", "kernel")->f_path->dentry : 0 +%: + dentry = file? @cast(file, "file", "kernel")->f_dentry : 0 +%) + d_parent = dentry? @cast(dentry, "dentry", "kernel")->d_parent : 0 + if (d_parent == 0) + return "NULL" else { - const unsigned char *name = kread(&(d_parent->d_name.name)); - deref_string(THIS->__retvalue, name, MAXSTRINGLEN); + name = @cast(d_parent, "dentry", "kernel")->d_name->name + return kernel_string(name) } - CATCH_DEREF_FAULT(); -%} +} /* * Combination of generic_segment_checks and iov_length functions diff --git a/tapset/rpc.stp b/tapset/rpc.stp index f97117b5..e6eaed46 100644 --- a/tapset/rpc.stp +++ b/tapset/rpc.stp @@ -877,60 +877,52 @@ probe sunrpc.sched.delay.return = kernel.function("rpc_delay").return !, *****************************************************************/ function xid_from_clnt:long(clnt:long) -%{ /* pure */ - struct rpc_clnt *clnt = (struct rpc_clnt *)(long)THIS->clnt; - if (clnt == NULL) - THIS->__retvalue = 0; +{ + if (clnt == 0) + return 0 else { - struct rpc_xprt *cl_xprt = kread(&(clnt->cl_xprt)); - THIS->__retvalue = kread(&(cl_xprt->xid)); + cl_xprt = @cast(clnt, "rpc_clnt", "kernel")->cl_xprt + return @cast(cl_xprt, "rpc_xprt", "kernel")->xid } - CATCH_DEREF_FAULT(); -%} +} function prog_from_clnt:long(clnt:long) -%{ /* pure */ - struct rpc_clnt *clnt = (struct rpc_clnt *)(long)THIS->clnt; - if (clnt == NULL) - THIS->__retvalue = 0; +{ + if (clnt == 0) + return 0 else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) - THIS->__retvalue = kread(&(clnt->cl_prog)); -#else - struct rpc_portmap *cl_pmap = kread(&(clnt->cl_pmap)); - THIS->__retvalue = kread(&(cl_pmap->pm_prog)); -#endif +%(kernel_v >= "2.6.19" %? + return @cast(clnt, "rpc_clnt", "kernel")->cl_prog +%: + cl_pmap = @cast(clnt, "rpc_clnt", "kernel")->cl_pmap + return @cast(cl_pmap, "rpc_portmap", "kernel")->pm_prog +%) } - CATCH_DEREF_FAULT(); -%} +} function vers_from_clnt:long(clnt:long) -%{ /* pure */ - struct rpc_clnt *clnt = (struct rpc_clnt *)(long)THIS->clnt; - if (clnt == NULL) - THIS->__retvalue = 0; - else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) - THIS->__retvalue = kread(&(clnt->cl_vers)); -#else - struct rpc_portmap *cl_pmap = kread(&(clnt->cl_pmap)); - THIS->__retvalue = kread(&(cl_pmap->pm_vers)); -#endif - } - CATCH_DEREF_FAULT(); -%} +{ + if (clnt == 0) + return 0 + else { +%(kernel_v >= "2.6.19" %? + return @cast(clnt, "rpc_clnt", "kernel")->cl_vers +%: + cl_pmap = @cast(clnt, "rpc_clnt", "kernel")->cl_pmap + return @cast(cl_pmap, "rpc_portmap", "kernel")->pm_vers +%) + } +} function prot_from_clnt:long(clnt:long) -%{ /* pure */ - struct rpc_clnt *clnt = (struct rpc_clnt *)(long)THIS->clnt; - if (clnt == NULL) - THIS->__retvalue = 0; - else { - struct rpc_xprt *cl_xprt = kread(&(clnt->cl_xprt)); - THIS->__retvalue = kread(&(cl_xprt->prot)); - } - CATCH_DEREF_FAULT(); -%} +{ + if (clnt == 0) + return 0 + else { + cl_xprt = @cast(clnt, "rpc_clnt", "kernel")->cl_xprt + return @cast(cl_xprt, "rpc_xprt", "kernel")->prot + } +} function port_from_clnt:long(clnt:long) %{ /* pure */ @@ -975,16 +967,14 @@ function tasks_from_clnt:long(clnt:long) %} function proc_from_msg:long(msg:long) -%{ /* pure */ - struct rpc_message *msg = (struct rpc_message *)(long)THIS->msg; - if (msg == NULL) - THIS->__retvalue = 0; +{ + if (msg == 0) + return 0 else { - struct rpc_procinfo *rpc_proc = kread(&(msg->rpc_proc)); - THIS->__retvalue = kread(&(rpc_proc->p_proc)); + rpc_proc = @cast(msg, "rpc_message", "kernel")->rpc_proc + return @cast(rpc_proc, "rpc_procinfo", "kernel")->p_proc } - CATCH_DEREF_FAULT(); -%} +} function vers_from_prog:long(program:long, vers:long) %{ /* pure */ diff --git a/tapset/scsi.stp b/tapset/scsi.stp index 76b9a114..b1b2d19b 100644 --- a/tapset/scsi.stp +++ b/tapset/scsi.stp @@ -136,9 +136,7 @@ function scsi_timer_pending:long(var:long) %} function get_devstate_from_req:long(var:long) -%{ /* pure */ - struct request_queue *q = (struct request_queue *)((long)THIS->var); - struct scsi_device *sdev = (struct scsi_device *)kread(&(q->queuedata)); - THIS->__retvalue = kread(&(sdev->sdev_state)); - CATCH_DEREF_FAULT(); -%} +{ + sdev = @cast(var, "request_queue", "kernel")->queuedata + return @cast(sdev, "scsi_device", "kernel")->sdev_state +} diff --git a/tapset/signal.stp b/tapset/signal.stp index f40958e6..8fb6fe57 100644 --- a/tapset/signal.stp +++ b/tapset/signal.stp @@ -608,17 +608,15 @@ probe signal.flush = kernel.function("flush_signals") pid_name = kernel_string($t->comm) } -function get_sa_flags:long (act:long) %{ /* pure */ - struct k_sigaction *act = (struct k_sigaction *)((long)THIS->act); - THIS->__retvalue = kread(&act->sa.sa_flags); - CATCH_DEREF_FAULT(); -%} +function get_sa_flags:long (act:long) +{ + return @cast(act, "k_sigaction", "kernel")->sa->sa_flags +} -function get_sa_handler:long (act:long) %{ /* pure */ - struct k_sigaction *act = (struct k_sigaction *)((long)THIS->act); - THIS->__retvalue = (long)kread(&act->sa.sa_handler); - CATCH_DEREF_FAULT(); -%} +function get_sa_handler:long (act:long) +{ + return @cast(act, "k_sigaction", "kernel")->sa->sa_handler +} // sa_mask contains the set of signals to be blocked when executing the // signal handler. This function returns a string, delimited by ",". diff --git a/tapset/socket.stp b/tapset/socket.stp index 842dbfc4..3271d4f7 100644 --- a/tapset/socket.stp +++ b/tapset/socket.stp @@ -922,53 +922,43 @@ function _get_sock_size:long (iov:long, nr_segs:long) %} function _sock_prot_num:long (sock:long) -%{ /* pure */ - struct socket *sktp = (struct socket *)(long)(THIS->sock); - struct sock *skp = sktp? kread(&(sktp->sk)) : NULL; - if (skp == NULL) - THIS->__retvalue = -1; +{ + skp = sock? @cast(sock, "socket", "kernel")->sk : 0 + if (skp == 0) + return -1 else - THIS->__retvalue = kread(&(skp->sk_protocol)); - CATCH_DEREF_FAULT(); -%} + return @cast(skp, "sock", "kernel")->sk_protocol +} function _sock_fam_num:long (sock:long) -%{ /* pure */ - struct socket *sockp = (struct socket *)(long)(THIS->sock); - const struct proto_ops *ops = sockp? kread(&(sockp->ops)) : NULL; - if (ops == NULL) - THIS->__retvalue = -1; +{ + ops = sock? @cast(sock, "socket", "kernel")->ops : 0 + if (ops == 0) + return -1 else - THIS->__retvalue = kread(&(ops->family)); - CATCH_DEREF_FAULT(); -%} + return @cast(ops, "proto_ops", "kernel")->family +} function _sock_state_num:long (sock:long) -%{ /* pure */ - struct socket *sockp = (struct socket *)(long)(THIS->sock); - if (sockp == NULL) - THIS->__retvalue = -1; +{ + if (sock == 0) + return -1 else - THIS->__retvalue = kread(&(sockp->state)); - CATCH_DEREF_FAULT(); -%} + return @cast(sock, "socket", "kernel")->state +} function _sock_type_num:long (sock:long) -%{ /* pure */ - struct socket *sockp = (struct socket *)(long)(THIS->sock); - if (sockp == NULL) - THIS->__retvalue = -1; - else - THIS->__retvalue = kread(&(sockp->type)); - CATCH_DEREF_FAULT(); -%} +{ + if (sock == 0) + return -1 + else + return @cast(sock, "socket", "kernel")->type +} function _sock_flags_num:long (sock:long) -%{ /* pure */ - struct socket *sockp = (struct socket *)(long)(THIS->sock); - if (sockp == NULL) - THIS->__retvalue = -1; - else - THIS->__retvalue = kread(&(sockp->flags)); - CATCH_DEREF_FAULT(); -%} +{ + if (sock == 0) + return -1 + else + return @cast(sock, "socket", "kernel")->flags +} diff --git a/tapset/task.stp b/tapset/task.stp index 684cef93..07337156 100644 --- a/tapset/task.stp +++ b/tapset/task.stp @@ -43,35 +43,31 @@ function task_parent:long (task:long) %{ /* pure */ // TASK_TRACED 8 // EXIT_ZOMBIE 16 // EXIT_DEAD 32 -function task_state:long (task:long) %{ /* pure */ - struct task_struct *t = (struct task_struct *)(long)THIS->task; - THIS->__retvalue = kread(&(t->state)); - CATCH_DEREF_FAULT(); -%} +function task_state:long (task:long) +{ + return @cast(task, "task_struct", "kernel")->state +} // Return the name of the given task -function task_execname:string (task:long) %{ /* pure */ - struct task_struct *t = (struct task_struct *)(long)THIS->task; - deref_string(THIS->__retvalue, t->comm, MAXSTRINGLEN); - CATCH_DEREF_FAULT(); -%} +function task_execname:string (task:long) +{ + return kernel_string(@cast(task, "task_struct", "kernel")->comm) +} // Return the process id of the given task -function task_pid:long (task:long) %{ /* pure */ - struct task_struct *t = (struct task_struct *)(long)THIS->task; - THIS->__retvalue = kread(&(t->tgid)); - CATCH_DEREF_FAULT(); -%} +function task_pid:long (task:long) +{ + return @cast(task, "task_struct", "kernel")->tgid +} // Return the thread id of the given task -function task_tid:long (task:long) %{ /* pure */ - struct task_struct *t = (struct task_struct *)(long)THIS->task; - THIS->__retvalue = kread(&(t->pid)); - CATCH_DEREF_FAULT(); -%} +function task_tid:long (task:long) +{ + return @cast(task, "task_struct", "kernel")->pid +} // Return the group id of the given task @@ -156,22 +152,14 @@ function task_nice:long (task:long) %{ /* pure */ // Return the scheduled cpu for the given task function task_cpu:long (task:long) +{ %( kernel_v >= "2.6.22" %? -%{ /* pure */ - struct task_struct *t = (struct task_struct *)(long)THIS->task; - struct thread_info *ti = kread(&(t->stack)); - THIS->__retvalue = kread(&(ti->cpu)); - CATCH_DEREF_FAULT(); -%} + ti = @cast(task, "task_struct", "kernel")->stack %: -%{ /* pure */ - struct task_struct *t = (struct task_struct *)(long)THIS->task; - struct thread_info *ti = kread(&(t->thread_info)); - THIS->__retvalue = kread(&(ti->cpu)); - CATCH_DEREF_FAULT(); -%} + ti = @cast(task, "task_struct", "kernel")->thread_info %) - + return @cast(ti, "thread_info", "kernel")->cpu +} // Return the number of open file handlers for the given task function task_open_file_handles:long (task:long) diff --git a/tapset/vfs.stp b/tapset/vfs.stp index 43603177..3bb9292d 100644 --- a/tapset/vfs.stp +++ b/tapset/vfs.stp @@ -51,136 +51,106 @@ function ppos_pos:long (ppos:long) %{ /* pure */ CATCH_DEREF_FAULT(); %} -function __page_ino:long (page:long) %{ /* pure */ - struct page *page = (struct page *)(long)THIS->page; - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - if (mapping == NULL) { - THIS->__retvalue = -1; - } else { - struct inode *host = kread(&(mapping->host)); - THIS->__retvalue = kread(&(host->i_ino)); - } - CATCH_DEREF_FAULT(); -%} - -function __address_inode:long (page:long) %{ /* pure */ - struct page *page = (struct page *)(long)THIS->page; - struct address_space *mapping = kread(&(page->mapping)); - if (mapping == NULL) { - THIS->__retvalue = -1; - } else { - THIS->__retvalue = (long)kread(&(mapping->host)); - } - CATCH_DEREF_FAULT(); -%} +function __address_inode:long (page:long) +{ + mapping = page? @cast(page, "page", "kernel")->mapping : 0 + if (mapping == 0) + return -1 + else + return @cast(mapping, "address_space", "kernel")->host +} -function __page_dev:long (page:long) %{ /* pure */ - struct page *page = (struct page *)(long)THIS->page; - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - if (mapping == NULL) { - THIS->__retvalue = -1; - } else { - struct inode *host = kread(&(mapping->host)); - struct super_block *i_sb = kread(&(host->i_sb)); - THIS->__retvalue = kread(&(i_sb->s_dev)); - } - CATCH_DEREF_FAULT(); -%} +function __page_ino:long (page:long) +{ + host = __address_inode(page) + if (host == -1) + return -1 + else + return @cast(host, "inode", "kernel")->i_ino +} -function __page_bdev:long (page:long) %{ /* pure */ - struct page *page = (struct page *)(long)THIS->page; - struct address_space *mapping = page? kread(&(page->mapping)) : NULL; - if (mapping == NULL) { - THIS->__retvalue = 0; - } else { - struct inode *host = kread(&(mapping->host)); - struct super_block *i_sb = kread(&(host->i_sb)); - THIS->__retvalue = (long)kread(&(i_sb->s_bdev)); +function __page_dev:long (page:long) +{ + host = __address_inode(page) + if (host == -1) + return -1 + else { + i_sb = @cast(host, "inode", "kernel")->i_sb + return @cast(i_sb, "super_block", "kernel")->s_dev } - CATCH_DEREF_FAULT(); -%} +} -function __page_index:long (page:long) %{ /* pure */ - struct page *page = (struct page *)(long)THIS->page; - THIS->__retvalue = (long)kread(&(page->index)); - CATCH_DEREF_FAULT(); -%} +function __page_bdev:long (page:long) +{ + host = __address_inode(page) + if (host == -1) + return 0 + else { + i_sb = @cast(host, "inode", "kernel")->i_sb + return @cast(i_sb, "super_block", "kernel")->s_bdev + } +} -function __file_dev:long (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - if (dentry == NULL) { - THIS->__retvalue = 0; - } else { - struct inode *d_inode = kread(&(dentry->d_inode)); - struct super_block *i_sb = kread(&(d_inode->i_sb)); - THIS->__retvalue = kread(&(i_sb->s_dev)); - } - CATCH_DEREF_FAULT(); -%} +function __page_index:long (page:long) +{ + return @cast(page, "page", "kernel")->index +} -function __file_bdev:long (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - if (dentry == NULL) { - THIS->__retvalue = 0; - } else { - struct inode *d_inode = kread(&(dentry->d_inode)); - struct super_block *i_sb = kread(&(d_inode->i_sb)); - THIS->__retvalue = (long)kread(&(i_sb->s_bdev)); +function __file_dev:long (file:long) +{ + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + else { + i_sb = @cast(d_inode, "inode", "kernel")->i_sb + return @cast(i_sb, "super_block", "kernel")->s_dev } - CATCH_DEREF_FAULT(); -%} +} -function __file_ino:long (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - if (dentry == NULL) { - THIS->__retvalue = 0; - } else { - struct inode *d_inode = kread(&(dentry->d_inode)); - THIS->__retvalue = kread(&(d_inode->i_ino)); - } - CATCH_DEREF_FAULT(); -%} +function __file_bdev:long (file:long) +{ + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + else { + i_sb = @cast(d_inode, "inode", "kernel")->i_sb + return @cast(i_sb, "super_block", "kernel")->s_bdev + } +} -function __file_maxbytes:long (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - if (dentry == NULL) { - THIS->__retvalue = 0; - } else { - struct inode *d_inode = kread(&(dentry->d_inode)); - struct super_block *i_sb = kread(&(d_inode->i_sb)); - THIS->__retvalue = kread(&(i_sb->s_maxbytes)); - } - CATCH_DEREF_FAULT(); -%} +function __file_ino:long (file:long) +{ + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + else + return @cast(d_inode, "inode", "kernel")->i_ino +} -function __file_filename:string (file:long) %{ /* pure */ - struct file *file = (struct file *)(long)THIS->file; - struct dentry *dentry = file? kread(&(file->f_dentry)) : NULL; - const unsigned char *name = dentry? kread(&(dentry->d_name.name)) : NULL; - if (name == NULL) { - strlcpy(THIS->__retvalue, "NULL", MAXSTRINGLEN); - } else { - deref_string(THIS->__retvalue, name, MAXSTRINGLEN); - } - CATCH_DEREF_FAULT(); -%} +function __file_maxbytes:long (file:long) +{ + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + else { + i_sb = @cast(d_inode, "inode", "kernel")->i_sb + return @cast(i_sb, "super_block", "kernel")->s_maxbytes + } +} -function __inode_num:long(file:long) -%{ - struct file *file = NULL; - struct dentry *dentry = NULL; - struct inode *inode = NULL; - - file = (struct file *)(long)THIS->file; - dentry = file? kread(&(file->f_dentry)) : NULL; - inode = dentry? kread(&(dentry->d_inode)) : NULL; - THIS->__retvalue = inode? (long)(kread(&(inode->i_ino))) : 0; - CATCH_DEREF_FAULT(); -%} +function __file_filename:string (file:long) +{ +%( kernel_v >= "2.6.20" %? + dentry = file? @cast(file, "file", "kernel")->f_path->dentry : 0 +%: + dentry = file? @cast(file, "file", "kernel")->f_dentry : 0 +%) + name = dentry? @cast(dentry, "dentry", "kernel")->d_name->name : 0 + if (name == 0) + return "NULL" + else + return kernel_string(name) +} function _get_fopv_size:long (iov:long, nr_segs:long) %{ -- cgit From c03f0c3d60d7ba465fe94ba60c26656f32287685 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Fri, 6 Mar 2009 07:37:56 -0500 Subject: Create unique named labels. * includes/sys/sdt.h (STAP_PROBEN_): New macros that take advantage of __COUNTER__ --- includes/sys/sdt.h | 159 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 65 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index ef0977ea..1d41d878 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -33,88 +33,94 @@ static char probe ## _ ## probe_name [strlen(#probe)+1] \ = #probe; \ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc}; -#define STAP_LABEL_REF(probe) \ +// The goto _probe_ prevents the label from "drifting" +#define STAP_LABEL_REF(probe, label) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__); + goto label; +// These baroque macros are used to create a unique label #define STAP_CONCAT(a,b) a ## b -#define STAP_LABEL(p,n) \ - STAP_CONCAT(_stapprobe1_ ## p ## _, n) +#define STAP_LABEL_PREFIX(p) _stapprobe1_ ## p +// __COUNTER__ is not present in gcc 4.1 +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 3 +#define STAP_COUNTER STAP_CONCAT(__,COUNTER__) +#else +#define STAP_COUNTER STAP_CONCAT(__,LINE__) +#endif +#define STAP_LABEL(a,b) STAP_CONCAT(a,b) -// The goto _probe_ prevents the label from "drifting" -#define STAP_PROBE(provider,probe) \ - {__label__ STAP_LABEL(probe,__LINE__); \ -STAP_LABEL(probe,__LINE__): \ +#define STAP_PROBE_(probe,label) \ +do { \ +label: \ asm volatile ("nop"); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe) \ -} + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE1(provider,probe,parm1) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE1_(probe,label,parm1) \ +do { \ volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop /* %0 */" :: "g"( arg1)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} +label: \ + asm volatile ("nop /* %0 */" :: "X"( arg1)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE2(provider,probe,parm1,parm2) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE2_(probe,label,parm1,parm2) \ +do { \ volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop /* %0 %1 */" :: "g"(arg1), "g"(arg2)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} +label: \ + asm volatile ("nop /* %0 %1 */" :: "X"(arg1), "X"(arg2)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ +do { \ 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 /* %0 %1 %2 */" :: "g"(arg1), "g"(arg2), "g"(arg3)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} +label: \ + asm volatile ("nop /* %0 %1 %2 */" :: "X"(arg1), "X"(arg2), "X"(arg3)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ +do { \ 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 /* %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);} +label: \ + asm volatile ("nop /* %0 %1 %2 %3 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4)); \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ +do { \ 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; \ volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ -STAP_LABEL(probe,__LINE__): \ +label: \ asm volatile ("nop /* %0 %1 %2 %3 %4 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \ +do { \ 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; \ volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ -STAP_LABEL(probe,__LINE__): \ +label: \ asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ +do { \ volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -122,13 +128,13 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ -STAP_LABEL(probe,__LINE__): \ +label: \ asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ +do { \ volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -137,13 +143,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; \ -STAP_LABEL(probe,__LINE__): \ +label: \ asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ +do { \ volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -153,13 +159,13 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ volatile typeof((parm8)) arg8 __attribute__ ((unused)) = parm8; \ volatile typeof((parm9)) arg9 __attribute__ ((unused)) = parm9; \ -STAP_LABEL(probe,__LINE__): \ +label: \ asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ - {__label__ STAP_LABEL(probe,__LINE__); \ +#define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ +do { \ volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -170,10 +176,33 @@ STAP_LABEL(probe,__LINE__): \ volatile typeof((parm8)) arg8 __attribute__ ((unused)) = parm8; \ volatile typeof((parm9)) arg9 __attribute__ ((unused)) = parm9; \ volatile typeof((parm10)) arg10 __attribute__ ((unused)) = parm9; \ -STAP_LABEL(probe,__LINE__): \ +label: \ asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9), "X"(arg10)); \ - STAP_PROBE_STRUCT(probe,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - STAP_LABEL_REF(probe);} + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ + STAP_LABEL_REF(probe,label);} while (0) + +#define STAP_PROBE(provider,probe,...) \ + STAP_PROBE_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE1(provider,probe,...) \ + STAP_PROBE1_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE2(provider,probe,...) \ + STAP_PROBE2_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE3(provider,probe,...) \ + STAP_PROBE3_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE4(provider,probe,...) \ + STAP_PROBE4_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE5(provider,probe,...) \ + STAP_PROBE5_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE6(provider,probe,...) \ + STAP_PROBE6_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE7(provider,probe,...) \ + STAP_PROBE7_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE8(provider,probe,...) \ + STAP_PROBE8_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE9(provider,probe,...) \ + STAP_PROBE9_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE10(provider,probe,...) \ + STAP_PROBE10_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) #define DTRACE_PROBE(provider,probe) \ STAP_PROBE(provider,probe) -- cgit From 63df184c9510561887771420a47cdc9c04b876f1 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 6 Mar 2009 19:21:44 +0100 Subject: STAP_PROBE takes no extra arguments. * includes/sys/sdt.h (STAP_PROBE): Don't add __VA_ARGS__. --- includes/sys/sdt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index 1d41d878..4ebf4fe0 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -181,8 +181,8 @@ label: \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ STAP_LABEL_REF(probe,label);} while (0) -#define STAP_PROBE(provider,probe,...) \ - STAP_PROBE_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE(provider,probe) \ + STAP_PROBE_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER)) #define STAP_PROBE1(provider,probe,...) \ STAP_PROBE1_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) #define STAP_PROBE2(provider,probe,...) \ -- cgit From 730aaa7ac9847816d4dbb3ebef039add3b5a82a7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 6 Mar 2009 16:27:21 -0800 Subject: Update AUTHORS --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index 7afdd53e..6a20ef72 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,6 +2,7 @@ Ananth N Mavinakayanahalli Anil Keshavamurthy Anithra Janakiraman Charles Spirakis +Dan Horak Dave Brolley Dave Nomura David Smith @@ -24,6 +25,7 @@ Mark McLoughlin Mark Wielaard Martin Hunt Masami Hiramatsu +Maynard Johnson Michael Meeks Mike Mason Nobuhiro Tachino -- cgit From 2da9cedbf2a1916107fe829692af5113646a894d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 18:51:28 -0800 Subject: Make iterate_over_functions work with base_querys * tapsets.cxx (dwflpp::iterate_over_functions): Change arg from void* to base_query*, and add explicit function-search parameters. (query_cu): update caller (query_dwarf_func): update callback signature (Note: instead of passing around callback functions, it might be nicer to use a virtual method in base_query...) --- tapsets.cxx | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 7a321dce..834aa06a 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1193,8 +1193,9 @@ struct dwflpp return DWARF_CB_OK; } - int iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg), - void * data); + int iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q), + base_query * q, const string& function, + bool has_statement_num=false); int iterate_over_globals (int (* callback)(Dwarf_Die *, void *), void * data); @@ -2937,13 +2938,13 @@ dwflpp::iterate_over_globals (int (* callback)(Dwarf_Die *, void *), } int -dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg), - void * data) +dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q), + base_query * q, const string& function, + bool has_statement_num) { int rc = DWARF_CB_OK; assert (module); assert (cu); - dwarf_query * q = static_cast(data); string key = module_name + ":" + cu_name; cu_function_cache_t *v = cu_function_cache[key]; @@ -2956,13 +2957,13 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg), clog << "function cache " << key << " size " << v->size() << endl; } - string subkey = q->function; + string subkey = function; if (v->find(subkey) != v->end()) { Dwarf_Die die = v->find(subkey)->second; if (q->sess.verbose > 4) clog << "function cache " << key << " hit " << subkey << endl; - return (*callback)(& die, data); + return (*callback)(& die, q); } else if (name_has_wildcard (subkey)) { @@ -2976,17 +2977,17 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg), if (q->sess.verbose > 4) clog << "function cache " << key << " match " << func_name << " vs " << subkey << endl; - rc = (*callback)(& die, data); + rc = (*callback)(& die, q); if (rc != DWARF_CB_OK) break; } } } - else if (q->has_statement_num) // searching all for kernel.statement + else if (has_statement_num) // searching all for kernel.statement { for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++) { Dwarf_Die die = it->second; - rc = (*callback)(& die, data); + rc = (*callback)(& die, q); if (rc != DWARF_CB_OK) break; } } @@ -3876,9 +3877,9 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg) } static int -query_dwarf_func (Dwarf_Die * func, void * arg) +query_dwarf_func (Dwarf_Die * func, base_query * bq) { - dwarf_query * q = static_cast(arg); + dwarf_query * q = static_cast(bq); try { @@ -3892,7 +3893,7 @@ query_dwarf_func (Dwarf_Die * func, void * arg) if (q->sess.verbose>3) clog << "checking instances of inline " << q->dw.function_name << "\n"; - q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg); + q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, q); if (q->dw.function_name_final_match (q->function)) return DWARF_CB_ABORT; @@ -4026,7 +4027,9 @@ query_cu (Dwarf_Die * cudie, void * arg) // Pick up [entrypc, name, DIE] tuples for all the functions // matching the query, and fill in the prologue endings of them // all in a single pass. - int rc = q->dw.iterate_over_functions (query_dwarf_func, q); + int rc = q->dw.iterate_over_functions (query_dwarf_func, q, + q->function, + q->has_statement_num); if (rc != DWARF_CB_OK) q->query_done = true; -- cgit From 0a6f5a3f0c2ecfb8b4a416dd07d5b976daf79551 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 19:32:25 -0800 Subject: Build tracequery to scan for tracepoints * session.h (systemtap_session): add tracepoint_derived_probes * buildrun.cxx (make_tracequery): New - builds a kernel module that hijacks the tracepoint declarations, so we can query debuginfo. * buildrun.h: declare above * tapsets.cxx (tracepoint_builder): New builder for tracepoint probes. For now it just handles the initialization to build the tracequery kernel module. --- buildrun.cxx | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ buildrun.h | 1 + session.h | 2 ++ tapsets.cxx | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+) diff --git a/buildrun.cxx b/buildrun.cxx index 973343cd..b81cba23 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -24,6 +24,7 @@ extern "C" { #include #include #include +#include } @@ -336,4 +337,73 @@ run_pass (systemtap_session& s) return rc; } + +// Build a tiny kernel module to query tracepoints +int +make_tracequery(systemtap_session& s, string& name) +{ + // create a subdirectory for the module + string dir(s.tmpdir + "/tracequery"); + if (create_dir(dir.c_str()) != 0) + { + if (! s.suppress_warnings) + cerr << "Warning: failed to create directory for querying tracepoints." << endl; + return 1; + } + + name = dir + "/tracequery.ko"; + + // create a simple Makefile + string makefile(dir + "/Makefile"); + ofstream omf(makefile.c_str()); + omf << "EXTRA_CFLAGS := -g" << endl; // force debuginfo generation + omf << "obj-m := tracequery.o" << endl; + omf.close(); + + // create our source file + string source(dir + "/tracequery.c"); + ofstream osrc(source.c_str()); + osrc << "#include " << endl; + osrc << "#ifdef CONFIG_TRACEPOINTS" << endl; + osrc << "#include " << endl; + + // override DECLARE_TRACE to synthesize probe functions for us + osrc << "#undef DECLARE_TRACE" << endl; + osrc << "#define DECLARE_TRACE(name, proto, args) \\" << endl; + osrc << " void stapprobe_##name(proto) {}" << endl; + + // dynamically pull in all tracepoint headers from include/trace/ + glob_t trace_glob; + string glob_str(s.kernel_build_tree + "/include/trace/*.h"); + glob(glob_str.c_str(), 0, NULL, &trace_glob); + for (unsigned i = 0; i < trace_glob.gl_pathc; ++i) + { + string header(basename(trace_glob.gl_pathv[i])); + + // filter out a few known "internal-only" headers + if (header == "trace_events.h") + continue; + if (header.find("_event_types.h") != string::npos) + continue; + + osrc << "#include " << endl; + } + globfree(&trace_glob); + + // finish up the module source + osrc << "#endif /* CONFIG_TRACEPOINTS */" << endl; + osrc << "int init_module(void) { return 0; }" << endl; + osrc << "void cleanup_module(void) {}" << endl; + osrc << "MODULE_DESCRIPTION(\"tracepoint query\");" << endl; + osrc << "MODULE_LICENSE(\"GPL\");" << endl; + osrc.close(); + + // make the module + string make_cmd = "make -C '" + s.kernel_build_tree + "'" + + " M='" + dir + "' modules"; + if (s.verbose < 4) + make_cmd += " >/dev/null 2>&1"; + return run_make_cmd(s, make_cmd); +} + /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ diff --git a/buildrun.h b/buildrun.h index 98c81251..88127449 100644 --- a/buildrun.h +++ b/buildrun.h @@ -14,6 +14,7 @@ int compile_pass (systemtap_session& s); int run_pass (systemtap_session& s); +int make_tracequery(systemtap_session& s, std::string& name); #endif // BUILDRUN_H diff --git a/session.h b/session.h index e6d8eb82..8fa491fd 100644 --- a/session.h +++ b/session.h @@ -37,6 +37,7 @@ struct task_finder_derived_probe_group; struct timer_derived_probe_group; struct profile_derived_probe_group; struct mark_derived_probe_group; +struct tracepoint_derived_probe_group; struct hrtimer_derived_probe_group; struct perfmon_derived_probe_group; struct procfs_derived_probe_group; @@ -162,6 +163,7 @@ struct systemtap_session timer_derived_probe_group* timer_derived_probes; profile_derived_probe_group* profile_derived_probes; mark_derived_probe_group* mark_derived_probes; + tracepoint_derived_probe_group* tracepoint_derived_probes; hrtimer_derived_probe_group* hrtimer_derived_probes; perfmon_derived_probe_group* perfmon_derived_probes; procfs_derived_probe_group* procfs_derived_probes; diff --git a/tapsets.cxx b/tapsets.cxx index 834aa06a..6693e9c3 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -15,6 +15,7 @@ #include "translate.h" #include "session.h" #include "util.h" +#include "buildrun.h" #include "dwarf_wrappers.h" #include "auto_free.h" @@ -465,6 +466,7 @@ static string TOK_STATEMENT("statement"); static string TOK_ABSOLUTE("absolute"); static string TOK_PROCESS("process"); static string TOK_MARK("mark"); +static string TOK_TRACE("trace"); static string TOK_LABEL("label"); // Can we handle this query with just symbol-table info? @@ -9200,6 +9202,81 @@ mark_builder::build(systemtap_session & sess, +// ------------------------------------------------------------------------ +// statically inserted kernel-tracepoint derived probes +// ------------------------------------------------------------------------ + + +struct tracepoint_derived_probe: public derived_probe +{ + // TODO +}; + + +struct tracepoint_derived_probe_group: public generic_dpg +{ + // TODO +}; + + +struct tracepoint_builder: public derived_probe_builder +{ +private: + dwflpp *dw; + bool init_dw(systemtap_session& s); + +public: + tracepoint_builder(): dw(0) {} + ~tracepoint_builder() { delete dw; } + + void build_no_more (systemtap_session& s) + { + if (dw && s.verbose > 3) + clog << "tracepoint_builder releasing dwflpp" << endl; + delete dw; + dw = NULL; + } + + void build(systemtap_session& s, + probe *base, probe_point *location, + literal_map_t const& parameters, + vector& finished_results); +}; + + +bool +tracepoint_builder::init_dw(systemtap_session& s) +{ + if (dw != NULL) + return true; + + string tracequery_ko; + int rc = make_tracequery(s, tracequery_ko); + if (rc != 0) + return false; + + // TODO cache tracequery.ko + + dw = new dwflpp(s); + dw->setup_user(tracequery_ko); + return true; +} + + +void +tracepoint_builder::build(systemtap_session& s, + probe *base, probe_point *location, + literal_map_t const& parameters, + vector& finished_results) +{ + if (!init_dw(s)) + return; + + // TODO run a query to match tracepoint locations +} + + + // ------------------------------------------------------------------------ // hrtimer derived probes // ------------------------------------------------------------------------ @@ -10002,6 +10079,10 @@ register_standard_tapsets(systemtap_session & s) s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_MARK)->bind_str(TOK_FORMAT) ->bind(new mark_builder()); + // kernel tracepoint probes + s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_TRACE) + ->bind(new tracepoint_builder()); + // procfs parts s.pattern_root->bind(TOK_PROCFS)->bind(TOK_READ)->bind(new procfs_builder()); s.pattern_root->bind_str(TOK_PROCFS)->bind(TOK_READ) @@ -10030,6 +10111,7 @@ all_session_groups(systemtap_session& s) DOONE(timer); DOONE(profile); DOONE(mark); + DOONE(tracepoint); DOONE(hrtimer); DOONE(perfmon); DOONE(procfs); -- cgit From 75ead1f7f65c280a7a068e562dbb7b751f1f0de4 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 19:56:02 -0800 Subject: Scan tracequery.ko for tracepoints * tapsets.cxx (tracepoint_query): Iterate over the modules, CUs, and functions in tracequery.ko looking for our hijacked tracepoint declarations. (tracepoint_builder::build): Run a tracepoint_query --- tapsets.cxx | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/tapsets.cxx b/tapsets.cxx index 6693e9c3..adda3d19 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9219,6 +9219,80 @@ struct tracepoint_derived_probe_group: public generic_dpg & results): + base_query(dw, "*"), tracepoint(tracepoint), + base_probe(base_probe), base_loc(base_loc), + results(results) {} + + const string& tracepoint; + + probe * base_probe; + probe_point * base_loc; + vector & results; + + void handle_query_module(); + int handle_query_cu(Dwarf_Die * cudie); + int handle_query_func(Dwarf_Die * func); + + static int tracepoint_query_cu (Dwarf_Die * cudie, void * arg); + static int tracepoint_query_func (Dwarf_Die * func, base_query * query); +}; + + +void +tracepoint_query::handle_query_module() +{ + // look for the tracepoints in each CU + dw.iterate_over_cus(tracepoint_query_cu, this); +} + + +int +tracepoint_query::handle_query_cu(Dwarf_Die * cudie) +{ + dw.focus_on_cu (cudie); + + // look at each function to see if it's a tracepoint + string function = "stapprobe_" + tracepoint; + return dw.iterate_over_functions (tracepoint_query_func, this, function); +} + + +int +tracepoint_query::handle_query_func(Dwarf_Die * func) +{ + dw.focus_on_function (func); + + assert(dw.function_name.compare(0, 10, "stapprobe_") == 0); + string tracepoint_instance = dw.function_name.substr(10); + // TODO build a tracepoint_derived_probe + clog << "DEBUG: found a tracepoint: " << tracepoint_instance << endl; + return DWARF_CB_OK; +} + + +int +tracepoint_query::tracepoint_query_cu (Dwarf_Die * cudie, void * arg) +{ + tracepoint_query * q = static_cast(arg); + if (pending_interrupts) return DWARF_CB_ABORT; + return q->handle_query_cu(cudie); +} + + +int +tracepoint_query::tracepoint_query_func (Dwarf_Die * func, base_query * query) +{ + tracepoint_query * q = static_cast(query); + if (pending_interrupts) return DWARF_CB_ABORT; + return q->handle_query_func(func); +} + + struct tracepoint_builder: public derived_probe_builder { private: @@ -9272,7 +9346,11 @@ tracepoint_builder::build(systemtap_session& s, if (!init_dw(s)) return; - // TODO run a query to match tracepoint locations + string tracepoint; + assert(get_param (parameters, TOK_TRACE, tracepoint)); + + tracepoint_query q(*dw, tracepoint, base, location, finished_results); + dw->query_modules(&q); } -- cgit From 79189b84b112484901e5ee6b84a334da24791128 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 20:17:38 -0800 Subject: Build skeleton tracepoint probes * tapsets.cxx (tracepoint_derived_probe): Create a skeleton probe (tracepoint_derived_probe_group): Create a skeleton group (tracepoint_query::handle_query_func): build a probe --- tapsets.cxx | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index adda3d19..f7bba968 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9209,16 +9209,89 @@ mark_builder::build(systemtap_session & sess, struct tracepoint_derived_probe: public derived_probe { - // TODO + tracepoint_derived_probe (systemtap_session& s, + dwflpp& dw, Dwarf_Die& func_die, + const string& tracepoint_name, + probe* base_probe, probe_point* location); + + systemtap_session& sess; + string tracepoint_name; + + void join_group (systemtap_session& s); }; struct tracepoint_derived_probe_group: public generic_dpg { - // TODO + void emit_module_decls (systemtap_session& s); + void emit_module_init (systemtap_session& s); + void emit_module_exit (systemtap_session& s); }; +tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s, + dwflpp& dw, Dwarf_Die& func_die, + const string& tracepoint_name, + probe* base, probe_point* loc): + derived_probe (base, new probe_point(*loc) /* .components soon rewritten */), + sess (s), tracepoint_name (tracepoint_name) +{ + // create synthetic probe point name; preserve condition + vector comps; + comps.push_back (new probe_point::component (TOK_KERNEL)); + comps.push_back (new probe_point::component (TOK_TRACE, new literal_string (tracepoint_name))); + this->sole_location()->components = comps; + + if (sess.verbose > 2) + clog << "tracepoint-based " << name << " tracepoint='" << tracepoint_name + << "'" << endl; +} + + +void +tracepoint_derived_probe::join_group (systemtap_session& s) +{ + if (! s.tracepoint_derived_probes) + s.tracepoint_derived_probes = new tracepoint_derived_probe_group (); + s.tracepoint_derived_probes->enroll (this); +} + + +void +tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) +{ + if (probes.empty()) + return; + + s.op->newline() << "/* ---- tracepointer probes ---- */"; + + // TODO +} + + +void +tracepoint_derived_probe_group::emit_module_init (systemtap_session &s) +{ + if (probes.size () == 0) + return; + + s.op->newline() << "/* init tracepoint probes */"; + + // TODO +} + + +void +tracepoint_derived_probe_group::emit_module_exit (systemtap_session& s) +{ + if (probes.empty()) + return; + + s.op->newline() << "/* deregister tracepointer probes */"; + // TODO +} + + struct tracepoint_query : public base_query { tracepoint_query(dwflpp & dw, const string & tracepoint, @@ -9269,8 +9342,10 @@ tracepoint_query::handle_query_func(Dwarf_Die * func) assert(dw.function_name.compare(0, 10, "stapprobe_") == 0); string tracepoint_instance = dw.function_name.substr(10); - // TODO build a tracepoint_derived_probe - clog << "DEBUG: found a tracepoint: " << tracepoint_instance << endl; + derived_probe *dp = new tracepoint_derived_probe (dw.sess, dw, *func, + tracepoint_instance, + base_probe, base_loc); + results.push_back (dp); return DWARF_CB_OK; } -- cgit From 6fb70fb7915c3f5f7352e5393efb859b70e6f3fc Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 20:32:22 -0800 Subject: Emit code to hook up tracepoint probes * tapsets.cxx (tracepoint_arg): New (tracepoint_derived_probe): Add declaring header name and arg vector (dwarf_type_name): Build a type string for a given type DIE (tracepoint_derived_probe::build_args): Scan the function DIE for the name and type of formal parameters required by the tracepoint. (tracepoint_derived_probe::tracepoint_derived_probe): Call build_args and determine the relevant header to include. (tracepoint_derived_probe_group::emit_module_decls): For each tracepoint, include its header and declare a probe entry point with the right function signature. (tracepoint_derived_probe_group::emit_module_init): Call the registration for each tracepoint, and handle error unwinding. (tracepoint_derived_probe_group::emit_module_exit): Unregister each. --- tapsets.cxx | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 4 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index f7bba968..7c054411 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9206,6 +9206,10 @@ mark_builder::build(systemtap_session & sess, // statically inserted kernel-tracepoint derived probes // ------------------------------------------------------------------------ +struct tracepoint_arg +{ + string name, c_type; +}; struct tracepoint_derived_probe: public derived_probe { @@ -9215,8 +9219,10 @@ struct tracepoint_derived_probe: public derived_probe probe* base_probe, probe_point* location); systemtap_session& sess; - string tracepoint_name; + string tracepoint_name, header; + vector args; + void build_args(dwflpp& dw, Dwarf_Die& func_die); void join_group (systemtap_session& s); }; @@ -9242,12 +9248,116 @@ tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s, comps.push_back (new probe_point::component (TOK_TRACE, new literal_string (tracepoint_name))); this->sole_location()->components = comps; + // fill out the available arguments in this tracepoint + build_args(dw, func_die); + + // determine which header defined this tracepoint + string decl_file = dwarf_decl_file(&func_die); + size_t header_pos = decl_file.rfind("trace/"); + if (header_pos == string::npos) + throw semantic_error ("cannot parse header location for tracepoint '" + + tracepoint_name + "' in '" + + decl_file + "'"); + header = decl_file.substr(header_pos); + + // tracepoints from FOO_event_types.h should really be included from FOO.h + // XXX can dwarf tell us the include hierarchy? it would be better to + // ... walk up to see which one was directly included by tracequery.c + header_pos = header.find("_event_types"); + if (header_pos != string::npos) + header.erase(header_pos, 12); + if (sess.verbose > 2) clog << "tracepoint-based " << name << " tracepoint='" << tracepoint_name << "'" << endl; } +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) + { + 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); + return true; + } + + // otherwise, this die is a type modifier. + + // recurse into the referent type + 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; + + const char *suffix = NULL; + switch (dwarf_tag(&type_die)) + { + case DW_TAG_pointer_type: + suffix = "*"; + break; + case DW_TAG_array_type: + suffix = "[]"; + break; + case DW_TAG_const_type: + suffix = " const"; + break; + case DW_TAG_volatile_type: + suffix = " volatile"; + break; + default: + return false; + } + c_type.append(suffix); + return true; +} + + +void +tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) +{ + Dwarf_Die arg; + if (dwarf_child(&func_die, &arg) == 0) + do + if (dwarf_tag(&arg) == DW_TAG_formal_parameter) + { + // build a tracepoint_arg for this parameter + tracepoint_arg tparg; + tparg.name = dwarf_diename_integrate(&arg); + + // read the type of this parameter + Dwarf_Attribute type_attr; + Dwarf_Die type_die; + if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) + || !dwarf_formref_die (&type_attr, &type_die) + || !dwarf_type_name(type_die, tparg.c_type)) + throw semantic_error ("cannot get type of tracepoint '" + + tracepoint_name + "' parameter '" + + tparg.name + "'"); + + args.push_back(tparg); + if (sess.verbose > 4) + clog << "found parameter for tracepoint '" << tracepoint_name + << "': type:'" << tparg.c_type + << "' name:'" << tparg.name << "'" << endl; + } + while (dwarf_siblingof(&arg, &arg) == 0); +} + + void tracepoint_derived_probe::join_group (systemtap_session& s) { @@ -9265,7 +9375,28 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "/* ---- tracepointer probes ---- */"; - // TODO + for (unsigned i = 0; i < probes.size(); ++i) + { + tracepoint_derived_probe *p = probes[i]; + s.op->newline(); + s.op->newline() << "#include <" << p->header << ">"; + s.op->newline() << "static void enter_tracepoint_probe_" << i << "("; + for (unsigned j = 0; j < p->args.size(); ++j) + { + if (j > 0) + s.op->line() << ", "; + s.op->line() << p->args[j].c_type << " __tracepoint_arg_" << p->args[j].name; + } + s.op->line() << ") {"; + s.op->indent(1); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); + s.op->newline() << "c->probe_point = " + << lex_cast_qstring (*p->sole_location()) << ";"; + s.op->newline() << p->name << " (c);"; + common_probe_entryfn_epilogue (s.op); + s.op->newline(-1) << "}"; + s.op->newline(); + } } @@ -9277,7 +9408,27 @@ tracepoint_derived_probe_group::emit_module_init (systemtap_session &s) s.op->newline() << "/* init tracepoint probes */"; - // TODO + // We can't use a simple runtime loop because the probe registration + // functions are distinct inlines. Instead, this will generate nesting as + // deep as the number of probe points. Gotos are also possible, but the end + // result is the same. + + for (unsigned i = 0; i < probes.size(); ++i) + { + s.op->newline() << "if (!rc) {"; + s.op->newline(1) << "probe_point = " + << lex_cast_qstring (*probes[i]->sole_location()) << ";"; + s.op->newline() << "rc = register_trace_" << probes[i]->tracepoint_name + << "(enter_tracepoint_probe_" << i << ");"; + } + + for (unsigned i = probes.size() - 1; i < probes.size(); --i) + { + s.op->newline() << "if (rc)"; + s.op->newline(1) << "unregister_trace_" << probes[i]->tracepoint_name + << "(enter_tracepoint_probe_" << i << ");"; + s.op->newline(-2) << "}"; + } } @@ -9288,7 +9439,9 @@ tracepoint_derived_probe_group::emit_module_exit (systemtap_session& s) return; s.op->newline() << "/* deregister tracepointer probes */"; - // TODO + for (unsigned i = 0; i < probes.size(); ++i) + s.op->newline() << "unregister_trace_" << probes[i]->tracepoint_name + << "(enter_tracepoint_probe_" << i << ");"; } -- cgit From f8a968bccd1e71f2e8f486e60ff95a4d718a6332 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 21:07:54 -0800 Subject: Enable tracepoint target variables This uses a similar mechanism as marker probes for storing target variables in locals of the probe body. * tapsets.cxx (tracepoint_arg): Add fields to help $target access. (tracepoint_var_expanding_visitor): Expand code to access target variables - a $target for each tracepoint parameter, as well as the special $$name and $$vars. (tracepoint_derived_probe::tracepoint_derived_probe): Expand targets (resolve_tracepoint_arg_type): Determine if a parameter is a type that we can dereference, and store the underlying type. (tracepoint_derived_probe::build_args): Resolve the types. (tracepoint_derived_probe::emit_probe_context_vars): Emit $target placeholders into the locals of the probe body. (tracepoint_derived_probe_group::emit_module_decls): Initialize $targets from the entry point parameters. --- tapsets.cxx | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 338 insertions(+), 3 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 7c054411..5aa67e4d 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9209,6 +9209,9 @@ mark_builder::build(systemtap_session & sess, struct tracepoint_arg { string name, c_type; + bool used, isptr; + Dwarf_Die type_die; + tracepoint_arg(): used(false), isptr(false) {} }; struct tracepoint_derived_probe: public derived_probe @@ -9224,6 +9227,7 @@ struct tracepoint_derived_probe: public derived_probe void build_args(dwflpp& dw, Dwarf_Die& func_die); void join_group (systemtap_session& s); + void emit_probe_context_vars (translator_output* o); }; @@ -9235,6 +9239,283 @@ struct tracepoint_derived_probe_group: public generic_dpg& args): + dw (dw), probe_name (probe_name), args (args) {} + dwflpp& dw; + const string& probe_name; + vector & args; + + void visit_target_symbol (target_symbol* e); + void visit_target_symbol_arg (target_symbol* e); + void visit_target_symbol_context (target_symbol* e); +}; + + +void +tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) +{ + string argname = e->base_name.substr(1); + + // 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) + { + arg = &args[i]; + arg->used = true; + break; + } + + if (arg == NULL) + { + stringstream alternatives; + for (unsigned i = 0; i < args.size(); ++i) + alternatives << " $" << args[i].name; + alternatives << " $$name $$vars"; + + // We hope that this value ends up not being referenced after all, so it + // can be optimized out quietly. + semantic_error* saveme = + new semantic_error("unable to find tracepoint variable '" + e->base_name + + "' (alternatives:" + alternatives.str () + ")", e->tok); + // NB: we can have multiple errors, since a target variable + // may be expanded in several different contexts: + // trace ("*") { $foo->bar } + saveme->chain = e->saved_conversion_error; + e->saved_conversion_error = saveme; + provide (e); + return; + } + + // make sure we're not dereferencing base types + if (!e->components.empty() && !arg->isptr) + switch (e->components[0].first) + { + case target_symbol::comp_literal_array_index: + throw semantic_error("tracepoint variable '" + e->base_name + + "' may not be used as array", e->tok); + case target_symbol::comp_struct_member: + throw semantic_error("tracepoint variable '" + e->base_name + + "' may not be used as a structure", e->tok); + default: + throw semantic_error("invalid use of tracepoint variable '" + + e->base_name + "'", e->tok); + } + + // we can only write to dereferenced fields, and only if guru mode is on + bool lvalue = is_active_lvalue(e); + if (lvalue && (!dw.sess.guru_mode || e->components.empty())) + throw semantic_error("write to tracepoint variable '" + e->base_name + + "' not permitted", e->tok); + + if (e->components.empty()) + { + // Synthesize a simple function to grab the parameter + functiondecl *fdecl = new functiondecl; + fdecl->tok = e->tok; + embeddedcode *ec = new embeddedcode; + ec->tok = e->tok; + + string fname = (string("_tracepoint_tvar_get") + + "_" + e->base_name.substr(1) + + "_" + lex_cast(tick++)); + + fdecl->name = fname; + fdecl->body = ec; + fdecl->type = pe_long; + + ec->code = (string("THIS->__retvalue = CONTEXT->locals[0].") + + probe_name + string(".__tracepoint_arg_") + + arg->name + string (";/* pure */")); + + dw.sess.functions[fdecl->name] = fdecl; + + // Synthesize a functioncall. + functioncall* n = new functioncall; + n->tok = e->tok; + n->function = fname; + n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session + + provide (n); + } + else + { + // Synthesize a function to dereference the dwarf fields, + // with a pointer parameter that is the base tracepoint variable + functiondecl *fdecl = new functiondecl; + fdecl->tok = e->tok; + embeddedcode *ec = new embeddedcode; + ec->tok = e->tok; + + string fname = (string(lvalue ? "_tracepoint_tvar_set" : "_tracepoint_tvar_get") + + "_" + e->base_name.substr(1) + + "_" + lex_cast(tick++)); + + fdecl->name = fname; + fdecl->body = ec; + + try + { + ec->code = dw.literal_stmt_for_pointer (&arg->type_die, e->components, + lvalue, fdecl->type); + } + catch (const semantic_error& er) + { + // We suppress this error message, and pass the unresolved + // variable 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* saveme = new semantic_error (er); // copy it + saveme->tok1 = e->tok; // XXX: token not passed to dw code generation routines + // NB: we can have multiple errors, since a target variable + // may be expanded in several different contexts: + // trace ("*") { $foo->bar } + saveme->chain = e->saved_conversion_error; + e->saved_conversion_error = saveme; + provide (e); + return; + } + + // Give the fdecl an argument for the raw tracepoint value + vardecl *v1 = new vardecl; + v1->type = pe_long; + v1->name = "pointer"; + v1->tok = e->tok; + fdecl->formal_args.push_back(v1); + + if (lvalue) + { + // Modify the fdecl so it carries a pe_long formal + // argument called "value". + + // FIXME: For the time being we only support setting target + // variables which have base types; these are 'pe_long' in + // stap's type vocabulary. Strings and pointers might be + // reasonable, some day, but not today. + + vardecl *v2 = new vardecl; + v2->type = pe_long; + v2->name = "value"; + v2->tok = e->tok; + fdecl->formal_args.push_back(v2); + } + else + ec->code += "/* pure */"; + + dw.sess.functions[fdecl->name] = fdecl; + + // Synthesize a functioncall. + functioncall* n = new functioncall; + n->tok = e->tok; + n->function = fname; + n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session + + // make the original a bare target symbol for the tracepoint value, + // which will be passed into the dwarf dereferencing code + e->components.clear(); + n->args.push_back(require(e)); + + if (lvalue) + { + // Provide the functioncall to our parent, so that it can be + // used to substitute for the assignment node immediately above + // us. + assert(!target_symbol_setter_functioncalls.empty()); + *(target_symbol_setter_functioncalls.top()) = n; + } + + provide (n); + } +} + + +void +tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) +{ + if (is_active_lvalue (e)) + throw semantic_error("write to tracepoint '" + e->base_name + "' not permitted", e->tok); + + if (!e->components.empty()) + switch (e->components[0].first) + { + case target_symbol::comp_literal_array_index: + throw semantic_error("tracepoint '" + e->base_name + "' may not be used as array", + e->tok); + case target_symbol::comp_struct_member: + throw semantic_error("tracepoint '" + e->base_name + "' may not be used as a structure", + e->tok); + default: + throw semantic_error("invalid tracepoint '" + e->base_name + "' use", e->tok); + } + + if (e->base_name == "$$name") + { + // Synthesize a functioncall. + functioncall* n = new functioncall; + n->tok = e->tok; + n->function = "_mark_name_get"; + n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session + provide (n); + } + else if (e->base_name == "$$vars") + { + target_symbol *tsym = new target_symbol; + print_format* pf = new print_format; + + // Convert $$vars to sprintf of a list of vars which we recursively evaluate + // NB: we synthesize a new token here rather than reusing + // e->tok, because print_format::print likes to use + // its tok->content. + token* pf_tok = new token(*e->tok); + pf_tok->content = "sprintf"; + + pf->tok = pf_tok; + pf->print_to_stream = false; + pf->print_with_format = true; + pf->print_with_delim = false; + pf->print_with_newline = false; + pf->print_char = false; + + for (unsigned i = 0; i < args.size(); ++i) + { + if (i > 0) + pf->raw_components += " "; + pf->raw_components += args[i].name; + tsym->tok = e->tok; + tsym->base_name = "$" + args[i].name; + + // every variable should always be accessible! + tsym->saved_conversion_error = 0; + expression *texp = require (tsym); // NB: throws nothing ... + assert (!tsym->saved_conversion_error); // ... but this is how we know it happened. + + pf->raw_components += "=%#x"; + pf->args.push_back(texp); + } + + pf->components = print_format::string_to_components(pf->raw_components); + provide (pf); + } + else + assert(0); // shouldn't get here +} + +void +tracepoint_var_expanding_visitor::visit_target_symbol (target_symbol* e) +{ + assert(e->base_name.size() > 0 && e->base_name[0] == '$'); + + if (e->base_name == "$$name" || e->base_name == "$$vars") + visit_target_symbol_context (e); + else + visit_target_symbol_arg (e); +} + + + tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s, dwflpp& dw, Dwarf_Die& func_die, const string& tracepoint_name, @@ -9267,6 +9548,10 @@ tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s, if (header_pos != string::npos) header.erase(header_pos, 12); + // Now expand the local variables in the probe body + tracepoint_var_expanding_visitor v (dw, name, args); + this->body = v.require (this->body); + if (sess.verbose > 2) clog << "tracepoint-based " << name << " tracepoint='" << tracepoint_name << "'" << endl; @@ -9326,6 +9611,36 @@ dwarf_type_name(Dwarf_Die& type_die, string& c_type) } +static bool +resolve_tracepoint_arg_type(Dwarf_Die& type_die, bool& isptr) +{ + Dwarf_Attribute type_attr; + switch (dwarf_tag(&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)); + case DW_TAG_base_type: + // base types will simply be treated as script longs + 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)); + default: + // should we consider other types too? + return false; + } +} + + void tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) { @@ -9340,10 +9655,10 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) // read the type of this parameter Dwarf_Attribute type_attr; - Dwarf_Die type_die; if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) - || !dwarf_formref_die (&type_attr, &type_die) - || !dwarf_type_name(type_die, tparg.c_type)) + || !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)) throw semantic_error ("cannot get type of tracepoint '" + tracepoint_name + "' parameter '" + tparg.name + "'"); @@ -9367,6 +9682,15 @@ tracepoint_derived_probe::join_group (systemtap_session& s) } +void +tracepoint_derived_probe::emit_probe_context_vars (translator_output* o) +{ + for (unsigned i = 0; i < args.size(); i++) + if (args[i].used) + o->newline() << "int64_t __tracepoint_arg_" << args[i].name << ";"; +} + + void tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) { @@ -9392,6 +9716,17 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); s.op->newline() << "c->probe_point = " << lex_cast_qstring (*p->sole_location()) << ";"; + s.op->newline() << "c->marker_name = " + << lex_cast_qstring (p->tracepoint_name) << ";"; + for (unsigned j = 0; j < p->args.size(); ++j) + if (p->args[j].used) + { + 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() << "__tracepoint_arg_" << p->args[j].name << ";"; + } s.op->newline() << p->name << " (c);"; common_probe_entryfn_epilogue (s.op); s.op->newline(-1) << "}"; -- cgit From d99d881952436f5b01364b8f31b1bc90c22a1444 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 6 Mar 2009 15:44:50 -0800 Subject: Support older tracepoints using DEFINE_TRACE At one point, the tracepoints API didn't have DECLARE_TRACE, and the trace headers all used DEFINE_TRACE. This is what got pulled into RHEL, so we need to support this older usage. The rest of the API stays the same though. * buildrun.cxx (make_tracequery): Redefine DEFINE_TRACE as well. --- buildrun.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/buildrun.cxx b/buildrun.cxx index b81cba23..2685949d 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -372,6 +372,11 @@ make_tracequery(systemtap_session& s, string& name) osrc << "#define DECLARE_TRACE(name, proto, args) \\" << endl; osrc << " void stapprobe_##name(proto) {}" << endl; + // older tracepoints used DEFINE_TRACE, so redirect that too + osrc << "#undef DEFINE_TRACE" << endl; + osrc << "#define DEFINE_TRACE(name, proto, args) \\" << endl; + osrc << " DECLARE_TRACE(name, TPPROTO(proto), TPARGS(args))" << endl; + // dynamically pull in all tracepoint headers from include/trace/ glob_t trace_glob; string glob_str(s.kernel_build_tree + "/include/trace/*.h"); -- cgit From ddc5ee5a548c8c945b63d9e3076efb12272d2617 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 6 Mar 2009 19:30:39 -0800 Subject: Ensure tracepoints are synchronized after unreg The tracepoint API provides tracepoint_synchronize_unregister() as a way to guarantee that all tracepoint handlers are inactive. This is necessary after unregistering to allow the module to safely unload. * tapsets.cxx (tracepoint_derived_probe_group::emit_module_init): Call synchronize after unregistering tracepoints. (tracepoint_derived_probe_group::emit_module_exit): Ditto. --- tapsets.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tapsets.cxx b/tapsets.cxx index 5aa67e4d..defaf385 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9764,6 +9764,9 @@ tracepoint_derived_probe_group::emit_module_init (systemtap_session &s) << "(enter_tracepoint_probe_" << i << ");"; s.op->newline(-2) << "}"; } + s.op->newline() << "if (rc)"; + s.op->newline(1) << "tracepoint_synchronize_unregister();"; + s.op->indent(-1); } @@ -9777,6 +9780,7 @@ tracepoint_derived_probe_group::emit_module_exit (systemtap_session& s) for (unsigned i = 0; i < probes.size(); ++i) s.op->newline() << "unregister_trace_" << probes[i]->tracepoint_name << "(enter_tracepoint_probe_" << i << ");"; + s.op->newline() << "tracepoint_synchronize_unregister();"; } -- cgit From bc724b8b2ee799f23a64aee42d5e439d1666ecaa Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 6 Mar 2009 19:36:05 -0800 Subject: Document TRACEPOINTS in stapprobes(5) --- stapprobes.5.in | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/stapprobes.5.in b/stapprobes.5.in index 0854be53..0daeb973 100644 --- a/stapprobes.5.in +++ b/stapprobes.5.in @@ -548,6 +548,42 @@ The marker format string associated with a marker is available in And also the marker name string is avalable in .BR $name . +.SS TRACEPOINTS + +This family of probe points hooks up to static probing tracepoints +inserted into the kernel or modules. As with markers, these +tracepoints are special macro calls inserted by kernel developers to +make probing faster and more reliable than with DWARF-based probes, +and DWARF debugging information is not required to probe tracepoints. +Tracepoints have an extra advantage of more strongly-typed parameters +than markers. + +Tracepoint probes begin with +.BR kernel . +The next part names the tracepoint itself: +.BR trace("name") . +The tracepoint name string, which may contain the usual wildcard +characters, is matched against the names defined by the kernel +developers in the tracepoint header files. + +The handler associated with a tracepoint-based probe may read the +optional parameters specified at the macro call site. These are +named according to the declaration by the tracepoint author. For +example, the tracepoint probe +.BR kernel.trace("sched_switch") +provides the parameters +.BR $rq ", " $prev ", and " $next . +If the parameter is a complex type, as in a struct pointer, then a +script can access fields with the same syntax as DWARF $target +variables. Also, tracepoint parameters cannot be modified, but in +guru-mode a script may modify fields of parameters. + +The name of the tracepoint is available in +.BR $$name , +and a string of name=value pairs for all parameters of the tracepoint +is available in +.BR $$vars . + .SS PERFORMANCE MONITORING HARDWARE The perfmon family of probe points is used to access the performance -- cgit From bc9a523d505c604c187dd2e81be1e24ec877d1af Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 7 Mar 2009 12:11:45 -0500 Subject: Tweak tracepoint logic to run on tracepoint_synchronize_unregister()-less RHEL5 --- tapsets.cxx | 17 +++++++++++++---- translate.cxx | 5 +++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index defaf385..5ea3982d 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9764,9 +9764,15 @@ tracepoint_derived_probe_group::emit_module_init (systemtap_session &s) << "(enter_tracepoint_probe_" << i << ");"; s.op->newline(-2) << "}"; } - s.op->newline() << "if (rc)"; - s.op->newline(1) << "tracepoint_synchronize_unregister();"; - s.op->indent(-1); + + // This would be technically proper (on those autoconf-detectable + // kernels that include this function in tracepoint.h), however we + // already make several calls to synchronze_sched() during our + // shutdown processes. + + // s.op->newline() << "if (rc)"; + // s.op->newline(1) << "tracepoint_synchronize_unregister();"; + // s.op->indent(-1); } @@ -9780,7 +9786,10 @@ tracepoint_derived_probe_group::emit_module_exit (systemtap_session& s) for (unsigned i = 0; i < probes.size(); ++i) s.op->newline() << "unregister_trace_" << probes[i]->tracepoint_name << "(enter_tracepoint_probe_" << i << ");"; - s.op->newline() << "tracepoint_synchronize_unregister();"; + + // Not necessary: see above. + + // s.op->newline() << "tracepoint_synchronize_unregister();"; } diff --git a/translate.cxx b/translate.cxx index 23a24100..c679e0f1 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1236,6 +1236,11 @@ c_unparser::emit_module_init () o->newline() << getvar (v).fini(); } + // For any partially registered/unregistered kernel facilities. + o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED"; + o->newline() << "synchronize_sched();"; + o->newline() << "#endif"; + o->newline() << "return rc;"; o->newline(-1) << "}\n"; } -- cgit From 944e2486c1bc490ead36fca86131b2a38416067d Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 7 Mar 2009 16:42:57 -0500 Subject: Add placeholder for new news --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 280b6fb2..08705c81 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* What's new + * What's new in version 0.9 - Typecasting is now supported using the @cast operator. A script can -- cgit From c12d974f4ad369f8d7585f2f07713dae3654b3fb Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 7 Mar 2009 17:00:54 -0500 Subject: PR9930: reentrancy debugging If stap is run with "-t -DDEBUG_REENTRANCY", additional warnings will be printed for every reentrancy event, including the probe points of the resident and interloper probes. * tapsets.cxx (common_probe_entryfn_prologue): Add "new_pp" argument, update all callers. Print reentrancy details if needed. --- tapsets.cxx | 73 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 5ea3982d..02f0b553 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -158,6 +158,7 @@ be_derived_probe::join_group (systemtap_session& s) // ------------------------------------------------------------------------ void common_probe_entryfn_prologue (translator_output* o, string statestr, + string new_pp, bool overload_processing = true, bool interruptible = true) { @@ -207,6 +208,15 @@ common_probe_entryfn_prologue (translator_output* o, string statestr, o->newline(1) << "atomic_inc (& skipped_count);"; o->newline() << "#ifdef STP_TIMING"; o->newline() << "atomic_inc (& skipped_count_reentrant);"; + o->newline() << "#ifdef DEBUG_REENTRANCY"; + o->newline() << "_stp_warn (\"Skipped %s due to %s residency on cpu %u\\n\", " + << new_pp << ", c->probe_point ?: \"?\", smp_processor_id());"; + // NB: There is a conceivable race condition here with reading + // c->probe_point, knowing that this other probe is sort of running. + // However, in reality, it's interrupted. Plus even if it were able + // to somehow start again, and stop before we read c->probe_point, + // at least we have that ?: "?" bit in there to avoid a NULL deref. + o->newline() << "#endif"; o->newline() << "#endif"; o->newline() << "atomic_dec (& c->busy);"; o->newline() << "goto probe_epilogue;"; @@ -217,12 +227,12 @@ common_probe_entryfn_prologue (translator_output* o, string statestr, o->newline() << "c->nesting = 0;"; o->newline() << "c->regs = 0;"; o->newline() << "c->unwaddr = 0;"; + o->newline() << "c->probe_point = " << new_pp << ";"; // reset unwound address cache o->newline() << "c->pi = 0;"; o->newline() << "c->regparm = 0;"; o->newline() << "c->marker_name = NULL;"; o->newline() << "c->marker_format = NULL;"; - o->newline() << "c->probe_point = 0;"; if (! interruptible) o->newline() << "c->actionremaining = MAXACTION;"; else @@ -290,6 +300,7 @@ common_probe_entryfn_epilogue (translator_output* o, o->newline() << "c->cycles_base = cycles_atend;"; o->newline() << "c->cycles_sum = 0;"; + o->newline() << "c->probe_point = 0;"; // vacated o->newline(-1) << "}"; o->newline(-1) << "}"; o->newline() << "#endif"; @@ -338,24 +349,21 @@ be_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "/* ---- begin/end probes ---- */"; s.op->newline() << "static void enter_begin_probe (void (*fn)(struct context*), const char* pp) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false, true); - s.op->newline() << "c->probe_point = pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", "pp", false, true); s.op->newline() << "(*fn) (c);"; common_probe_entryfn_epilogue (s.op, false, true); s.op->newline(-1) << "}"; s.op->newline() << "static void enter_end_probe (void (*fn)(struct context*), const char* pp) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false, true); - s.op->newline() << "c->probe_point = pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", "pp", false, true); s.op->newline() << "(*fn) (c);"; common_probe_entryfn_epilogue (s.op, false, true); s.op->newline(-1) << "}"; s.op->newline() << "static void enter_error_probe (void (*fn)(struct context*), const char* pp) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", false, true); - s.op->newline() << "c->probe_point = pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", "pp", false, true); s.op->newline() << "(*fn) (c);"; common_probe_entryfn_epilogue (s.op, false, true); s.op->newline(-1) << "}"; @@ -5467,8 +5475,7 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption // XXX: it would be nice to give a more verbose error though; BUG_ON later? s.op->line() << "];"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = sdp->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sdp->pp"); s.op->newline() << "c->regs = regs;"; s.op->newline() << "(*sdp->ph) (c);"; common_probe_entryfn_epilogue (s.op); @@ -5490,8 +5497,7 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) // XXX: it would be nice to give a more verbose error though; BUG_ON later? s.op->line() << "];"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = sdp->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sdp->pp"); s.op->newline() << "c->regs = regs;"; s.op->newline() << "c->pi = inst;"; // for assisting runtime's backtrace logic s.op->newline() << "(*sdp->ph) (c);"; @@ -6381,8 +6387,7 @@ itrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "static void enter_itrace_probe(struct stap_itrace_probe *p, struct pt_regs *regs, void *data) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = p->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "p->pp"); s.op->newline() << "c->regs = regs;"; s.op->newline() << "c->data = data;"; @@ -6974,8 +6979,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "static void stap_utrace_probe_handler(struct task_struct *tsk, struct stap_utrace_probe *p) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = p->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "p->pp"); // call probe function s.op->newline() << "(*p->ph) (c);"; @@ -6997,8 +7001,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->indent(1); s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = p->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "p->pp"); s.op->newline() << "c->regs = regs;"; // call probe function @@ -7486,10 +7489,9 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "static void enter_uprobe_probe (struct uprobe *inst, struct pt_regs *regs) {"; s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst, struct stap_uprobe, up);"; s.op->newline() << "struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sups->pp"); s.op->newline() << "if (sup->spec_index < 0 ||" << "sup->spec_index >= " << probes.size() << ") return;"; // XXX: should not happen - s.op->newline() << "c->probe_point = sups->pp;"; s.op->newline() << "c->regs = regs;"; s.op->newline() << "(*sups->ph) (c);"; common_probe_entryfn_epilogue (s.op); @@ -7498,10 +7500,9 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "static void enter_uretprobe_probe (struct uretprobe_instance *inst, struct pt_regs *regs) {"; s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst->rp, struct stap_uprobe, urp);"; s.op->newline() << "struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sups->pp"); s.op->newline() << "if (sup->spec_index < 0 ||" << "sup->spec_index >= " << probes.size() << ") return;"; // XXX: should not happen - s.op->newline() << "c->probe_point = sups->pp;"; // XXX: kretprobes saves "c->pi = inst;" too s.op->newline() << "c->regs = regs;"; s.op->newline() << "(*sups->ph) (c);"; @@ -7828,8 +7829,7 @@ timer_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->line() << ");"; s.op->newline(-1) << "{"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = stp->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "stp->pp"); s.op->newline() << "(*stp->ph) (c);"; common_probe_entryfn_epilogue (s.op); s.op->newline(-1) << "}"; @@ -7951,8 +7951,8 @@ profile_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "static void enter_all_profile_probes (struct pt_regs *regs) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = \"timer.profile\";"; // NB: hard-coded for convenience + string pp = lex_cast_qstring("timer.profile"); // hard-coded for convenience + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", pp); s.op->newline() << "c->regs = regs;"; for (unsigned i=0; inewline() << "int bytes = 0;"; s.op->newline() << "string_t strdata = {'\\0'};"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = spp->read_pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "spp->read_pp"); s.op->newline() << "if (c->data == NULL)"; s.op->newline(1) << "c->data = &strdata;"; @@ -8251,8 +8250,7 @@ procfs_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(1) << "struct stap_procfs_probe *spp = (struct stap_procfs_probe *)data;"; s.op->newline() << "string_t strdata = {'\\0'};"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = spp->write_pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "spp->write_pp"); s.op->newline() << "if (count > (MAXSTRINGLEN - 1))"; s.op->newline(1) << "count = MAXSTRINGLEN - 1;"; @@ -9012,8 +9010,7 @@ mark_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(); s.op->newline() << "static void enter_marker_probe (void *probe_data, void *call_data, const char *fmt, va_list *args) {"; s.op->newline(1) << "struct stap_marker_probe *smp = (struct stap_marker_probe *)probe_data;"; - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = smp->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "smp->pp"); s.op->newline() << "c->marker_name = smp->name;"; s.op->newline() << "c->marker_format = smp->format;"; s.op->newline() << "c->mark_va_list = args;"; @@ -9713,11 +9710,11 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) } s.op->line() << ") {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = " - << lex_cast_qstring (*p->sole_location()) << ";"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", + lex_cast_qstring (*p->sole_location())); s.op->newline() << "c->marker_name = " - << lex_cast_qstring (p->tracepoint_name) << ";"; + << lex_cast_qstring (p->tracepoint_name) + << ";"; for (unsigned j = 0; j < p->args.size(); ++j) if (p->args[j].used) { @@ -10070,8 +10067,7 @@ hrtimer_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(-1) << "}"; s.op->newline() << "{"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); - s.op->newline() << "c->probe_point = stp->pp;"; + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "stp->pp"); s.op->newline() << "(*stp->ph) (c);"; common_probe_entryfn_epilogue (s.op); s.op->newline(-1) << "}"; @@ -10435,7 +10431,8 @@ perfmon_derived_probe::emit_probe_entries (translator_output * o) emit_probe_prologue (o, (mode == perfmon_count ? "STAP_SESSION_STARTING" : - "STAP_SESSION_RUNNING")); + "STAP_SESSION_RUNNING"), + "probe_point"); // NB: locals are initialized by probe function itself o->newline() << name << " (c);"; -- cgit From 9b692b91ee25c33281c32c7ba86f5f0734e46be9 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Sun, 8 Mar 2009 19:55:05 -0400 Subject: Fix and add tests for function(".so").statement(N) * tapsets.cxx (query_dwarf_func): die_has_pc (dwarf_haspc) does not expect a module_start for shared objects so don't call module_address_to_global for the statement address. * testsuite/systemtap.base/labels.exp: Add tests for executable .statement(N), shared object .label("L") and so .statement(N). --- tapsets.cxx | 6 +-- testsuite/systemtap.base/labels.exp | 86 +++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 02f0b553..d99eebe2 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3920,9 +3920,9 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq) else if (q->has_function_num || q->has_statement_num) { Dwarf_Addr query_addr = - q->dw.module_address_to_global(q->has_function_num ? q->function_num_val : - q->has_statement_num ? q->statement_num_val : - (assert(0) , 0)); + (q->has_function_num ? q->function_num_val : + q->has_statement_num ? q->statement_num_val : + (assert(0) , 0)); Dwarf_Die d; q->dw.function_die (&d); diff --git a/testsuite/systemtap.base/labels.exp b/testsuite/systemtap.base/labels.exp index 9c92d69c..54640268 100644 --- a/testsuite/systemtap.base/labels.exp +++ b/testsuite/systemtap.base/labels.exp @@ -13,6 +13,7 @@ if {$utrace_support_found == 0} { untested "$test"; return } # Compile a C program to use as the user-space probing target set label_srcpath "[pwd]/labels.c" set label_exepath "[pwd]/labels.x" +set label_sopath "[pwd]/labels.so" set label_flags "additional_flags=-g" set fp [open $label_srcpath "w"] puts $fp " @@ -54,9 +55,12 @@ if { $res != "" } { pass "compiling labels.c -g" } +# label in an executable + verbose -log "spawn stap -c $label_exepath $label_stppath" spawn stap -c $label_exepath $label_stppath +wait expect { -timeout 180 -re {VARS a=0x0 b=0x0.*VARS a=0x2 b=0x0.*VARS a=0x2 b=0x3 c=0x[a-f01-9]} { incr ok; exp_continue } @@ -64,7 +68,83 @@ expect { eof { } } -wait +if {$ok == 1} { pass "$test exe .label" } { fail "$test exe .label" } + +# address of label in an executable + +set label_shpath "[pwd]/label.sh" +set fp [open $label_shpath "w"] +puts $fp " +readelf --debug-dump $label_exepath | awk \" +/init_another_int/ {have_label=1} +/DW_AT_low_pc/ {if (have_label) {print \$3;exit;}} +\" +" +close $fp +spawn sh $label_shpath +expect { + -re {0x[0-9a-f]*} +} +set ok 0 +spawn stap -p2 -l "process\(\"$label_exepath\"\).statement($expect_out(0,string))" +expect { + -timeout 180 + -re {no match} { incr ok; exp_continue } + timeout { fail "$test (timeout)" } + eof { } +} + +if {$ok == 0} { pass "$test exe .statement" } { xfail "$test exe .statement" } + +set ok 0 + +set label_flags "additional_flags=-g additional_flags=-shared additional_flags=-fPIC" +set res [target_compile $label_srcpath $label_sopath executable $label_flags] +if { $res != "" } { + verbose "target_compile failed: $res" 2 + fail "compiling labels.c -g" + catch {exec rm -f $label_srcpath $label_stppath} + return +} else { + pass "compiling labels.c -g" +} + +# label in a shared object + +spawn stap -p2 -l "process\(\"$label_sopath\"\).function\(\"\*\"\).label\(\"init_another_int\"\)" +expect { + -timeout 180 + -re {process.*function} { incr ok; exp_continue } + timeout { fail "$test (timeout)" } + eof { } +} + +if {$ok == 1} { pass "$test so .label" } { fail "$test so .label" } + +# address of label in a shared object + +set label_shpath "[pwd]/label.sh" +set fp [open $label_shpath "w"] +puts $fp " +readelf --debug-dump $label_sopath | awk \" +/init_another_int/ {have_label=1} +/DW_AT_low_pc/ {if (have_label) {print \$3;exit;}} +\" +" +close $fp +spawn sh $label_shpath +expect { + -re {0x[0-9a-f]*} +} +set ok 0 +spawn stap -p2 -l "process\(\"$label_sopath\"\).statement($expect_out(0,string))" +expect { + -timeout 180 + -re {no match} { incr ok; exp_continue } + timeout { fail "$test (timeout)" } + eof { } +} + +if {$ok == 0} { pass "$test so .statement" } { xfail "$test so .statement" } -if {$ok == 1} { pass "$test" } { fail "$test ($ok)" } -catch {exec rm -f $label_srcpath $label_stppath $label_exepath} +# catch {exec rm -f $label_srcpath $label_stppath $label_exepath} -- cgit From 4be9af07213db548443da4ae7ed365e98ed2b29c Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Sun, 8 Mar 2009 20:17:10 -0400 Subject: Minor changes to labels.exp. --- testsuite/systemtap.base/labels.exp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/testsuite/systemtap.base/labels.exp b/testsuite/systemtap.base/labels.exp index 54640268..1b538dbb 100644 --- a/testsuite/systemtap.base/labels.exp +++ b/testsuite/systemtap.base/labels.exp @@ -85,16 +85,16 @@ spawn sh $label_shpath expect { -re {0x[0-9a-f]*} } -set ok 0 +set nomatch 0 spawn stap -p2 -l "process\(\"$label_exepath\"\).statement($expect_out(0,string))" expect { -timeout 180 - -re {no match} { incr ok; exp_continue } + -re {semantic error: no match} { incr nomatch; exp_continue } timeout { fail "$test (timeout)" } eof { } } -if {$ok == 0} { pass "$test exe .statement" } { xfail "$test exe .statement" } +if {$nomatch == 0} { pass "$test exe .statement" } { fail "$test exe .statement" } set ok 0 @@ -136,15 +136,15 @@ spawn sh $label_shpath expect { -re {0x[0-9a-f]*} } -set ok 0 +set nomatch 0 spawn stap -p2 -l "process\(\"$label_sopath\"\).statement($expect_out(0,string))" expect { -timeout 180 - -re {no match} { incr ok; exp_continue } + -re {semantic error: no match} { incr nomatch; exp_continue } timeout { fail "$test (timeout)" } eof { } } -if {$ok == 0} { pass "$test so .statement" } { xfail "$test so .statement" } +if {$nomatch == 0} { pass "$test so .statement" } { fail "$test so .statement" } # catch {exec rm -f $label_srcpath $label_stppath $label_exepath} -- cgit From 2e802851f3c72d841fe436ec1e178d858bb37f6d Mon Sep 17 00:00:00 2001 From: ddomingo Date: Mon, 9 Mar 2009 11:10:13 +1000 Subject: added commenting/documentation guidelines --- .../en-US/Tapset_Dev_Guide.xml | 181 ++++++++++++++++++++- 1 file changed, 174 insertions(+), 7 deletions(-) diff --git a/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml b/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml index 26ea9896..555fa7e6 100644 --- a/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml +++ b/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml @@ -99,19 +99,186 @@ kernel.function("compat_do_execve") that the process ID of the new process is retrieved by calling task_pid() and passing it the task_struct pointer. In this case, the auxiliary function is an embedded C function - that's defined in the task tapset (task.stp). + defined in task.stp. + + + +probe process.create = kernel.function("copy_process").return +{ + task = $return + new_pid = task_pid(task) +} + + + + It is not advisable to write probes for every function. Most SystemTap users + will not need or understand them. Keep your tapsets simple and high-level. info from here:http://sources.redhat.com/git/?p=systemtap.git;a=blob_plain;f=tapset/DEVGUIDE + +
+ Elements of a Tapset + + + The following sections describe the most important aspects of writing a tapset. Most of + the content herein is suitable for developers who wish to contribute to + SystemTap's upstream library of tapsets. + + +
+ Tapset Files + + + Tapset files are stored in src/tapset/ + of the SystemTap GIT directory. Most tapset files are kept at that level. If you have + code that only works with a specific architecture or kernel version, you may + choose to put your tapset in the appropriate subdirectory. + + + + Installed tapsets are located in /usr/share/systemtap/tapset/ + or /usr/local/share/systemtap/tapset. + + + + Personal tapsets can be stored anywhere. However, to ensure that SystemTap + can use them, use -I tapset_directory + to specify their location when invoking stap. + +
+ +
+ Namespace + + + + Probe alias names should take the form + tapset_name.probe_name. + For example, the probe for sending a signal could be named + signal.send. + + + + Global symbol names (probes, functions, and variables) should be unique + accross all tapsets. This helps avoid namespace collisions in scripts + that use multiple tapsets. To ensure this, use tapset-specific + prefixes in your global symbols. + + + + Internal symbol names should be prefixed with an underscore + (_). + +
+ +
+ Comments and Documentation + + + All probes and functions should include comment blocks that describe + their purpose, the data they provide, and the context in which they run + (e.g. interrupt, process, etc). Use comments in areas where your intent may not + be clear from reading the code. + + + + Note that specially-formatted comments are automatically extracted from most + tapsets and included in this guide. This helps ensure that tapset contributors + can write their tapset and document it in the same place. + The specified format for documenting tapsets is as follows: + + + +/** + * probe tapset.name - Short summary of what the tapset does. + * @argument: Explanation of argument. + * @argument2: Explanation of argument2. Probes can have multiple arguments. + * + * Context: + * A brief explanation of the tapset context. + * Note that the context should only be 1 paragraph short. + * + * Text that will appear under "Description." + * + * A new paragraph that will also appear under the heading "Description". + * + * Header: + * A paragraph that will appear under the heading "Header". + **/ + + +For example: + + +/** + * probe vm.write_shared_copy- Page copy for shared page write. + * @address: The address of the shared write. + * @zero: Boolean indicating whether it is a zero page + * (can do a clear instead of a copy). + * + * Context: + * The process attempting the write. + * + * Fires when a write to a shared page requires a page copy. This is + * always preceded by a vm.shared_write. + **/ + + +To override the automatically-generated Synopsis content, use: + + + * Synopsis: + * Synopsis string + * + + +For example: + + +/** + * probe signal.handle - Fires when the signal handler is invoked + * @sig: The signal number that invoked the signal handler + * + * Synopsis: + * <programlisting>static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, + * sigset_t *oldset, struct pt_regs * regs)</programlisting> + */ + + + + It is recommended that you use the <programlisting> tag in + this instance, since overriding the Synopsis content of an entry + does not automatically form the necessary tags. + + + + For the purposes of improving the DocBook XML output of your comments, you can also + use the following XML tags in your comments: + + + + command + emphasis + programlisting + remark (tagged strings will appear in Publican beta + builds of the document. + + + +
+ +
+ -- cgit From b1f85b93f4cdc5eaad45891399c30341d4d6ce93 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 8 Mar 2009 22:28:03 -0400 Subject: Adapt to linux-next commit changing __alloc_percpu API. After linux-next commit f2a8205c, it takes two parameters again, so we autoconf for it rather than use KERNEL_VERSION ifdefs. --- buildrun.cxx | 1 + runtime/alloc.c | 25 +++---------------------- runtime/autoconf-alloc-percpu-align.c | 6 ++++++ 3 files changed, 10 insertions(+), 22 deletions(-) create mode 100644 runtime/autoconf-alloc-percpu-align.c diff --git a/buildrun.cxx b/buildrun.cxx index 2685949d..b9d648ef 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -147,6 +147,7 @@ compile_pass (systemtap_session& s) output_autoconf(s, o, "autoconf-task-uid.c", "STAPCONF_TASK_UID", NULL); 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); #if 0 /* NB: For now, the performance hit of probe_kernel_read/write (vs. our diff --git a/runtime/alloc.c b/runtime/alloc.c index 89d16612..439e8a7e 100644 --- a/runtime/alloc.c +++ b/runtime/alloc.c @@ -233,30 +233,14 @@ static void *_stp_vmalloc(unsigned long size) } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) static void *_stp_alloc_percpu(size_t size) { -#ifdef DEBUG_MEM +#ifdef STAPCONF_ALLOC_PERCPU_ALIGN void *ret = __alloc_percpu(size, 8); - if (likely(ret)) { - struct _stp_mem_entry *m = kmalloc(sizeof(struct _stp_mem_entry), STP_ALLOC_FLAGS); - if (unlikely(m == NULL)) { - free_percpu(ret); - return NULL; - } - _stp_mem_debug_percpu(m, ret, size); - _stp_allocated_memory += size * num_online_cpus(); - } - return ret; #else - return __alloc_percpu(size, 8); + void *ret = __alloc_percpu(size); #endif -} -#else -static void *_stp_alloc_percpu(size_t size) -{ #ifdef DEBUG_MEM - void *ret = __alloc_percpu(size); if (likely(ret)) { struct _stp_mem_entry *m = kmalloc(sizeof(struct _stp_mem_entry), STP_ALLOC_FLAGS); if (unlikely(m == NULL)) { @@ -266,12 +250,9 @@ static void *_stp_alloc_percpu(size_t size) _stp_mem_debug_percpu(m, ret, size); _stp_allocated_memory += size * num_online_cpus(); } - return ret; -#else - return __alloc_percpu(size); #endif + return ret; } -#endif /* LINUX_VERSION_CODE */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) #define _stp_kmalloc_node(size,node) _stp_kmalloc(size) diff --git a/runtime/autoconf-alloc-percpu-align.c b/runtime/autoconf-alloc-percpu-align.c new file mode 100644 index 00000000..158d579c --- /dev/null +++ b/runtime/autoconf-alloc-percpu-align.c @@ -0,0 +1,6 @@ +#include + +/* kernel commit f2a8205c */ +void foo (void) { + (void) __alloc_percpu(sizeof(int), 8); +} -- cgit From ee53a613180a780ea377b4f1c857aaeabcf44240 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 8 Mar 2009 22:30:03 -0400 Subject: Check pending_interrupts more frequently during unwindsyms (pass 3) processing --- translate.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/translate.cxx b/translate.cxx index c679e0f1..b2ba5c72 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4458,6 +4458,9 @@ dump_unwindsyms (Dwfl_Module *m, string modname = name; + if (pending_interrupts) + return DWARF_CB_ABORT; + // skip modules/files we're not actually interested in if (c->session.unwindsym_modules.find(modname) == c->session.unwindsym_modules.end()) return DWARF_CB_OK; -- cgit From f9355a6c0645c7efa0b7bc7894231b51b9f7e91c Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 8 Mar 2009 22:30:30 -0400 Subject: tracepoint probes: clear session derived_probe_groups pointer in ctor to avoid SEGV --- elaborate.cxx | 1 + session.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/elaborate.cxx b/elaborate.cxx index 0a00ebf2..34e6ab16 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1448,6 +1448,7 @@ systemtap_session::systemtap_session (): timer_derived_probes(0), profile_derived_probes(0), mark_derived_probes(0), + tracepoint_derived_probes(0), hrtimer_derived_probes(0), perfmon_derived_probes(0), procfs_derived_probes(0), diff --git a/session.h b/session.h index 8fa491fd..bc99385b 100644 --- a/session.h +++ b/session.h @@ -167,6 +167,8 @@ struct systemtap_session hrtimer_derived_probe_group* hrtimer_derived_probes; perfmon_derived_probe_group* perfmon_derived_probes; procfs_derived_probe_group* procfs_derived_probes; + // NB: It is very important for all of the above (and below) fields + // to be cleared in the systemtap_session ctor (elaborate.cxx). // unparser data translator_output* op; -- cgit From da573399d560fc659ee45ae041dcb2bf5b9b0bf6 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 8 Mar 2009 20:56:18 +0100 Subject: Remove extra semi-colons from defines in sdt.h. * includes/sys/sdt.h (STAP_PROBE_STRUCT_ARG): Remove ending semi-colon. (STAP_LABEL_REF): Likewise. --- includes/sys/sdt.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index 4ebf4fe0..8e27cfdb 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -13,10 +13,10 @@ #if _LP64 #define STAP_PROBE_STRUCT_ARG(arg) \ - __uint64_t arg; + __uint64_t arg #else #define STAP_PROBE_STRUCT_ARG(arg) \ - long arg __attribute__ ((aligned(8))); + long arg __attribute__ ((aligned(8))) #endif #define STAP_SENTINEL 0x31425250 @@ -36,7 +36,7 @@ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section // The goto _probe_ prevents the label from "drifting" #define STAP_LABEL_REF(probe, label) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto label; + goto label // These baroque macros are used to create a unique label #define STAP_CONCAT(a,b) a ## b -- cgit From 1d4cb9b5f957bd3825fd1f0cfa1df1c24a07164d Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 8 Mar 2009 23:23:35 +0100 Subject: Make stap_run2 count exact number of lines. * testsuite/lib/stap_run2.exp: Compare found and expected number of lines. * testsuite/systemtap.*/*.exp (result_string): Make number of lines exact. --- testsuite/lib/stap_run2.exp | 7 ++++++- testsuite/systemtap.base/ctime.exp | 3 +-- testsuite/systemtap.base/limits.exp | 3 +-- testsuite/systemtap.base/stmt_rel.exp | 3 +-- testsuite/systemtap.maps/exists.exp | 3 +-- testsuite/systemtap.maps/foreach_foreach.exp | 3 +-- testsuite/systemtap.maps/foreach_limit.exp | 3 +-- testsuite/systemtap.maps/foreach_limit2.exp | 3 +-- testsuite/systemtap.maps/ii.exp | 3 +-- testsuite/systemtap.maps/iiiiii.exp | 3 +-- testsuite/systemtap.maps/is.exp | 3 +-- testsuite/systemtap.maps/ix.exp | 3 +-- testsuite/systemtap.maps/linear.exp | 1 - testsuite/systemtap.maps/linear_empty.exp | 3 +-- testsuite/systemtap.maps/linear_large.exp | 1 - testsuite/systemtap.maps/linear_large_neg.exp | 1 - testsuite/systemtap.maps/linear_over.exp | 1 - testsuite/systemtap.maps/linear_overunder.exp | 1 - testsuite/systemtap.maps/linear_under.exp | 1 - testsuite/systemtap.maps/log.exp | 1 - testsuite/systemtap.maps/log_edge.exp | 3 +-- testsuite/systemtap.maps/si.exp | 3 +-- testsuite/systemtap.maps/ss.exp | 3 +-- testsuite/systemtap.printf/basic3.exp | 3 +-- testsuite/systemtap.printf/bin6.exp | Bin 1225 -> 1224 bytes testsuite/systemtap.printf/char1.exp | 5 ++--- testsuite/systemtap.printf/int1.exp | 3 +-- testsuite/systemtap.printf/memory1.exp | 3 +-- testsuite/systemtap.printf/print.exp | 3 +-- testsuite/systemtap.printf/print_char.exp | 3 +-- testsuite/systemtap.printf/println.exp | 3 +-- testsuite/systemtap.printf/ptr.exp | 6 ++---- testsuite/systemtap.printf/string1.exp | 3 +-- testsuite/systemtap.string/dot.exp | 3 +-- testsuite/systemtap.string/isinstr.exp | 3 +-- testsuite/systemtap.string/sprint.exp | 3 +-- testsuite/systemtap.string/strlen.exp | 3 +-- testsuite/systemtap.string/strtol.exp | 3 +-- testsuite/systemtap.string/substr.exp | 3 +-- 39 files changed, 38 insertions(+), 71 deletions(-) diff --git a/testsuite/lib/stap_run2.exp b/testsuite/lib/stap_run2.exp index 9849aefb..cb1c6615 100644 --- a/testsuite/lib/stap_run2.exp +++ b/testsuite/lib/stap_run2.exp @@ -29,5 +29,10 @@ proc stap_run2 { TEST_NAME args } { } incr n } - pass "$TEST_NAME" + if {[expr $n == [llength $expected]]} { + pass "$TEST_NAME" + } else { + fail "$TEST_NAME" + send_log "too few lines of output, got $n, expected [llength $expected]\n" + } } diff --git a/testsuite/systemtap.base/ctime.exp b/testsuite/systemtap.base/ctime.exp index f6db096a..d5ae07d5 100644 --- a/testsuite/systemtap.base/ctime.exp +++ b/testsuite/systemtap.base/ctime.exp @@ -13,6 +13,5 @@ a long, long time ago... Tue Jan 19 03:14:07 2038 far far in the future... a long, long time ago... -far far in the future... -} +far far in the future...} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.base/limits.exp b/testsuite/systemtap.base/limits.exp index c5328e8f..c04d507d 100644 --- a/testsuite/systemtap.base/limits.exp +++ b/testsuite/systemtap.base/limits.exp @@ -32,7 +32,6 @@ Minimum signed 64-bit number -9223372036854775808 0x8000000000000000 -9223372036854775808 0x8000000000000000 -9223372036854775808 0x8000000000000000 --9223372036854775808 0x8000000000000000 -} +-9223372036854775808 0x8000000000000000} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.base/stmt_rel.exp b/testsuite/systemtap.base/stmt_rel.exp index 25156d9b..be51fef9 100644 --- a/testsuite/systemtap.base/stmt_rel.exp +++ b/testsuite/systemtap.base/stmt_rel.exp @@ -3,7 +3,6 @@ set test "stmt_rel" set ::result_string {PASS bio_init PASS line number -PASS wildcard -} +PASS wildcard} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/exists.exp b/testsuite/systemtap.maps/exists.exp index ea043a6b..bbdac737 100755 --- a/testsuite/systemtap.maps/exists.exp +++ b/testsuite/systemtap.maps/exists.exp @@ -9,8 +9,7 @@ comlete list for b: [0,0] [1,10] [2,20] [3,30] [4,40] [5,50] [6,60] [7,70] [8,80 [0,0] is still there emtpy string there hello there -emtpy string still there -} +emtpy string still there} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/foreach_foreach.exp b/testsuite/systemtap.maps/foreach_foreach.exp index f79d290a..07a2d871 100644 --- a/testsuite/systemtap.maps/foreach_foreach.exp +++ b/testsuite/systemtap.maps/foreach_foreach.exp @@ -114,8 +114,7 @@ bar[21] = 9261 bar[22] = 10648 bar[23] = 12167 bar[24] = 13824 -foo[10] = 100 -} +foo[10] = 100} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/foreach_limit.exp b/testsuite/systemtap.maps/foreach_limit.exp index 97305c4b..4cc87ec8 100644 --- a/testsuite/systemtap.maps/foreach_limit.exp +++ b/testsuite/systemtap.maps/foreach_limit.exp @@ -94,8 +94,7 @@ bucket 69: 13 bucket 70: 28 loop had 71 iterations -Done. -} +Done.} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/foreach_limit2.exp b/testsuite/systemtap.maps/foreach_limit2.exp index 00696fe1..224a0aa7 100644 --- a/testsuite/systemtap.maps/foreach_limit2.exp +++ b/testsuite/systemtap.maps/foreach_limit2.exp @@ -82,8 +82,7 @@ agg_array[6]: count:2 sum:18 avg:9 min:6 max:12 loop had 4 iterations x ended up as 5 -Done. -} +Done.} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/ii.exp b/testsuite/systemtap.maps/ii.exp index f7ce95fb..1f4a972a 100644 --- a/testsuite/systemtap.maps/ii.exp +++ b/testsuite/systemtap.maps/ii.exp @@ -61,8 +61,7 @@ foo[6] = 91 foo[7] = 140 foo[8] = 204 foo[9] = 285 -foo[10] = 385 -} +foo[10] = 385} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/iiiiii.exp b/testsuite/systemtap.maps/iiiiii.exp index 3c8dbaf0..aeddbbac 100644 --- a/testsuite/systemtap.maps/iiiiii.exp +++ b/testsuite/systemtap.maps/iiiiii.exp @@ -64,8 +64,7 @@ foo[1,1,0,1,1] = 4 foo[1,1,1,0,0] = 3 foo[1,1,1,0,1] = 4 foo[1,1,1,1,0] = 4 -foo[1,1,1,1,1] = 5 -} +foo[1,1,1,1,1] = 5} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/is.exp b/testsuite/systemtap.maps/is.exp index 5dffb850..31e96e77 100644 --- a/testsuite/systemtap.maps/is.exp +++ b/testsuite/systemtap.maps/is.exp @@ -61,8 +61,7 @@ foo[6] = # 36 foo[7] = # 49 foo[8] = # 64 foo[9] = # 81 -foo[10] = # 100 -} +foo[10] = # 100} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/ix.exp b/testsuite/systemtap.maps/ix.exp index 578e8e38..11de73c1 100644 --- a/testsuite/systemtap.maps/ix.exp +++ b/testsuite/systemtap.maps/ix.exp @@ -41,8 +41,7 @@ foo[9]: count:4 sum:117 avg:29 min:-2 max:100 foo[10]: count:4 sum:118 avg:29 min:-2 max:100 Run a quick foreach without sorting... -complete sum of foo:1243 -} +complete sum of foo:1243} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/linear.exp b/testsuite/systemtap.maps/linear.exp index 5519ee11..23b5f871 100644 --- a/testsuite/systemtap.maps/linear.exp +++ b/testsuite/systemtap.maps/linear.exp @@ -38,7 +38,6 @@ value |-------------------------------------------------- count 1400 | 3 1450 | 3 1500 | 0 - } stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/linear_empty.exp b/testsuite/systemtap.maps/linear_empty.exp index 88a53a31..922ff0b9 100644 --- a/testsuite/systemtap.maps/linear_empty.exp +++ b/testsuite/systemtap.maps/linear_empty.exp @@ -1,8 +1,7 @@ # Test empty linear histogram set test "linear_empty" -set ::result_string {count=0 -} +set ::result_string {count=0} stap_run2 $srcdir/$subdir/$test.stp -w diff --git a/testsuite/systemtap.maps/linear_large.exp b/testsuite/systemtap.maps/linear_large.exp index 51df3c92..d2a03f0a 100644 --- a/testsuite/systemtap.maps/linear_large.exp +++ b/testsuite/systemtap.maps/linear_large.exp @@ -19,7 +19,6 @@ avg=1115333333 900000000 | 0 1000000000 |@@@@ 4 >1000000000 |@ 1 - } stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/linear_large_neg.exp b/testsuite/systemtap.maps/linear_large_neg.exp index bdffba7b..470414a3 100644 --- a/testsuite/systemtap.maps/linear_large_neg.exp +++ b/testsuite/systemtap.maps/linear_large_neg.exp @@ -19,7 +19,6 @@ avg=-1284615384 -200000000 | 0 -100000000 |@@ 2 0 |@ 1 - } stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/linear_over.exp b/testsuite/systemtap.maps/linear_over.exp index 5b0fafa4..25eca1e1 100644 --- a/testsuite/systemtap.maps/linear_over.exp +++ b/testsuite/systemtap.maps/linear_over.exp @@ -10,7 +10,6 @@ value |-------------------------------------------------- count 90 | 0 100 | 0 >100 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9000 - } stap_run2 $srcdir/$subdir/$test.stp -DMAXACTION=10000 diff --git a/testsuite/systemtap.maps/linear_overunder.exp b/testsuite/systemtap.maps/linear_overunder.exp index 80b74c72..e5275524 100644 --- a/testsuite/systemtap.maps/linear_overunder.exp +++ b/testsuite/systemtap.maps/linear_overunder.exp @@ -25,7 +25,6 @@ value |-------------------------------------------------- count 950 |@ 27 1000 |@ 23 >1000 |@@@@@@@ 102 - } stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/linear_under.exp b/testsuite/systemtap.maps/linear_under.exp index 8efc45be..28d24886 100644 --- a/testsuite/systemtap.maps/linear_under.exp +++ b/testsuite/systemtap.maps/linear_under.exp @@ -10,7 +10,6 @@ value |-------------------------------------------------- count <1800 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 100 1800 | 0 1900 | 0 - } stap_run2 $srcdir/$subdir/$test.stp -DMAXACTION=10000 diff --git a/testsuite/systemtap.maps/log.exp b/testsuite/systemtap.maps/log.exp index 2bc54a33..d19082b4 100644 --- a/testsuite/systemtap.maps/log.exp +++ b/testsuite/systemtap.maps/log.exp @@ -130,7 +130,6 @@ set ::result_string { value |------------------------------------- 1152921504606846976 |@ 1 2305843009213693952 |@ 1 4611686018427387904 |@ 1 - } stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/log_edge.exp b/testsuite/systemtap.maps/log_edge.exp index 051021b1..6ce546d9 100644 --- a/testsuite/systemtap.maps/log_edge.exp +++ b/testsuite/systemtap.maps/log_edge.exp @@ -43,8 +43,7 @@ value |-------------------------------------------------- count bucket 65: 1 bucket 66: 2 -bucket 67: 1 -} +bucket 67: 1} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/si.exp b/testsuite/systemtap.maps/si.exp index 600687ed..eb1b05c7 100644 --- a/testsuite/systemtap.maps/si.exp +++ b/testsuite/systemtap.maps/si.exp @@ -61,8 +61,7 @@ foo[6] = 91 foo[7] = 140 foo[8] = 204 foo[9] = 285 -foo[10] = 385 -} +foo[10] = 385} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.maps/ss.exp b/testsuite/systemtap.maps/ss.exp index 548a888e..9978ead0 100644 --- a/testsuite/systemtap.maps/ss.exp +++ b/testsuite/systemtap.maps/ss.exp @@ -61,7 +61,6 @@ foo[6] = # 36 foo[7] = # 49 foo[8] = # 64 foo[9] = # 81 -foo[10] = # 100 -} +foo[10] = # 100} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/basic3.exp b/testsuite/systemtap.printf/basic3.exp index e3beb9ed..5c4f7e79 100644 --- a/testsuite/systemtap.printf/basic3.exp +++ b/testsuite/systemtap.printf/basic3.exp @@ -1,5 +1,4 @@ set test "basic3" set ::result_string {Hello -World -} +World} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/bin6.exp b/testsuite/systemtap.printf/bin6.exp index 0de41e78..4c5e7f2b 100644 Binary files a/testsuite/systemtap.printf/bin6.exp and b/testsuite/systemtap.printf/bin6.exp differ diff --git a/testsuite/systemtap.printf/char1.exp b/testsuite/systemtap.printf/char1.exp index 0e9232e9..35aa479f 100644 --- a/testsuite/systemtap.printf/char1.exp +++ b/testsuite/systemtap.printf/char1.exp @@ -1,4 +1,3 @@ set test "char1" -set ::result_string {stap -} -stap_run2 $srcdir/$subdir/$test.stp \ No newline at end of file +set ::result_string {stap} +stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/int1.exp b/testsuite/systemtap.printf/int1.exp index bb30b4f3..b308848c 100644 --- a/testsuite/systemtap.printf/int1.exp +++ b/testsuite/systemtap.printf/int1.exp @@ -19,6 +19,5 @@ set ::result_string {1,10,9000000000000,-1,-1024 1,12,202757163310000,1777777777777777777777,1777777777777777776000 1,12,202757163310000,1777777777777777777777,1777777777777777776000 1, 12, 202757163310000,1777777777777777777777,1777777777777777776000 -0000000000000001,0000000000000012,0202757163310000,1777777777777777777777,1777777777777777776000 -} +0000000000000001,0000000000000012,0202757163310000,1777777777777777777777,1777777777777777776000} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/memory1.exp b/testsuite/systemtap.printf/memory1.exp index 7b55a3d7..c5f03610 100644 --- a/testsuite/systemtap.printf/memory1.exp +++ b/testsuite/systemtap.printf/memory1.exp @@ -1,4 +1,3 @@ set test "memory1" -set ::result_string {Test passed -} +set ::result_string {Test passed} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/print.exp b/testsuite/systemtap.printf/print.exp index 3a4de529..151de10d 100644 --- a/testsuite/systemtap.printf/print.exp +++ b/testsuite/systemtap.printf/print.exp @@ -13,6 +13,5 @@ foo99 888 123456789 hello999 -999hello -} +999hello} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/print_char.exp b/testsuite/systemtap.printf/print_char.exp index bab056dd..a9d63be6 100644 --- a/testsuite/systemtap.printf/print_char.exp +++ b/testsuite/systemtap.printf/print_char.exp @@ -1,5 +1,4 @@ set test "print_char" set ::result_string {ABC -ABCDEFGHIJKLMNOPQRSTUVWXYZ -} +ABCDEFGHIJKLMNOPQRSTUVWXYZ} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/println.exp b/testsuite/systemtap.printf/println.exp index 8deba53f..fcbe0c82 100644 --- a/testsuite/systemtap.printf/println.exp +++ b/testsuite/systemtap.printf/println.exp @@ -13,6 +13,5 @@ foo99 99foo 123456789 hello999 -999hello -} +999hello} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/ptr.exp b/testsuite/systemtap.printf/ptr.exp index f25a7a02..3eb412a7 100644 --- a/testsuite/systemtap.printf/ptr.exp +++ b/testsuite/systemtap.printf/ptr.exp @@ -29,8 +29,7 @@ if {$::tcl_platform(wordSize) == 8} { 0x000001X 0x12345678X 0x12345678abcdef00X -0x12345678X -" +0x12345678X" } else { set ::result_string "0x00000000 0x00000001 @@ -60,7 +59,6 @@ if {$::tcl_platform(wordSize) == 8} { 0x000001X 0x12345678X 0xabcdef00X -0x12345678X -" +0x12345678X" } stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.printf/string1.exp b/testsuite/systemtap.printf/string1.exp index aee0b71a..7c94d645 100644 --- a/testsuite/systemtap.printf/string1.exp +++ b/testsuite/systemtap.printf/string1.exp @@ -1,6 +1,5 @@ set test "string1" set ::result_string {The string is Foobar!XYZZY -XYZZYFoobar!XYZZYFoobar! -} +XYZZYFoobar!XYZZYFoobar!} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.string/dot.exp b/testsuite/systemtap.string/dot.exp index b1d38172..14f329db 100644 --- a/testsuite/systemtap.string/dot.exp +++ b/testsuite/systemtap.string/dot.exp @@ -5,6 +5,5 @@ helloworld 0 100 -42 -66 -} +66} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.string/isinstr.exp b/testsuite/systemtap.string/isinstr.exp index 986043e8..ed0474de 100644 --- a/testsuite/systemtap.string/isinstr.exp +++ b/testsuite/systemtap.string/isinstr.exp @@ -1,6 +1,5 @@ set test "isinstr" set ::result_string {"foo" is in "abcfoobad" "foo" is NOT in "abcdefg" -"" is in "" -} +"" is in ""} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.string/sprint.exp b/testsuite/systemtap.string/sprint.exp index c8f9826a..b4f0b453 100644 --- a/testsuite/systemtap.string/sprint.exp +++ b/testsuite/systemtap.string/sprint.exp @@ -3,6 +3,5 @@ set ::result_string {helloworld helloworld EQUAL EQUAL -hello-world helloworld FOO helloworld -} +hello-world helloworld FOO helloworld} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.string/strlen.exp b/testsuite/systemtap.string/strlen.exp index 40c790fe..b93564ef 100644 --- a/testsuite/systemtap.string/strlen.exp +++ b/testsuite/systemtap.string/strlen.exp @@ -2,6 +2,5 @@ set test "strlen" set ::result_string {strlen("") = 0 strlen("1") = 1 strlen("0123456789") = 10 -strlen("012345678901234567890123456789012345678901234567890123456789012") = 63 -} +strlen("012345678901234567890123456789012345678901234567890123456789012") = 63} stap_run2 $srcdir/$subdir/$test.stp -DMAXSTRINGLEN=64 diff --git a/testsuite/systemtap.string/strtol.exp b/testsuite/systemtap.string/strtol.exp index 12d63f0d..25cc21a0 100644 --- a/testsuite/systemtap.string/strtol.exp +++ b/testsuite/systemtap.string/strtol.exp @@ -10,6 +10,5 @@ set ::result_string {1 1000 4096 512 -8 -0} +8} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.string/substr.exp b/testsuite/systemtap.string/substr.exp index c9884935..5f1b662b 100644 --- a/testsuite/systemtap.string/substr.exp +++ b/testsuite/systemtap.string/substr.exp @@ -13,6 +13,5 @@ set ::result_string {Hello World! 12,1: 0,10: Hello Worl 0,100: Hello World! -0,100000: Hello World! -} +0,100000: Hello World!} stap_run2 $srcdir/$subdir/$test.stp -- cgit From 048cb0db9b075e3632e2372a754a68801c3e5ae9 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 8 Mar 2009 23:49:05 +0100 Subject: Only use plain C comments in sdt.h. includes/sys/sdt.h: Replace c++ comments with plain C comments. --- includes/sys/sdt.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index 8e27cfdb..46f259f5 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -1,10 +1,11 @@ -// Copyright (C) 2005-2009 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. +/* Copyright (C) 2005-2009 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. +*/ #ifndef _SYS_SDT_H #define _SYS_SDT_H 1 @@ -33,15 +34,15 @@ static char probe ## _ ## probe_name [strlen(#probe)+1] \ = #probe; \ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc}; -// The goto _probe_ prevents the label from "drifting" +/* The goto _probe_ prevents the label from "drifting" */ #define STAP_LABEL_REF(probe, label) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ goto label -// These baroque macros are used to create a unique label +/* These baroque macros are used to create a unique label */ #define STAP_CONCAT(a,b) a ## b #define STAP_LABEL_PREFIX(p) _stapprobe1_ ## p -// __COUNTER__ is not present in gcc 4.1 +/* __COUNTER__ is not present in gcc 4.1 */ #if __GNUC__ == 4 && __GNUC_MINOR__ >= 3 #define STAP_COUNTER STAP_CONCAT(__,COUNTER__) #else -- cgit From 8e9f87b2c6e8e75e0f57f41f14879f803ec95545 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 9 Mar 2009 00:15:23 +0100 Subject: Put statements after declaration in sdt macros. Fix arg10 assignment. * includes/sys/sdt.h: Assign args, after declaration. --- includes/sys/sdt.h | 225 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 140 insertions(+), 85 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index 46f259f5..4eb54250 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -59,128 +59,183 @@ label: \ #define STAP_PROBE1_(probe,label,parm1) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ -label: \ - asm volatile ("nop /* %0 */" :: "X"( arg1)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ +label: \ + asm volatile ("nop /* %0 */" :: "X"( arg1)); } while (0) #define STAP_PROBE2_(probe,label,parm1,parm2) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ -label: \ - asm volatile ("nop /* %0 %1 */" :: "X"(arg1), "X"(arg2)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ +label: \ + asm volatile ("nop /* %0 %1 */" :: "X"(arg1), "X"(arg2)); } while (0) #define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ -label: \ - asm volatile ("nop /* %0 %1 %2 */" :: "X"(arg1), "X"(arg2), "X"(arg3)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ +label: \ + asm volatile ("nop /* %0 %1 %2 */" :: "X"(arg1), "X"(arg2), "X"(arg3)); } while (0) #define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ do { \ - 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; \ -label: \ - asm volatile ("nop /* %0 %1 %2 %3 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ + arg4 = parm4; \ +label: \ + asm volatile ("nop /* %0 %1 %2 %3 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4)); } while (0) #define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ do { \ - 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; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ -label: \ - asm volatile ("nop /* %0 %1 %2 %3 %4 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ + arg4 = parm4; \ + arg5 = parm5; \ +label: \ + asm volatile ("nop /* %0 %1 %2 %3 %4 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5)); } while (0) #define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \ do { \ - 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; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ -label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ + volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ + arg4 = parm4; \ + arg5 = parm5; \ + arg6 = parm6; \ +label: \ + asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6)); } while (0) #define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ do { \ - 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; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ -label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ + volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ + volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ + arg4 = parm4; \ + arg5 = parm5; \ + arg6 = parm6; \ + arg7 = parm7; \ +label: \ + asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7)); } while (0) #define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ do { \ - 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; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ - volatile typeof((parm8)) arg8 __attribute__ ((unused)) = parm8; \ -label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ + volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ + volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ + volatile typeof((parm8)) arg8 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ + arg4 = parm4; \ + arg5 = parm5; \ + arg6 = parm6; \ + arg7 = parm7; \ + arg8 = parm8; \ +label: \ + asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8)); } while (0) #define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ do { \ - 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; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - 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; \ -label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ + volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ + volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ + volatile typeof((parm8)) arg8 __attribute__ ((unused)); \ + volatile typeof((parm9)) arg9 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ + arg4 = parm4; \ + arg5 = parm5; \ + arg6 = parm6; \ + arg7 = parm7; \ + arg8 = parm8; \ + arg9 = parm9; \ +label: \ + asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9)); } while (0) #define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ do { \ - 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; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - 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((parm10)) arg10 __attribute__ ((unused)) = parm9; \ -label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9), "X"(arg10)); \ + volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ + volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ + volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ + volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ + volatile typeof((parm8)) arg8 __attribute__ ((unused)); \ + volatile typeof((parm9)) arg9 __attribute__ ((unused)); \ + volatile typeof((parm10)) arg10 __attribute__ ((unused)); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ + arg1 = parm1; \ + arg2 = parm2; \ + arg3 = parm3; \ + arg4 = parm4; \ + arg5 = parm5; \ + arg6 = parm6; \ + arg7 = parm7; \ + arg8 = parm8; \ + arg9 = parm9; \ + arg10 = parm10; \ +label: \ + asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9), "X"(arg10)); } while (0) #define STAP_PROBE(provider,probe) \ STAP_PROBE_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER)) -- cgit From 68b7cb6fdb08707ae48c8f558278eee3b2ae5154 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 9 Mar 2009 10:40:08 +0100 Subject: Include sys/types.h in sdt.h for __uint64_t. * includes/sys/sdt.h: Add #include . --- includes/sys/sdt.h | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index 4eb54250..ba927093 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -11,6 +11,7 @@ #define _SYS_SDT_H 1 #include +#include #if _LP64 #define STAP_PROBE_STRUCT_ARG(arg) \ -- cgit From c18b2f69080486db2b2591308ace672bdb1fe123 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 9 Mar 2009 11:03:55 +0100 Subject: Add new sdt.exp testcase. * testsuite/systemtap.base/sdt.exp: New test file. * testsuite/systemtap.base/sdt.stp: Likewise. * testsuite/systemtap.base/sdt.c: Likewise. --- testsuite/systemtap.base/sdt.c | 69 ++++++++++++++++++++++++++++++++++++++++ testsuite/systemtap.base/sdt.exp | 36 +++++++++++++++++++++ testsuite/systemtap.base/sdt.stp | 49 ++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 testsuite/systemtap.base/sdt.c create mode 100644 testsuite/systemtap.base/sdt.exp create mode 100644 testsuite/systemtap.base/sdt.stp diff --git a/testsuite/systemtap.base/sdt.c b/testsuite/systemtap.base/sdt.c new file mode 100644 index 00000000..46f68664 --- /dev/null +++ b/testsuite/systemtap.base/sdt.c @@ -0,0 +1,69 @@ +#include "sdt.h" /* Really , but pick current source version. */ + +static void call1(int a) +{ + STAP_PROBE1(test, mark_a, a); +} + +static void call2(int a, int b) +{ + STAP_PROBE2(test, mark_b, a, b); +} + +static void call3(int a, int b, int c) +{ + STAP_PROBE3(test, mark_c, a, b, c); +} + +static void call4(int a, int b, int c, int d) +{ + STAP_PROBE4(test, mark_d, a, b, c, d); +} + +static void call5(int a, int b, int c, int d, int e) +{ + STAP_PROBE5(test, mark_e, a, b, c, d, e); +} + +static void call6(int a, int b, int c, int d, int e, int f) +{ + STAP_PROBE6(test, mark_f, a, b, c, d, e, f); +} + +static void call7(int a, int b, int c, int d, int e, int f, int g) +{ + STAP_PROBE7(test, mark_g, a, b, c, d, e, f, g); +} + +static void call8(int a, int b, int c, int d, int e, int f, int g, int h) +{ + STAP_PROBE8(test, mark_h, a, b, c, d, e, f, g, h); +} + +static void call9(int a, int b, int c, int d, int e, int f, int g, int h, int i) +{ + STAP_PROBE9(test, mark_i, a, b, c, d, e, f, g, h, i); +} + +static void call10(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) +{ + STAP_PROBE10(test, mark_j, a, b, c, d, e, f, g, h, i, j); +} + +int +main (int argc, char **argv) +{ + int a, b, c, d, e, f, g, h, i, j; + a = 1; b = 2; c = 3; d = 4; e = 5; f = 6; g = 7; h = 8; i = 9; j = 10; + call1(a); + call2(a, b); + call3(a, b, c); + call4(a, b, c, d); + call5(a, b, c, d, e); + call6(a, b, c, d, e, f); + call7(a, b, c, d, e, f, g); + call8(a, b, c, d, e, f, g, h); + call9(a, b, c, d, e, f, g, h, i); + call10(a, b, c, d, e, f, g, h, i, j); + return 0; +} diff --git a/testsuite/systemtap.base/sdt.exp b/testsuite/systemtap.base/sdt.exp new file mode 100644 index 00000000..ce6b9a71 --- /dev/null +++ b/testsuite/systemtap.base/sdt.exp @@ -0,0 +1,36 @@ +set test "sdt" +set ::result_string {1 +1 2 +1 2 3 +1 2 3 4 +1 2 3 4 5 +1 2 3 4 5 6 +1 2 3 4 5 6 7 +1 2 3 4 5 6 7 8 +1 2 3 4 5 6 7 8 9 +1 2 3 4 5 6 7 8 9 10} + +set test_flags "additional_flags=-g" +set test_flags "$test_flags additional_flags=-I$srcdir/../includes/sys" +set test_flags "$test_flags additional_flags=-std=gnu89" +set test_flags "$test_flags additional_flags=-Wall" +set test_flags "$test_flags additional_flags=-Wdeclaration-after-statement" +set test_flags "$test_flags additional_flags=-Werror" +set res [target_compile $srcdir/$subdir/$test.c $test.prog executable $test_flags] +if { $res != "" } { + verbose "target_compile failed: $res" 2 + fail "compiling $test.c" + return +} else { + pass "compiling $test.c" +} + +# Currently fails for any mark probe with more than 4 arguments. +# FIXME - PR s/false/{![installtest_p]/ +if (0) { + stap_run2 $srcdir/$subdir/$test.stp -c ./$test.prog +} else { + untested "$test" +} + +catch {exec rm -f $test.prog} diff --git a/testsuite/systemtap.base/sdt.stp b/testsuite/systemtap.base/sdt.stp new file mode 100644 index 00000000..d2deb557 --- /dev/null +++ b/testsuite/systemtap.base/sdt.stp @@ -0,0 +1,49 @@ +probe process("sdt.prog").mark("mark_a") +{ + printf("%d\n", $arg1); +} + +probe process("sdt.prog").mark("mark_b") +{ + printf("%d %d\n", $arg1, $arg2); +} + +probe process("sdt.prog").mark("mark_c") +{ + printf("%d %d %d\n", $arg1, $arg2, $arg3); +} + +probe process("sdt.prog").mark("mark_d") +{ + printf("%d %d %d %d\n", $arg1, $arg2, $arg3, $arg4); +} + +probe process("sdt.prog").mark("mark_e") +{ + printf("%d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5); +} + +probe process("sdt.prog").mark("mark_f") +{ + printf("%d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6); +} + +probe process("sdt.prog").mark("mark_g") +{ + printf("%d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7); +} + +probe process("sdt.prog").mark("mark_h") +{ + printf("%d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7, arg8); +} + +probe process("sdt.prog").mark("mark_i") +{ + printf("%d %d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7, arg8, arg9); +} + +probe process("sdt.prog").mark("mark_j") +{ + printf("%d %d %d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7, arg8, arg9, arg10); +} -- cgit From df5d1ba4cd009ba39f1bbe9466ae0f1a4e250a67 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 9 Mar 2009 12:55:46 +0100 Subject: Add PR9935 number to sdt.exp disabled test. --- testsuite/systemtap.base/sdt.exp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/systemtap.base/sdt.exp b/testsuite/systemtap.base/sdt.exp index ce6b9a71..71fe9dac 100644 --- a/testsuite/systemtap.base/sdt.exp +++ b/testsuite/systemtap.base/sdt.exp @@ -26,7 +26,7 @@ if { $res != "" } { } # Currently fails for any mark probe with more than 4 arguments. -# FIXME - PR s/false/{![installtest_p]/ +# FIXME - PR9935 s/(0)/{![installtest_p]}/ if (0) { stap_run2 $srcdir/$subdir/$test.stp -c ./$test.prog } else { -- cgit From fd0143174d30451c99fde61d719d2eaa53730ff6 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 9 Mar 2009 16:48:13 +0100 Subject: PR9935. Fixed stap script typos. arg[5-10] -> $arg[5-10]. * testsuite/systemtap.base/sdt.exp: Enable stap_run2 when installtest_p. * testsuite/systemtap.base/sdt.stp: Fixed all arg to $arg typos. --- testsuite/systemtap.base/sdt.exp | 4 +--- testsuite/systemtap.base/sdt.stp | 12 ++++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/testsuite/systemtap.base/sdt.exp b/testsuite/systemtap.base/sdt.exp index 71fe9dac..9c40bf4d 100644 --- a/testsuite/systemtap.base/sdt.exp +++ b/testsuite/systemtap.base/sdt.exp @@ -25,9 +25,7 @@ if { $res != "" } { pass "compiling $test.c" } -# Currently fails for any mark probe with more than 4 arguments. -# FIXME - PR9935 s/(0)/{![installtest_p]}/ -if (0) { +if {[installtest_p]} { stap_run2 $srcdir/$subdir/$test.stp -c ./$test.prog } else { untested "$test" diff --git a/testsuite/systemtap.base/sdt.stp b/testsuite/systemtap.base/sdt.stp index d2deb557..1f075bca 100644 --- a/testsuite/systemtap.base/sdt.stp +++ b/testsuite/systemtap.base/sdt.stp @@ -20,30 +20,30 @@ probe process("sdt.prog").mark("mark_d") probe process("sdt.prog").mark("mark_e") { - printf("%d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5); + printf("%d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, $arg5); } probe process("sdt.prog").mark("mark_f") { - printf("%d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6); + printf("%d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, $arg5, $arg6); } probe process("sdt.prog").mark("mark_g") { - printf("%d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7); + printf("%d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7); } probe process("sdt.prog").mark("mark_h") { - printf("%d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7, arg8); + printf("%d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8); } probe process("sdt.prog").mark("mark_i") { - printf("%d %d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7, arg8, arg9); + printf("%d %d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9); } probe process("sdt.prog").mark("mark_j") { - printf("%d %d %d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, arg5, arg6, arg7, arg8, arg9, arg10); + printf("%d %d %d %d %d %d %d %d %d %d\n", $arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9, $arg10); } -- cgit From ba4e4ff4ba0206bb707538bbfb5e07d3cca33d5b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 9 Mar 2009 14:40:24 -0700 Subject: Add safety checks to _stp_get_register_by_offset() This now checks that CONTEXT->regs actually exists, and that the requested offset is in the correct range. --- tapset/i686/registers.stp | 10 ++++++++++ tapset/ppc64/registers.stp | 10 ++++++++++ tapset/s390x/registers.stp | 12 +++++++++++- tapset/x86_64/registers.stp | 10 ++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/tapset/i686/registers.stp b/tapset/i686/registers.stp index b9eaba5b..a6e5694e 100644 --- a/tapset/i686/registers.stp +++ b/tapset/i686/registers.stp @@ -26,6 +26,16 @@ function _stp_register_regs() { function _stp_get_register_by_offset:long (offset:long) %{ /* pure */ long value; + if (!CONTEXT->regs) { + CONTEXT->last_error = "No registers available in this context"; + return; + } + if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(long)) { + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "Bad register offset: %lld", THIS->offset); + CONTEXT->last_error = CONTEXT->error_buffer; + return; + } memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); THIS->__retvalue = value; %} diff --git a/tapset/ppc64/registers.stp b/tapset/ppc64/registers.stp index 6a8ae279..e5decd81 100644 --- a/tapset/ppc64/registers.stp +++ b/tapset/ppc64/registers.stp @@ -64,6 +64,16 @@ function probing_32bit_app() %{ /* pure */ function _stp_get_register_by_offset:long (offset:long) %{ /* pure */ long value; + if (!CONTEXT->regs) { + CONTEXT->last_error = "No registers available in this context"; + return; + } + if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(long)) { + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "Bad register offset: %lld", THIS->offset); + CONTEXT->last_error = CONTEXT->error_buffer; + return; + } memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); THIS->__retvalue = value; %} diff --git a/tapset/s390x/registers.stp b/tapset/s390x/registers.stp index 84e28348..37218d14 100644 --- a/tapset/s390x/registers.stp +++ b/tapset/s390x/registers.stp @@ -56,8 +56,18 @@ function _stp_probing_kernel: long () %{ /* pure */ function _stp_get_register_by_offset:long (offset:long) %{ /* pure */ long value; + if (!CONTEXT->regs) { + CONTEXT->last_error = "No registers available in this context"; + return; + } + if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(unsigned short)) { + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "Bad register offset: %lld", THIS->offset); + CONTEXT->last_error = CONTEXT->error_buffer; + return; + } - if (THIS->offset <= 152) + if (THIS->offset < sizeof(struct pt_regs) - 2 * sizeof(unsigned short)) memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); else { diff --git a/tapset/x86_64/registers.stp b/tapset/x86_64/registers.stp index dd5eefb0..2e21f3eb 100644 --- a/tapset/x86_64/registers.stp +++ b/tapset/x86_64/registers.stp @@ -40,6 +40,16 @@ function _stp_register_regs() { function _stp_get_register_by_offset:long (offset:long) %{ /* pure */ long value; + if (!CONTEXT->regs) { + CONTEXT->last_error = "No registers available in this context"; + return; + } + if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(long)) { + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "Bad register offset: %lld", THIS->offset); + CONTEXT->last_error = CONTEXT->error_buffer; + return; + } memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); THIS->__retvalue = value; %} -- cgit From c3add01f692e698995a62c13e154bab35d9212df Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 9 Mar 2009 17:23:05 -0700 Subject: Update location of c->probe_point reset The probe_point clear was nested in the overload processing code, I believe accidentally. This just makes it always cleared on probe exit. --- tapsets.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tapsets.cxx b/tapsets.cxx index d99eebe2..18bd75f5 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -300,7 +300,6 @@ common_probe_entryfn_epilogue (translator_output* o, o->newline() << "c->cycles_base = cycles_atend;"; o->newline() << "c->cycles_sum = 0;"; - o->newline() << "c->probe_point = 0;"; // vacated o->newline(-1) << "}"; o->newline(-1) << "}"; o->newline() << "#endif"; @@ -309,6 +308,7 @@ common_probe_entryfn_epilogue (translator_output* o, o->newline(-1) << "}"; o->newline() << "#endif"; + o->newline() << "c->probe_point = 0;"; // vacated o->newline() << "if (unlikely (c->last_error && c->last_error[0])) {"; o->newline(1) << "if (c->last_stmt != NULL)"; o->newline(1) << "_stp_softerror (\"%s near %s\", c->last_error, c->last_stmt);"; -- cgit From 046e719028ae6b037fb7342b7d0764985bfaf408 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 9 Mar 2009 17:37:14 -0700 Subject: Add tracepoint $$parms alias for $$vars For parity with the DWARF probes, this makes tracepoints also define $$parms, which has the same value as $$vars (since tracepoints are missing the concept of $$locals). --- stapprobes.5.in | 2 +- tapsets.cxx | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/stapprobes.5.in b/stapprobes.5.in index 0daeb973..70d045c4 100644 --- a/stapprobes.5.in +++ b/stapprobes.5.in @@ -582,7 +582,7 @@ The name of the tracepoint is available in .BR $$name , and a string of name=value pairs for all parameters of the tracepoint is available in -.BR $$vars . +.BR $$vars " or " $$parms . .SS PERFORMANCE MONITORING HARDWARE diff --git a/tapsets.cxx b/tapsets.cxx index 18bd75f5..b748a487 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9271,7 +9271,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) stringstream alternatives; for (unsigned i = 0; i < args.size(); ++i) alternatives << " $" << args[i].name; - alternatives << " $$name $$vars"; + alternatives << " $$name $$parms $$vars"; // We hope that this value ends up not being referenced after all, so it // can be optimized out quietly. @@ -9457,7 +9457,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session provide (n); } - else if (e->base_name == "$$vars") + else if (e->base_name == "$$vars" || e->base_name == "$$parms") { target_symbol *tsym = new target_symbol; print_format* pf = new print_format; @@ -9505,7 +9505,9 @@ tracepoint_var_expanding_visitor::visit_target_symbol (target_symbol* e) { assert(e->base_name.size() > 0 && e->base_name[0] == '$'); - if (e->base_name == "$$name" || e->base_name == "$$vars") + if (e->base_name == "$$name" || + e->base_name == "$$parms" || + e->base_name == "$$vars") visit_target_symbol_context (e); else visit_target_symbol_arg (e); -- cgit From d82227a838a0ac11827a4047dc33b9e38eefc3b7 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Mon, 9 Mar 2009 21:27:30 -0400 Subject: Use alternate keywords for sdt.h * include/sys/sdt.h: Initialize args when declaring. Use alternate keywords. --- includes/sys/sdt.h | 228 +++++++++++++++--------------------- testsuite/systemtap.base/labels.exp | 2 +- 2 files changed, 93 insertions(+), 137 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index ba927093..ea1da719 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -18,7 +18,7 @@ __uint64_t arg #else #define STAP_PROBE_STRUCT_ARG(arg) \ - long arg __attribute__ ((aligned(8))) + long arg __attribute__ ((aligned(8))) #endif #define STAP_SENTINEL 0x31425250 @@ -33,12 +33,12 @@ struct _probe_ ## probe \ 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}; +__extension__ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc}; /* The goto _probe_ prevents the label from "drifting" */ #define STAP_LABEL_REF(probe, label) \ if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto label + goto label; /* These baroque macros are used to create a unique label */ #define STAP_CONCAT(a,b) a ## b @@ -53,190 +53,146 @@ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section #define STAP_PROBE_(probe,label) \ do { \ -label: \ - asm volatile ("nop"); \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label);} while (0) + STAP_LABEL_REF(probe,label); \ +label: \ + __asm__ volatile ("nop");} \ + while (0) #define STAP_PROBE1_(probe,label,parm1) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ + volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop /* %0 */" :: "X"( arg1)); } while (0) + __asm__ volatile ("nop /* %0 */" :: "X"( arg1));} \ +while (0) #define STAP_PROBE2_(probe,label,parm1,parm2) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ + volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop /* %0 %1 */" :: "X"(arg1), "X"(arg2)); } while (0) + __asm__ volatile ("nop /* %0 %1 */" :: "X"(arg1), "X"(arg2)); \ +} while (0) #define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ + volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ + volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ + volatile __typeof__((parm3)) arg3 __attribute__ ((unused)) = parm3; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop /* %0 %1 %2 */" :: "X"(arg1), "X"(arg2), "X"(arg3)); } while (0) + __asm__ volatile ("nop /* %0 %1 %2 */" :: "X"(arg1), "X"(arg2), "X"(arg3)); \ +} while (0) #define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ + 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_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ - arg4 = parm4; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop /* %0 %1 %2 %3 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4)); } while (0) + __asm__ volatile ("nop /* %0 %1 %2 %3 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4)); \ +} while (0) #define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ + 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; \ + volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ - arg4 = parm4; \ - arg5 = parm5; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop /* %0 %1 %2 %3 %4 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5)); } while (0) + __asm__ volatile ("nop /* %0 %1 %2 %3 %4 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5)); \ +} while (0) #define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ + 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; \ + volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ + volatile __typeof__((parm6)) arg6 __attribute__ ((unused)) = parm6; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ - arg4 = parm4; \ - arg5 = parm5; \ - arg6 = parm6; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6)); } while (0) + __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6)); \ +} while (0) #define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ + 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; \ + volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ + volatile __typeof__((parm6)) arg6 __attribute__ ((unused)) = parm6; \ + volatile __typeof__((parm7)) arg7 __attribute__ ((unused)) = parm7; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ - arg4 = parm4; \ - arg5 = parm5; \ - arg6 = parm6; \ - arg7 = parm7; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7)); } while (0) + __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7)); \ +} while (0) #define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ - volatile typeof((parm8)) arg8 __attribute__ ((unused)); \ + 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; \ + volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ + volatile __typeof__((parm6)) arg6 __attribute__ ((unused)) = parm6; \ + volatile __typeof__((parm7)) arg7 __attribute__ ((unused)) = parm7; \ + volatile __typeof__((parm8)) arg8 __attribute__ ((unused)) = parm8; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ - arg4 = parm4; \ - arg5 = parm5; \ - arg6 = parm6; \ - arg7 = parm7; \ - arg8 = parm8; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8)); } while (0) + __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8)); \ +} while (0) #define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ - volatile typeof((parm8)) arg8 __attribute__ ((unused)); \ - volatile typeof((parm9)) arg9 __attribute__ ((unused)); \ + 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; \ + volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ + 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; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ - arg4 = parm4; \ - arg5 = parm5; \ - arg6 = parm6; \ - arg7 = parm7; \ - arg8 = parm8; \ - arg9 = parm9; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9)); } while (0) + __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9)); \ +} while (0) #define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ do { \ - volatile typeof((parm1)) arg1 __attribute__ ((unused)); \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)); \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)); \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)); \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)); \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)); \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)); \ - volatile typeof((parm8)) arg8 __attribute__ ((unused)); \ - volatile typeof((parm9)) arg9 __attribute__ ((unused)); \ - volatile typeof((parm10)) arg10 __attribute__ ((unused)); \ + 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; \ + volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ + 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__((parm10)) arg10 __attribute__ ((unused)) = parm10; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ - arg1 = parm1; \ - arg2 = parm2; \ - arg3 = parm3; \ - arg4 = parm4; \ - arg5 = parm5; \ - arg6 = parm6; \ - arg7 = parm7; \ - arg8 = parm8; \ - arg9 = parm9; \ - arg10 = parm10; \ + STAP_LABEL_REF(probe,label); \ label: \ - asm volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9), "X"(arg10)); } while (0) + __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9), "X"(arg10)); \ +} while (0) #define STAP_PROBE(provider,probe) \ STAP_PROBE_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER)) diff --git a/testsuite/systemtap.base/labels.exp b/testsuite/systemtap.base/labels.exp index 1b538dbb..6db81c54 100644 --- a/testsuite/systemtap.base/labels.exp +++ b/testsuite/systemtap.base/labels.exp @@ -147,4 +147,4 @@ expect { if {$nomatch == 0} { pass "$test so .statement" } { fail "$test so .statement" } -# catch {exec rm -f $label_srcpath $label_stppath $label_exepath} +catch {exec rm -f $label_srcpath $label_stppath $label_exepath $label_shpath $label_sopath} -- cgit From be184deb8fa8f58ebe693c2483b9012daff6137d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 9 Mar 2009 19:10:20 -0700 Subject: Fix a few typos in stap(1) --- stap.1.in | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/stap.1.in b/stap.1.in index 6e4df024..3a0823e6 100644 --- a/stap.1.in +++ b/stap.1.in @@ -1039,10 +1039,10 @@ Maximum number of soft errors before an exit is triggered, default 0, which means that the first error will exit the script. .TP MAXSKIPPED -.TP Maximum number of skipped probes before an exit is triggered, default 100. Running systemtap with \-t (timing) mode gives more details about skipped probes. +.TP MINSTACKSPACE Minimum number of free kernel stack bytes required in order to run a probe handler, default 1024. This number should be large enough @@ -1053,8 +1053,9 @@ Maximum number of concurrently armed user-space probes (uprobes), default 100 times the number of user-space probe points named in the script. This pool is large because individual uprobe objects are allocated for each process for each script-level probe. + .PP -Multipule scripts can write data into a relay buffer concurrently. A host +Multiple scripts can write data into a relay buffer concurrently. A host script provides an interface for accessing its relay buffer to guest scripts. Then, the output of the guests are merged into the output of the host. To run a script as a host, execute stap with @@ -1096,16 +1097,16 @@ using symbols read from vmlinux and/or the modules in /lib/modules. Systemtap can also read the kernel symbol table from a text file such as /boot/System.map or /proc/kallsyms. See the -.B \-\--kelf +.B \-\-kelf and -.B \-\--kmap +.B \-\-kmap options. .PP If systemtap finds relevant debugging information, it will use it even if you specify -.B \-\--kelf +.B \-\-kelf or -.BR \-\--kmap . +.BR \-\-kmap . .PP Without debugging information, systemtap cannot support the following types of language constructs: -- cgit From e0a17418b9d12e2a95dc345e95080ba31a41677f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 9 Mar 2009 19:12:02 -0700 Subject: Let -DINTERRUPTIBLE=0 mask interrupts in probes Some time ago we loosened up the code for all probe types to allow interrupts during the handler. However, when probing something like kernel.trace("*"), you get a mix of probes in and out of the interrupt path, and it becomes much more common to have probes skipped due to interrupt reentrancy. The common_probe_entryfn_prologue and common_probe_entryfn_epilogue functions had an interruptible flag, but this was no longer used anywhere. I removed this flag, but then reused the logic to check an INTERRUPTIBLE macro instead. Now users can use -DINTERRUPTIBLE=0 to prevent interrupt reentrancy in their script, at the cost of a bit more overhead to toggle the interrupt mask. --- stap.1.in | 11 +++++++++++ tapsets.cxx | 51 +++++++++++++++++++++++++++------------------------ translate.cxx | 3 +++ 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/stap.1.in b/stap.1.in index 3a0823e6..546bebb8 100644 --- a/stap.1.in +++ b/stap.1.in @@ -1054,6 +1054,17 @@ Maximum number of concurrently armed user-space probes (uprobes), default pool is large because individual uprobe objects are allocated for each process for each script-level probe. +.PP +With scripts that contain probes on any interrupt path, it is possible that +those interrupts may occur in the middle of another probe handler. The probe +in the interrupt handler would be skipped in this case to avoid reentrance. +To work around this issue, execute stap with the option +.BR \-DINTERRUPTIBLE=0 +to mask interrupts throughout the probe handler. This does add some extra +overhead to the probes, but it may prevent reentrance for common problem +cases. However, probes in NMI handlers and in the callpath of the stap +runtime may still be skipped due to reentrance. + .PP Multiple scripts can write data into a relay buffer concurrently. A host script provides an interface for accessing its relay buffer to guest scripts. diff --git a/tapsets.cxx b/tapsets.cxx index b748a487..ce9a0ca1 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -159,12 +159,12 @@ be_derived_probe::join_group (systemtap_session& s) void common_probe_entryfn_prologue (translator_output* o, string statestr, string new_pp, - bool overload_processing = true, - bool interruptible = true) + bool overload_processing = true) { o->newline() << "struct context* __restrict__ c;"; - if (! interruptible) - o->newline() << "unsigned long flags;"; + o->newline() << "#if !INTERRUPTIBLE"; + o->newline() << "unsigned long flags;"; + o->newline() << "#endif"; if (overload_processing) o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)"; @@ -182,10 +182,11 @@ common_probe_entryfn_prologue (translator_output* o, string statestr, o->newline() << "static int _pfm_num_pmd_x;"; #endif - if (! interruptible) - o->newline() << "local_irq_save (flags);"; - else - o->newline() << "preempt_disable ();"; + o->newline() << "#if INTERRUPTIBLE"; + o->newline() << "preempt_disable ();"; + o->newline() << "#else"; + o->newline() << "local_irq_save (flags);"; + o->newline() << "#endif"; // Check for enough free enough stack space o->newline() << "if (unlikely ((((unsigned long) (& c)) & (THREAD_SIZE-1))"; // free space @@ -233,10 +234,12 @@ common_probe_entryfn_prologue (translator_output* o, string statestr, o->newline() << "c->regparm = 0;"; o->newline() << "c->marker_name = NULL;"; o->newline() << "c->marker_format = NULL;"; - if (! interruptible) - o->newline() << "c->actionremaining = MAXACTION;"; - else - o->newline() << "c->actionremaining = MAXACTION_INTERRUPTIBLE;"; + + o->newline() << "#if INTERRUPTIBLE"; + o->newline() << "c->actionremaining = MAXACTION_INTERRUPTIBLE;"; + o->newline() << "#else"; + o->newline() << "c->actionremaining = MAXACTION;"; + o->newline() << "#endif"; o->newline() << "#ifdef STP_TIMING"; o->newline() << "c->statp = 0;"; o->newline() << "#endif"; @@ -255,8 +258,7 @@ common_probe_entryfn_prologue (translator_output* o, string statestr, void common_probe_entryfn_epilogue (translator_output* o, - bool overload_processing = true, - bool interruptible = true) + bool overload_processing = true) { if (overload_processing) o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)"; @@ -332,10 +334,11 @@ common_probe_entryfn_epilogue (translator_output* o, o->newline() << "_stp_exit ();"; o->newline(-1) << "}"; - if (! interruptible) - o->newline() << "local_irq_restore (flags);"; - else - o->newline() << "preempt_enable_no_resched ();"; + o->newline() << "#if INTERRUPTIBLE"; + o->newline() << "preempt_enable_no_resched ();"; + o->newline() << "#else"; + o->newline() << "local_irq_restore (flags);"; + o->newline() << "#endif"; } @@ -349,23 +352,23 @@ be_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "/* ---- begin/end probes ---- */"; s.op->newline() << "static void enter_begin_probe (void (*fn)(struct context*), const char* pp) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", "pp", false, true); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", "pp", false); s.op->newline() << "(*fn) (c);"; - common_probe_entryfn_epilogue (s.op, false, true); + common_probe_entryfn_epilogue (s.op, false); s.op->newline(-1) << "}"; s.op->newline() << "static void enter_end_probe (void (*fn)(struct context*), const char* pp) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", "pp", false, true); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", "pp", false); s.op->newline() << "(*fn) (c);"; - common_probe_entryfn_epilogue (s.op, false, true); + common_probe_entryfn_epilogue (s.op, false); s.op->newline(-1) << "}"; s.op->newline() << "static void enter_error_probe (void (*fn)(struct context*), const char* pp) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", "pp", false, true); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", "pp", false); s.op->newline() << "(*fn) (c);"; - common_probe_entryfn_epilogue (s.op, false, true); + common_probe_entryfn_epilogue (s.op, false); s.op->newline(-1) << "}"; s.op->newline() << "static struct stap_be_probe {"; diff --git a/translate.cxx b/translate.cxx index b2ba5c72..17c37dc3 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4908,6 +4908,9 @@ translate_pass (systemtap_session& s) s.op->newline() << "#ifndef MINSTACKSPACE"; s.op->newline() << "#define MINSTACKSPACE 1024"; s.op->newline() << "#endif"; + s.op->newline() << "#ifndef INTERRUPTIBLE"; + s.op->newline() << "#define INTERRUPTIBLE 1"; + s.op->newline() << "#endif"; // Overload processing s.op->newline() << "#ifndef STP_OVERLOAD_INTERVAL"; -- cgit From 95635ee8a429033dcb5d63727f0f2cae039a2dfd Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 10 Mar 2009 17:43:17 -0400 Subject: Ensure args are available for postgres static probes. * includes/sys/sdt.h: Couple asm with its arg declaration. --- includes/sys/sdt.h | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index ea1da719..dc2950f0 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -30,7 +30,7 @@ struct _probe_ ## probe \ STAP_PROBE_STRUCT_ARG (probe_name); \ STAP_PROBE_STRUCT_ARG (probe_arg); \ }; \ -static char probe ## _ ## probe_name [strlen(#probe)+1] \ +static char probe ## _ ## probe_name [] \ __attribute__ ((section (".probes"))) \ = #probe; \ __extension__ static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc}; @@ -56,80 +56,81 @@ do { \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ STAP_LABEL_REF(probe,label); \ label: \ - __asm__ volatile ("nop");} \ - while (0) + __asm__ volatile ("nop"); \ + } while (0) #define STAP_PROBE1_(probe,label,parm1) \ do { \ - volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ + volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ label: \ - __asm__ volatile ("nop /* %0 */" :: "X"( arg1));} \ -while (0) + __asm__ volatile ("nop /* %0 */" :: "X"( arg1)); \ + STAP_LABEL_REF(probe,label); \ + } while (0) #define STAP_PROBE2_(probe,label,parm1,parm2) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop /* %0 %1 */" :: "X"(arg1), "X"(arg2)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile __typeof__((parm3)) arg3 __attribute__ ((unused)) = parm3; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop /* %0 %1 %2 */" :: "X"(arg1), "X"(arg2), "X"(arg3)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ 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_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop /* %0 %1 %2 %3 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ 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; \ volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop /* %0 %1 %2 %3 %4 */" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ 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; \ volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ volatile __typeof__((parm6)) arg6 __attribute__ ((unused)) = parm6; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile __typeof__((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -137,14 +138,14 @@ do { \ volatile __typeof__((parm5)) arg5 __attribute__ ((unused)) = parm5; \ volatile __typeof__((parm6)) arg6 __attribute__ ((unused)) = parm6; \ volatile __typeof__((parm7)) arg7 __attribute__ ((unused)) = parm7; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile __typeof__((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -153,14 +154,14 @@ do { \ volatile __typeof__((parm6)) arg6 __attribute__ ((unused)) = parm6; \ volatile __typeof__((parm7)) arg7 __attribute__ ((unused)) = parm7; \ volatile __typeof__((parm8)) arg8 __attribute__ ((unused)) = parm8; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile __typeof__((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -170,14 +171,14 @@ do { \ volatile __typeof__((parm7)) arg7 __attribute__ ((unused)) = parm7; \ volatile __typeof__((parm8)) arg8 __attribute__ ((unused)) = parm8; \ volatile __typeof__((parm9)) arg9 __attribute__ ((unused)) = parm9; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ do { \ + STAP_PROBE_STRUCT(probe,(size_t)&& label) \ volatile __typeof__((parm1)) arg1 __attribute__ ((unused)) = parm1; \ volatile __typeof__((parm2)) arg2 __attribute__ ((unused)) = parm2; \ volatile __typeof__((parm3)) arg3 __attribute__ ((unused)) = parm3; \ @@ -188,10 +189,9 @@ do { \ volatile __typeof__((parm8)) arg8 __attribute__ ((unused)) = parm8; \ volatile __typeof__((parm9)) arg9 __attribute__ ((unused)) = parm9; \ volatile __typeof__((parm10)) arg10 __attribute__ ((unused)) = parm10; \ - STAP_PROBE_STRUCT(probe,(size_t)&& label) \ - STAP_LABEL_REF(probe,label); \ label: \ __asm__ volatile ("nop" :: "X"(arg1), "X"(arg2), "X"(arg3), "X"(arg4), "X"(arg5), "X"(arg6), "X"(arg7), "X"(arg8), "X"(arg9), "X"(arg10)); \ + STAP_LABEL_REF(probe,label); \ } while (0) #define STAP_PROBE(provider,probe) \ -- cgit From abb41d920aecf908a132597f0a4bc26a10e58a7c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 10 Mar 2009 15:32:16 -0700 Subject: PR9932: add @cast module search path Sometimes @cast()ing can fail if the type needed may or may not be defined in a kernel module. This patch lets @cast take a colon- separated list of modules to search for the type definition. * tapsets.cxx (dwarf_cast_query): Simplify. Take the module and the code result as reference parameters, and use code.empty() as the sign that the type isn't resolved yet. (dwarf_cast_expanding_visitor::visit_cast_op): Split e->module by colon into substrings, and loop until the type is resolved. --- tapsets.cxx | 69 +++++++++++++++++++++++++++---------------------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index ce9a0ca1..b66dd123 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -4913,14 +4913,14 @@ struct dwarf_cast_query : public base_query { const cast_op& e; const bool lvalue; - exp_type& pe_type; - bool resolved; - string code; + exp_type& pe_type; + string& code; - dwarf_cast_query(dwflpp& dw, const cast_op& e, bool lvalue, exp_type& pe_type): - base_query(dw, e.module), e(e), lvalue(lvalue), pe_type(pe_type), resolved(false) {} - const string& get_code(); + dwarf_cast_query(dwflpp& dw, const string& module, const cast_op& e, + bool lvalue, exp_type& pe_type, string& code): + base_query(dw, module), e(e), lvalue(lvalue), + pe_type(pe_type), code(code) {} void handle_query_module(); int handle_query_cu(Dwarf_Die * cudie); @@ -4929,23 +4929,10 @@ struct dwarf_cast_query : public base_query }; -const string& -dwarf_cast_query::get_code() -{ - if (!resolved) - dw.query_modules(this); - - if (!resolved) - throw semantic_error("type definition not found"); - - return code; -} - - void dwarf_cast_query::handle_query_module() { - if (resolved) + if (!code.empty()) return; // look for the type in each CU @@ -4956,7 +4943,7 @@ dwarf_cast_query::handle_query_module() int dwarf_cast_query::handle_query_cu(Dwarf_Die * cudie) { - if (resolved) + if (!code.empty()) return DWARF_CB_ABORT; dw.focus_on_cu (cudie); @@ -4973,10 +4960,7 @@ dwarf_cast_query::handle_query_cu(Dwarf_Die * cudie) // XXX might be better to save the error // and try again in another CU sess.print_error (e); - return DWARF_CB_ABORT; } - - resolved = true; return DWARF_CB_ABORT; } return DWARF_CB_OK; @@ -5014,12 +4998,18 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) string code; exp_type type = pe_long; - try + size_t mod_end = -1; + do { + // split the module string by ':' for alternatives + size_t mod_begin = mod_end + 1; + mod_end = e->module.find(':', mod_begin); + string module = e->module.substr(mod_begin, mod_end); + // NB: This uses '/' to distinguish between kernel modules and userspace, // which means that userspace modules won't get any PATH searching. dwflpp* dw; - if (e->module.find('/') == string::npos) + if (module.find('/') == string::npos) { // kernel or kernel module target if (! db.kern_dw) @@ -5031,36 +5021,37 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) } else { - e->module = find_executable (e->module); // canonicalize it + module = find_executable (module); // canonicalize it // user-space target; we use one dwflpp instance per module name // (= program or shared library) - if (db.user_dw.find(e->module) == db.user_dw.end()) + if (db.user_dw.find(module) == db.user_dw.end()) { dw = new dwflpp(s); - dw->setup_user(e->module); - db.user_dw[e->module] = dw; + dw->setup_user(module); + db.user_dw[module] = dw; } else - dw = db.user_dw[e->module]; + dw = db.user_dw[module]; } - dwarf_cast_query q (*dw, *e, lvalue, type); - code = q.get_code(); + dwarf_cast_query q (*dw, module, *e, lvalue, type, code); + dw->query_modules(&q); } - catch (const semantic_error& er) + while (code.empty() && mod_end != string::npos); + + if (code.empty()) { - // We suppress this error message, and pass the unresolved + // We generate an error message, and pass the unresolved // 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* saveme = new semantic_error (er); // copy it - saveme->tok1 = e->tok; // XXX: token not passed to dw code generation routines + semantic_error* er = new semantic_error ("type definition not found", e->tok); // NB: we can have multiple errors, since a @cast // may be expanded in several different contexts: // function ("*") { @cast(...) } - saveme->chain = e->saved_conversion_error; - e->saved_conversion_error = saveme; + er->chain = e->saved_conversion_error; + e->saved_conversion_error = er; provide (e); return; } -- cgit From 6351f32433edb111b28362963c97d1cd0d1d8561 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 10 Mar 2009 15:46:21 -0700 Subject: PR9932: use @cast module search path The nfs, rpc, and scsi tapsets use @cast on types that may be compiled into a kernel module or into the main kernel binary. The @cast search path separated with colons lets us search both the kernel and the module. For a couple of cases, I also merged sequential @casts that work just fine as a single cast with a multiple-level dereference. --- tapset/nfs.stp | 50 +++++++++++++++++++------------------------------- tapset/rpc.stp | 41 ++++++++++++++--------------------------- tapset/scsi.stp | 4 ++-- 3 files changed, 35 insertions(+), 60 deletions(-) diff --git a/tapset/nfs.stp b/tapset/nfs.stp index fe25eff2..6752747f 100644 --- a/tapset/nfs.stp +++ b/tapset/nfs.stp @@ -137,11 +137,10 @@ function __nfs_wpages:long(inode:long) %{ /* pure */ /*Get struct inode from struct page*/ function __p2i :long(page:long) { - mapping = page? @cast(page, "page", "kernel")->mapping : 0 + mapping = page? @cast(page, "page", "kernel:nfs")->mapping : 0 if (mapping == 0) return 0 - else - return @cast(mapping, "address_space", "kernel")->host + return @cast(mapping, "address_space", "kernel:nfs")->host } /*Get i_flags from struct page*/ @@ -150,8 +149,7 @@ function __p2i_flag : long (page:long) host = __p2i(page) if (host == 0) return -1 - else - return @cast(host, "inode", "kernel")->i_flags + return @cast(host, "inode", "kernel:nfs")->i_flags } /*Get i_state from struct page*/ @@ -160,8 +158,7 @@ function __p2i_state :long (page:long) host = __p2i(page) if (host == 0) return -1 - else - return @cast(host, "inode", "kernel")->i_state + return @cast(host, "inode", "kernel:nfs")->i_state } /*Get i_size from struct page*/ @@ -170,19 +167,17 @@ function __p2i_size :long (page:long) host = __p2i(page) if (host == 0) return -1 - else - return @cast(host, "inode", "kernel")->i_size + return @cast(host, "inode", "kernel:nfs")->i_size } /*Get s_flags from struct page*/ function __p2sb_flag:long (page:long) { host = __p2i(page) - i_sb = host? @cast(host, "inode", "kernel")->i_sb : 0 + i_sb = host? @cast(host, "inode", "kernel:nfs")->i_sb : 0 if (i_sb == 0) return -1 - else - return @cast(i_sb, "super_block", "kernel")->s_flags + return @cast(i_sb, "super_block", "kernel:nfs")->s_flags } function __d_loff_t :long (ppos :long) %{ /* pure */ @@ -198,14 +193,13 @@ function __d_loff_t :long (ppos :long) %{ /* pure */ function __file_inode:long (file:long) { %( kernel_v >= "2.6.20" %? - dentry = file? @cast(file, "file", "kernel")->f_path->dentry : 0 + dentry = file? @cast(file, "file", "kernel:nfs")->f_path->dentry : 0 %: - dentry = file? @cast(file, "file", "kernel")->f_dentry : 0 + dentry = file? @cast(file, "file", "kernel:nfs")->f_dentry : 0 %) if (dentry == 0) return 0 - else - return @cast(dentry, "dentry", "kernel")->d_inode + return @cast(dentry, "dentry", "kernel:nfs")->d_inode } function __file_id:long (file:long) @@ -213,10 +207,7 @@ function __file_id:long (file:long) d_inode = __file_inode(file) if (d_inode == 0) return 0 - else { - i_sb = @cast(d_inode, "inode", "kernel")->i_sb - return @cast(i_sb, "super_block", "kernel")->s_id - } + return @cast(d_inode, "inode", "kernel:nfs")->i_sb->s_id } function __file_mode:long (file:long) @@ -224,24 +215,21 @@ function __file_mode:long (file:long) d_inode = __file_inode(file) if (d_inode == 0) return 0 - else - return @cast(d_inode, "inode", "kernel")->i_mode + return @cast(d_inode, "inode", "kernel:nfs")->i_mode } function __file_parentname:string (file:long) { %( kernel_v >= "2.6.20" %? - dentry = file? @cast(file, "file", "kernel")->f_path->dentry : 0 + dentry = file? @cast(file, "file", "kernel:nfs")->f_path->dentry : 0 %: - dentry = file? @cast(file, "file", "kernel")->f_dentry : 0 + dentry = file? @cast(file, "file", "kernel:nfs")->f_dentry : 0 %) - d_parent = dentry? @cast(dentry, "dentry", "kernel")->d_parent : 0 + d_parent = dentry? @cast(dentry, "dentry", "kernel:nfs")->d_parent : 0 if (d_parent == 0) return "NULL" - else { - name = @cast(d_parent, "dentry", "kernel")->d_name->name - return kernel_string(name) - } + name = @cast(d_parent, "dentry", "kernel:nfs")->d_name->name + return kernel_string(name) } /* @@ -336,8 +324,8 @@ probe nfs.fop.llseek = kernel.function ("nfs_file_llseek") !, { dev = __file_dev($filp) ino = __file_ino($filp) - s_id = __file_id($filp) - devname = kernel_string(s_id) + s_id = __file_id($filp) + devname = kernel_string(s_id) maxbyte = __file_maxbytes($filp) offset = $offset diff --git a/tapset/rpc.stp b/tapset/rpc.stp index e6eaed46..1d47daed 100644 --- a/tapset/rpc.stp +++ b/tapset/rpc.stp @@ -880,48 +880,36 @@ function xid_from_clnt:long(clnt:long) { if (clnt == 0) return 0 - else { - cl_xprt = @cast(clnt, "rpc_clnt", "kernel")->cl_xprt - return @cast(cl_xprt, "rpc_xprt", "kernel")->xid - } + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt->xid } function prog_from_clnt:long(clnt:long) { if (clnt == 0) return 0 - else { %(kernel_v >= "2.6.19" %? - return @cast(clnt, "rpc_clnt", "kernel")->cl_prog + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_prog %: - cl_pmap = @cast(clnt, "rpc_clnt", "kernel")->cl_pmap - return @cast(cl_pmap, "rpc_portmap", "kernel")->pm_prog + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_pmap->pm_prog %) - } } function vers_from_clnt:long(clnt:long) { - if (clnt == 0) - return 0 - else { + if (clnt == 0) + return 0 %(kernel_v >= "2.6.19" %? - return @cast(clnt, "rpc_clnt", "kernel")->cl_vers + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_vers %: - cl_pmap = @cast(clnt, "rpc_clnt", "kernel")->cl_pmap - return @cast(cl_pmap, "rpc_portmap", "kernel")->pm_vers + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_pmap->pm_vers %) - } } function prot_from_clnt:long(clnt:long) { - if (clnt == 0) - return 0 - else { - cl_xprt = @cast(clnt, "rpc_clnt", "kernel")->cl_xprt - return @cast(cl_xprt, "rpc_xprt", "kernel")->prot - } + if (clnt == 0) + return 0 + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt->prot } function port_from_clnt:long(clnt:long) @@ -934,12 +922,14 @@ function port_from_clnt:long(clnt:long) struct sockaddr_in *sap = (struct sockaddr_in *) &cl_xprt->addr; THIS->__retvalue = ntohs(kread(&(sap->sin_port))); + } #else if (cl_xprt && kread(&(cl_xprt->addr.sin_family)) == AF_INET) { /* Now consider ipv4 only */ THIS->__retvalue = ntohs(kread(&(cl_xprt->addr.sin_port))); + } #endif - } else + else THIS->__retvalue = 0; CATCH_DEREF_FAULT(); %} @@ -970,10 +960,7 @@ function proc_from_msg:long(msg:long) { if (msg == 0) return 0 - else { - rpc_proc = @cast(msg, "rpc_message", "kernel")->rpc_proc - return @cast(rpc_proc, "rpc_procinfo", "kernel")->p_proc - } + return @cast(msg, "rpc_message", "kernel:sunrpc")->rpc_proc->p_proc } function vers_from_prog:long(program:long, vers:long) diff --git a/tapset/scsi.stp b/tapset/scsi.stp index b1b2d19b..6d332e8b 100644 --- a/tapset/scsi.stp +++ b/tapset/scsi.stp @@ -137,6 +137,6 @@ function scsi_timer_pending:long(var:long) function get_devstate_from_req:long(var:long) { - sdev = @cast(var, "request_queue", "kernel")->queuedata - return @cast(sdev, "scsi_device", "kernel")->sdev_state + sdev = @cast(var, "request_queue", "kernel:scsi_mod")->queuedata + return @cast(sdev, "scsi_device", "kernel:scsi_mod")->sdev_state } -- cgit From 381dc4158249cffce8e76a3ea6874a084b41bf26 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 10 Mar 2009 15:51:09 -0700 Subject: Merge sequential casts in the vfs tapset A few places in this tapset were using a pattern like this: i_sb = @cast(foo, "inode")->i_sb return @cast(foo, "super_block")->bar The type of i_sb is already known, so I just merged this to: return @cast(foo, "inode")->i_sb->bar --- tapset/vfs.stp | 54 +++++++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/tapset/vfs.stp b/tapset/vfs.stp index 3bb9292d..23d95098 100644 --- a/tapset/vfs.stp +++ b/tapset/vfs.stp @@ -74,21 +74,15 @@ function __page_dev:long (page:long) host = __address_inode(page) if (host == -1) return -1 - else { - i_sb = @cast(host, "inode", "kernel")->i_sb - return @cast(i_sb, "super_block", "kernel")->s_dev - } + return @cast(host, "inode", "kernel")->i_sb->s_dev } function __page_bdev:long (page:long) { - host = __address_inode(page) - if (host == -1) - return 0 - else { - i_sb = @cast(host, "inode", "kernel")->i_sb - return @cast(i_sb, "super_block", "kernel")->s_bdev - } + host = __address_inode(page) + if (host == -1) + return 0 + return @cast(host, "inode", "kernel")->i_sb->s_bdev } function __page_index:long (page:long) @@ -101,41 +95,31 @@ function __file_dev:long (file:long) d_inode = __file_inode(file) if (d_inode == 0) return 0 - else { - i_sb = @cast(d_inode, "inode", "kernel")->i_sb - return @cast(i_sb, "super_block", "kernel")->s_dev - } + return @cast(d_inode, "inode", "kernel")->i_sb->s_dev } function __file_bdev:long (file:long) { - d_inode = __file_inode(file) - if (d_inode == 0) - return 0 - else { - i_sb = @cast(d_inode, "inode", "kernel")->i_sb - return @cast(i_sb, "super_block", "kernel")->s_bdev - } + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + return @cast(d_inode, "inode", "kernel")->i_sb->s_bdev } function __file_ino:long (file:long) { - d_inode = __file_inode(file) - if (d_inode == 0) - return 0 - else - return @cast(d_inode, "inode", "kernel")->i_ino + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + return @cast(d_inode, "inode", "kernel")->i_ino } function __file_maxbytes:long (file:long) { - d_inode = __file_inode(file) - if (d_inode == 0) - return 0 - else { - i_sb = @cast(d_inode, "inode", "kernel")->i_sb - return @cast(i_sb, "super_block", "kernel")->s_maxbytes - } + d_inode = __file_inode(file) + if (d_inode == 0) + return 0 + return @cast(d_inode, "inode", "kernel")->i_sb->s_maxbytes } function __file_filename:string (file:long) @@ -153,7 +137,7 @@ function __file_filename:string (file:long) } function _get_fopv_size:long (iov:long, nr_segs:long) -%{ +%{ /* pure */ struct iovec *iovp = (struct iovec *)(long)THIS->iov; if (iovp) { int i; -- cgit From e2086848b3b1e010249f68857ec10d6b9382446e Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Mon, 9 Mar 2009 08:17:27 -0400 Subject: Make tracepoint probe support listing mode -L This patch is to enable displaying arguments of tracepoint probe in listing mode -L. The example output is like $stap -L 'kernel.trace("block_bio*")' kernel.trace("block_bio_bounce") $q:struct request_queue* $bio:struct bio* kernel.trace("block_bio_backmerge") $q:struct request_queue* $bio:struct bio* kernel.trace("block_bio_complete") $q:struct request_queue* $bio:struct bio* kernel.trace("block_bio_queue") $q:struct request_queue* $bio:struct bio* kernel.trace("block_bio_frontmerge") $q:struct request_queue* $bio:struct bio* Signed-off-by: Wenji Huang --- elaborate.h | 2 ++ main.cxx | 5 ++++- tapsets.cxx | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/elaborate.h b/elaborate.h index 1e05444f..0ad5b4b2 100644 --- a/elaborate.h +++ b/elaborate.h @@ -124,6 +124,8 @@ struct derived_probe: public probe virtual void join_group (systemtap_session& s) = 0; virtual probe_point* sole_location () const; virtual void printsig (std::ostream &o) const; + //for print arguments of probe if there + virtual void printargs (std::ostream &o) const {} void printsig_nested (std::ostream &o) const; virtual void collect_derivation_chain (std::vector &probes_list); diff --git a/main.cxx b/main.cxx index dbb2a306..b494ba2b 100644 --- a/main.cxx +++ b/main.cxx @@ -187,13 +187,16 @@ printscript(systemtap_session& s, ostream& o) { o << pp; // Print the locals for -L mode only - if (s.unoptimized) + if (s.unoptimized) { for (unsigned j=0; jlocals.size(); j++) { o << " "; vardecl* v = p->locals[j]; v->printsig (o); } + // Print arguments of probe if there + p->printargs(o); + } o << endl; seen.insert (pp); } diff --git a/tapsets.cxx b/tapsets.cxx index b66dd123..71a9a768 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9217,6 +9217,7 @@ struct tracepoint_derived_probe: public derived_probe vector args; void build_args(dwflpp& dw, Dwarf_Die& func_die); + void printargs (std::ostream &o) const; void join_group (systemtap_session& s); void emit_probe_context_vars (translator_output* o); }; @@ -9665,6 +9666,12 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) while (dwarf_siblingof(&arg, &arg) == 0); } +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; +} void tracepoint_derived_probe::join_group (systemtap_session& s) -- cgit From 89f3a1254ccf16a6828671c6e5bc407bc061f040 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Mon, 9 Mar 2009 10:05:42 -0400 Subject: Make marker probe support listing mode -L This patch is to enable displaying the arguments of marker probe for listing mode -L. The output is like, $stap -L 'kernel.mark("*")' kernel.mark("core_marker_format").format("name %s format %s") $arg1:string $arg2:string kernel.mark("jbd2_checkpoint").format("dev %s need_checkpoint %d") $arg1:string $arg2:long kernel.mark("jbd2_end_commit").format("dev %s transaction %d head %d") $arg1:string $arg2:long $arg3:long kernel.mark("jbd2_start_commit").format("dev %s transaction %d") $arg1:string $arg2:long Note: It's also possible to figure out the arguments according to the format. Signed-off-by: Wenji Huang --- tapsets.cxx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tapsets.cxx b/tapsets.cxx index 71a9a768..b1d0b04e 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8523,6 +8523,7 @@ struct mark_derived_probe: public derived_probe void join_group (systemtap_session& s); void emit_probe_context_vars (translator_output* o); void initialize_probe_context_vars (translator_output* o); + void printargs (std::ostream &o) const; void parse_probe_format (); }; @@ -8967,6 +8968,27 @@ mark_derived_probe::initialize_probe_context_vars (translator_output* o) o->newline() << "deref_fault: ;"; } +void +mark_derived_probe::printargs(std::ostream &o) const +{ + for (unsigned i = 0; i < mark_args.size(); i++) + { + string localname = "$arg" + lex_cast(i+1); + switch (mark_args[i]->stp_type) + { + case pe_long: + o << " " << localname << ":long"; + break; + case pe_string: + o << " " << localname << ":string"; + break; + default: + o << " " << localname << ":unknown"; + break; + } + } +} + void mark_derived_probe_group::emit_module_decls (systemtap_session& s) -- cgit From 06ba5b2c104f5c1c613fdf9085897e56b0912209 Mon Sep 17 00:00:00 2001 From: Dave Brolley Date: Wed, 11 Mar 2009 12:12:16 -0400 Subject: 2009-03-11 Dave Brolley PR 9936 * stap-find-servers (configuration): Set timeout to 10 seconds. (find_servers): Run avahi-browse in the background and wait for $timeout seconds for it to finish. Kill it if it does not finish. Use a temp file for avahi-browse output. (match_server): Use -t $timeout on read commands. * stap-start-server: Check for $server_pid as a running process and for avahi-publish-service running as a child of $server_pid in order to confirm that the server is running. --- stap-find-servers | 52 ++++++++++++++++++++++++++++++++++++++++------------ stap-start-server | 19 +++++++++++-------- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/stap-find-servers b/stap-find-servers index 3038c54e..fde7d9ef 100755 --- a/stap-find-servers +++ b/stap-find-servers @@ -2,7 +2,7 @@ # Find compile servers for systemtap # -# 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 @@ -18,6 +18,7 @@ # function: configuration function configuration { avahi_service_tag=_stap._tcp + timeout=10 # seconds } # function: initialization @@ -30,13 +31,32 @@ function initialization { fi } -# function: find_and_connect_to_server +# function: find_servers # -# Find and establish connection with a compatibale stap server. +# Find and establish connection with a compatible stap server. function find_servers { - # Find a server - avahi-browse $avahi_service_tag --terminate -r 2>/dev/null | match_server - rc=$? + # Create a temp file for the list of servers. We do this instead + # of using a pipe so that we can kill avahi-browse if it + # takes more than a minute. + tmpfile=`mktemp -t stap-serversXXXXXX` || \ + fatal "Cannot create temporary file " $tmpfile + + # Find servers + avahi-browse $avahi_service_tag --terminate -r 2>/dev/null > $tmpfile & + + for ((attempt=0; $attempt < $timeout; ++attempt)) + do + if ! jobs '%avahi-browse' >/dev/null 2>&1; then + break + fi + sleep 1 + done + + # Kill avahi-browse, if it's still running + test $attempt = $timeout && kill -s SIGTERM '%avahi-browse' 2>/dev/null + + match_server < $tmpfile + rm -fr $tmpfile } # function: match_server @@ -47,10 +67,11 @@ function match_server { local server_name local server_sysinfo local server_port - local rc=1 # not found yet + + rc=1 # not found yet # Loop over the avahi service descriptors. - read || exit $rc + read -t $timeout || return while test "X$REPLY" != "X" do server_name= @@ -61,14 +82,14 @@ function match_server { # Examine the next service descriptor # Is it a stap server? if ! echo $REPLY | grep -q "=.* .* IPv4 .*_stap"; then - read || exit $rc + read -t $timeout || return continue fi REPLY= # Get the details of the service local service_tag equal service_data - while read service_tag equal service_data + while read -t $timeout service_tag equal service_data do case $service_tag in hostname ) @@ -113,8 +134,6 @@ function match_server { echo "$server_name $server_ip $server_port '$server_sysinfo'" rc=0 done - - exit $rc } # function client_sysinfo @@ -128,6 +147,15 @@ function client_sysinfo { echo sysinfo=$sysinfo_client } +# function: fatal [ MESSAGE ] +# +# Fatal error +# Prints its arguments to stderr and exits +function fatal { + echo "$0: ERROR:" "$@" >&2 + exit 1 +} + #----------------------------------------------------------------------------- # Beginning of main line execution. #----------------------------------------------------------------------------- diff --git a/stap-start-server b/stap-start-server index f1f02d2f..d718ed30 100755 --- a/stap-start-server +++ b/stap-start-server @@ -25,17 +25,20 @@ server_pid=$! # Make sure the server is started for ((attempt=0; $attempt < 10; ++attempt)) do - if test $EUID = 0; then - if ! test -f $sysconfdir/systemtap/ssl/server/stap-server.cert; then - sleep 1 - continue; - fi - elif ! test -f $HOME/.systemtap/ssl/server/stap-server.cert; then + # Has the server started? + if ! (ps -a | grep $server_pid) >/dev/null 2>&1; then sleep 1 continue fi - (ps -a | grep $server_pid) >/dev/null 2>&1 && echo $server_pid && exit 0 - sleep 1 + # Is avahi advertizing the server? + if ! (ps -fa | grep avahi-publish-service | grep $server_pid) > /dev/null 2>&1; then + sleep 1 + continue + fi + + # The server is ready + echo $server_pid + exit 0 done exit 1 # server did not start -- cgit From e248aea9a04dd0d3c4e066afdca52176aaf9a536 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Wed, 11 Mar 2009 17:37:09 -0400 Subject: Run the tests for each member of a list of extra options. * testsuite/systemtap.base/sdt.h: Add extra_flags and g++ as a test language. --- testsuite/systemtap.base/sdt.exp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/testsuite/systemtap.base/sdt.exp b/testsuite/systemtap.base/sdt.exp index 9c40bf4d..09aaaf8d 100644 --- a/testsuite/systemtap.base/sdt.exp +++ b/testsuite/systemtap.base/sdt.exp @@ -10,13 +10,41 @@ set ::result_string {1 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 10} +set extra_flags {{""} {additional_flags=-ansi}} + +# Iterate extra_flags, trying each with C and C++ +for {set i 0} {$i < [llength $extra_flags]} {incr i} { +# C set test_flags "additional_flags=-g" set test_flags "$test_flags additional_flags=-I$srcdir/../includes/sys" set test_flags "$test_flags additional_flags=-std=gnu89" set test_flags "$test_flags additional_flags=-Wall" set test_flags "$test_flags additional_flags=-Wdeclaration-after-statement" set test_flags "$test_flags additional_flags=-Werror" -set res [target_compile $srcdir/$subdir/$test.c $test.prog executable $test_flags] + +set res [target_compile $srcdir/$subdir/$test.c $test.prog executable [concat $test_flags " " [lindex $extra_flags $i]]] +if { $res != "" } { + verbose "target_compile failed: $res" 2 + fail "compiling $test.c" + return +} else { + pass "compiling $test.c" +} + +if {[installtest_p]} { + stap_run2 $srcdir/$subdir/$test.stp -c ./$test.prog +} else { + untested "$test" +} + +# C++ +set test_flags "additional_flags=-g" +set test_flags "$test_flags additional_flags=-I$srcdir/../includes/sys" +set test_flags "$test_flags additional_flags=-Wall" +set test_flags "$test_flags additional_flags=-Werror" +set test_flags "$test_flags additional_flags=-x additional_flags=c++" + +set res [target_compile $srcdir/$subdir/$test.c $test.prog executable [concat $test_flags [lindex $extra_flags $i]]] if { $res != "" } { verbose "target_compile failed: $res" 2 fail "compiling $test.c" @@ -30,5 +58,6 @@ if {[installtest_p]} { } else { untested "$test" } +} catch {exec rm -f $test.prog} -- cgit From 3bd0d4df7ccfd9afe7771441b26d8baaaf180e29 Mon Sep 17 00:00:00 2001 From: Rajan Arora Date: Wed, 11 Mar 2009 18:44:21 -0400 Subject: PR 7071: Optional $context variables fix * tapsets.cxx (dwarf_var_expanding_visitor::visit_target_symbol): Substitute erroneous target symbol with literal 0 if session level flag, skip_badvars is set. * session.h (struct systemtap_session): New flag: skip_badvars. * main.cxx: Command line argument --skip-badvars added. * stap.1.in: Entry for new option --skip-badvars. * NEWS: Added blurb for new option now available. * testsuite/semok/badvar.stp: Test case to check added functionality. --- NEWS | 5 +++++ main.cxx | 7 +++++++ session.h | 3 +++ stap.1.in | 3 +++ tapsets.cxx | 37 +++++++++++++++++++++++++------------ testsuite/semok/badvar.stp | 7 +++++++ 6 files changed, 50 insertions(+), 12 deletions(-) create mode 100755 testsuite/semok/badvar.stp diff --git a/NEWS b/NEWS index 08705c81..74fd1df5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,10 @@ * What's new +- 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 + literal 0 and print a warning message when the substitution has been made. + * What's new in version 0.9 - Typecasting is now supported using the @cast operator. A script can diff --git a/main.cxx b/main.cxx index b494ba2b..890f65bc 100644 --- a/main.cxx +++ b/main.cxx @@ -134,6 +134,8 @@ usage (systemtap_session& s, int exitcode) #endif // Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use // only, and don't belong in the eyesight of a plain user. + << " --skip-badvars" << endl + << " overlook context of bad $ variables" << endl << endl ; @@ -431,12 +433,14 @@ main (int argc, char * const argv []) #define LONG_OPT_IGNORE_VMLINUX 3 #define LONG_OPT_IGNORE_DWARF 4 #define LONG_OPT_VERBOSE_PASS 5 +#define LONG_OPT_SKIP_BADVARS 6 // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page static struct option long_options[] = { { "kelf", 0, &long_opt, LONG_OPT_KELF }, { "kmap", 2, &long_opt, LONG_OPT_KMAP }, { "ignore-vmlinux", 0, &long_opt, LONG_OPT_IGNORE_VMLINUX }, { "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF }, + { "skip-badvars", 0, &long_opt, LONG_OPT_SKIP_BADVARS }, { "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS }, { NULL, 0, NULL, 0 } }; @@ -698,6 +702,9 @@ main (int argc, char * const argv []) // NB: we don't do this: s.last_pass = strlen(optarg); break; } + case LONG_OPT_SKIP_BADVARS: + s.skip_badvars = true; + break; default: cerr << "Internal error parsing command arguments." << endl; usage(s, 1); diff --git a/session.h b/session.h index bc99385b..ec6c2e3e 100644 --- a/session.h +++ b/session.h @@ -123,6 +123,9 @@ struct systemtap_session bool ignore_vmlinux; bool ignore_dwarf; + // Skip bad $ vars + bool skip_badvars; + // temporary directory for module builds etc. // hazardous - it is "rm -rf"'d at exit std::string tmpdir; diff --git a/stap.1.in b/stap.1.in index 546bebb8..5a2e35f9 100644 --- a/stap.1.in +++ b/stap.1.in @@ -230,6 +230,9 @@ nor the kernel debugging information can be found. .TP .B \-\-ignore\-dwarf For testing, act as though vmlinux and modules lack debugging information. +.TP +.B \-\-skip\-badvars +Ignore out of context variables and substitute with literal 0. .SH ARGUMENTS diff --git a/tapsets.cxx b/tapsets.cxx index b1d0b04e..dce73534 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -4842,18 +4842,31 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) } catch (const semantic_error& er) { - // We suppress this error message, and pass the unresolved - // target_symbol to the next pass. We hope that this value ends - // up not being referenced after all, so it can be optimized out - // quietly. - provide (e); - semantic_error* saveme = new semantic_error (er); // copy it - saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines - // NB: we can have multiple errors, since a $target variable - // may be expanded in several different contexts: - // function ("*") { $var } - saveme->chain = e->saved_conversion_error; - e->saved_conversion_error = saveme; + if (!q.sess.skip_badvars) + { + // We suppress this error message, and pass the unresolved + // target_symbol to the next pass. We hope that this value ends + // up not being referenced after all, so it can be optimized out + // quietly. + provide (e); + semantic_error* saveme = new semantic_error (er); // copy it + saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines + // NB: we can have multiple errors, since a $target variable + // may be expanded in several different contexts: + // function ("*") { $var } + saveme->chain = e->saved_conversion_error; + e->saved_conversion_error = saveme; + } + else + { + // Upon user request for ignoring context, the symbol is replaced + // with a literal 0 and a warning message displayed + literal_number* ln_zero = new literal_number (0); + ln_zero->tok = e->tok; + provide (ln_zero); + q.sess.print_warning ("Bad variable being substituted with literal 0", + e->tok); + } delete fdecl; delete ec; return; diff --git a/testsuite/semok/badvar.stp b/testsuite/semok/badvar.stp new file mode 100755 index 00000000..b3bd2d67 --- /dev/null +++ b/testsuite/semok/badvar.stp @@ -0,0 +1,7 @@ +#! stap --skip-badvars + +probe syscall.read { + if ($foo == 0) + printf ("Voila! It works..\n") + exit () +} -- cgit From ec80b3969d33e4d54e97ead4286bdb018e2f1f97 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Wed, 11 Mar 2009 22:11:09 -0400 Subject: improve sdt.h compatibility and test suite Replaced cpp VA_ARGS in sdt.h with explicit enumeration of arguments (since with -pedantic, cpp has no varargs), and added a few more cflags variants to the sdt.exp test case. --- includes/sys/sdt.h | 40 ++++++++++++++++++++-------------------- testsuite/systemtap.base/sdt.c | 2 ++ testsuite/systemtap.base/sdt.exp | 25 ++++++++++++++----------- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index dc2950f0..d6c90192 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -196,26 +196,26 @@ label: \ #define STAP_PROBE(provider,probe) \ STAP_PROBE_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER)) -#define STAP_PROBE1(provider,probe,...) \ - STAP_PROBE1_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE2(provider,probe,...) \ - STAP_PROBE2_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE3(provider,probe,...) \ - STAP_PROBE3_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE4(provider,probe,...) \ - STAP_PROBE4_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE5(provider,probe,...) \ - STAP_PROBE5_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE6(provider,probe,...) \ - STAP_PROBE6_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE7(provider,probe,...) \ - STAP_PROBE7_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE8(provider,probe,...) \ - STAP_PROBE8_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE9(provider,probe,...) \ - STAP_PROBE9_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) -#define STAP_PROBE10(provider,probe,...) \ - STAP_PROBE10_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),__VA_ARGS__) +#define STAP_PROBE1(provider,probe,parm1) \ + STAP_PROBE1_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1)) +#define STAP_PROBE2(provider,probe,parm1,parm2) \ + STAP_PROBE2_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2)) +#define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ + STAP_PROBE3_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3)) +#define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ + STAP_PROBE4_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3),(parm4)) +#define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ + STAP_PROBE5_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3),(parm4),(parm5)) +#define STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ + STAP_PROBE6_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3),(parm4),(parm5),(parm6)) +#define STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ + STAP_PROBE7_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3),(parm4),(parm5),(parm6),(parm7)) +#define STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ + STAP_PROBE8_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3),(parm4),(parm5),(parm6),(parm7),(parm8)) +#define STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ + STAP_PROBE9_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3),(parm4),(parm5),(parm6),(parm7),(parm8),(parm9)) +#define STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ + STAP_PROBE10_(probe,STAP_LABEL(STAP_LABEL_PREFIX(probe),STAP_COUNTER),(parm1),(parm2),(parm3),(parm4),(parm5),(parm6),(parm7),(parm8),(parm9),(parm10)) #define DTRACE_PROBE(provider,probe) \ STAP_PROBE(provider,probe) diff --git a/testsuite/systemtap.base/sdt.c b/testsuite/systemtap.base/sdt.c index 46f68664..7c7398e5 100644 --- a/testsuite/systemtap.base/sdt.c +++ b/testsuite/systemtap.base/sdt.c @@ -65,5 +65,7 @@ main (int argc, char **argv) call8(a, b, c, d, e, f, g, h); call9(a, b, c, d, e, f, g, h, i); call10(a, b, c, d, e, f, g, h, i, j); + (void) argv; + (void) argc; return 0; } diff --git a/testsuite/systemtap.base/sdt.exp b/testsuite/systemtap.base/sdt.exp index 09aaaf8d..74818beb 100644 --- a/testsuite/systemtap.base/sdt.exp +++ b/testsuite/systemtap.base/sdt.exp @@ -10,31 +10,33 @@ set ::result_string {1 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 10} -set extra_flags {{""} {additional_flags=-ansi}} +set extra_flags {{""} {additional_flags=-std=gnu89} {additional_flags=-ansi} {additional_flags=-pedantic}} # Iterate extra_flags, trying each with C and C++ for {set i 0} {$i < [llength $extra_flags]} {incr i} { +set extra_flag [lindex $extra_flags $i] + # C set test_flags "additional_flags=-g" set test_flags "$test_flags additional_flags=-I$srcdir/../includes/sys" -set test_flags "$test_flags additional_flags=-std=gnu89" set test_flags "$test_flags additional_flags=-Wall" -set test_flags "$test_flags additional_flags=-Wdeclaration-after-statement" +set test_flags "$test_flags additional_flags=-Wextra" set test_flags "$test_flags additional_flags=-Werror" -set res [target_compile $srcdir/$subdir/$test.c $test.prog executable [concat $test_flags " " [lindex $extra_flags $i]]] +set res [target_compile $srcdir/$subdir/$test.c $test.prog executable "$test_flags $extra_flag"] if { $res != "" } { verbose "target_compile failed: $res" 2 - fail "compiling $test.c" + fail "compiling $test.c $extra_flag" return } else { - pass "compiling $test.c" + pass "compiling $test.c $extra_flag" } if {[installtest_p]} { +# XXX: we need distinct test names for these stap_run2 $srcdir/$subdir/$test.stp -c ./$test.prog } else { - untested "$test" + untested "$test $extra_flag" } # C++ @@ -44,19 +46,20 @@ set test_flags "$test_flags additional_flags=-Wall" set test_flags "$test_flags additional_flags=-Werror" set test_flags "$test_flags additional_flags=-x additional_flags=c++" -set res [target_compile $srcdir/$subdir/$test.c $test.prog executable [concat $test_flags [lindex $extra_flags $i]]] +set res [target_compile $srcdir/$subdir/$test.c $test.prog executable "$test_flags $extra_flag"] if { $res != "" } { verbose "target_compile failed: $res" 2 - fail "compiling $test.c" + fail "compiling $test.c c++ $extra_flag" return } else { - pass "compiling $test.c" + pass "compiling $test.c c++ $extra_flag" } if {[installtest_p]} { +# XXX: we need distinct test names for these stap_run2 $srcdir/$subdir/$test.stp -c ./$test.prog } else { - untested "$test" + untested "$test c++ $extra_flag" } } -- cgit From 49462d1bcec68365e3ac96fc5c11c83ab7a8abd6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 11 Mar 2009 20:07:07 -0700 Subject: Add simple testcases for @cast --- testsuite/semok/cast.stp | 13 +++++++++++++ testsuite/systemtap.base/cast.exp | 4 ++++ testsuite/systemtap.base/cast.stp | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100755 testsuite/semok/cast.stp create mode 100644 testsuite/systemtap.base/cast.exp create mode 100644 testsuite/systemtap.base/cast.stp diff --git a/testsuite/semok/cast.stp b/testsuite/semok/cast.stp new file mode 100755 index 00000000..93da18ef --- /dev/null +++ b/testsuite/semok/cast.stp @@ -0,0 +1,13 @@ +#! stap -p2 + +probe begin { + // basic @cast test, with and without specifying kernel + println(@cast(0, "task_struct")->tgid) + println(@cast(0, "task_struct", "kernel")->tgid) + + // check module-search paths + println(@cast(0, "task_struct", "foo:kernel:bar")->tgid) + + // would be nice to test usermode @cast too, + // but who knows what debuginfo is installed... +} diff --git a/testsuite/systemtap.base/cast.exp b/testsuite/systemtap.base/cast.exp new file mode 100644 index 00000000..df3246e8 --- /dev/null +++ b/testsuite/systemtap.base/cast.exp @@ -0,0 +1,4 @@ +set test "cast" +set ::result_string {PID OK +execname OK} +stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.base/cast.stp b/testsuite/systemtap.base/cast.stp new file mode 100644 index 00000000..bec0cc9b --- /dev/null +++ b/testsuite/systemtap.base/cast.stp @@ -0,0 +1,22 @@ +probe begin +{ + curr = task_current() + + // Compare PIDs + pid = pid() + cast_pid = @cast(curr, "task_struct")->tgid + if (pid == cast_pid) + println("PID OK") + else + printf("PID %d != %d\n", pid, cast_pid) + + // Compare execnames + name = execname() + cast_name = kernel_string(@cast(curr, "task_struct")->comm) + if (name == cast_name) + println("execname OK") + else + printf("execname \"%s\" != \"%s\"\n", name, cast_name) + + exit() +} -- cgit From 139dee87b8824df4d7562a980e886a6e6f0b8308 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 11 Mar 2009 20:07:22 -0700 Subject: Fix @cast module splitting The new semok testcase exposed that the module splitting wasn't properly setting substr boundaries. Instead of passing the end position, it's supposed to pass the number of characters (end - begin). Oops. --- tapsets.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tapsets.cxx b/tapsets.cxx index dce73534..7f6ca721 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -5017,7 +5017,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) // split the module string by ':' for alternatives size_t mod_begin = mod_end + 1; mod_end = e->module.find(':', mod_begin); - string module = e->module.substr(mod_begin, mod_end); + string module = e->module.substr(mod_begin, mod_end - mod_begin); // NB: This uses '/' to distinguish between kernel modules and userspace, // which means that userspace modules won't get any PATH searching. -- cgit From 6769e48794cfbeda3957f691077fb9d65f3e87bc Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 11 Mar 2009 20:30:58 -0700 Subject: Add test to compile and run all tracepoints This checks that kernel.trace("*") will compile, with all context variables accessed as well. For kernels without tracepoints, it will just hit a "begin" and quit. This doesn't ensure that kernel.trace("*") will always find something when it should, though... --- testsuite/systemtap.base/tracepoints.exp | 3 +++ testsuite/systemtap.base/tracepoints.stp | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 testsuite/systemtap.base/tracepoints.exp create mode 100644 testsuite/systemtap.base/tracepoints.stp diff --git a/testsuite/systemtap.base/tracepoints.exp b/testsuite/systemtap.base/tracepoints.exp new file mode 100644 index 00000000..bea461c4 --- /dev/null +++ b/testsuite/systemtap.base/tracepoints.exp @@ -0,0 +1,3 @@ +set test "tracepoints" +set ::result_string {tracepoints OK} +stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.base/tracepoints.stp b/testsuite/systemtap.base/tracepoints.stp new file mode 100644 index 00000000..bdb4d730 --- /dev/null +++ b/testsuite/systemtap.base/tracepoints.stp @@ -0,0 +1,23 @@ +// This checks that we can compile and register every tracepoint +// we can find, along with all of their context variables. +global hits +probe all_tracepoints = kernel.trace("*") +{ + if ($$name . $$vars . $$parms == "") + next + + // Allow it to quit once we hit our hundredth tracepoint + if (++hits < 100) + next +} + +// If there aren't any tracepoints in the kernel, +// we use "begin" instead to quit right away. +probe all_tracepoints!, begin { + println("tracepoints OK") + exit() +} + +// give hits a use so there's no warning +// when we don't have tracepoints +probe never { hits++ } -- cgit From 96b030fe8a0bb0297d23638e2975a3e9eb2b85b6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 12 Mar 2009 10:11:59 -0700 Subject: Simplify tracepoint registrations Instead of registering tracepoints with the deeply-nested if-tree, which was cluttering the module_init/exit, this now emits normalized reg/unreg functions for each tracepoint probes. Now the module_init/exit can be a simple loop like all of the other probe types. --- tapsets.cxx | 71 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 7f6ca721..b02e2cce 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9732,12 +9732,15 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) if (probes.empty()) return; - s.op->newline() << "/* ---- tracepointer probes ---- */"; + s.op->newline() << "/* ---- tracepoint probes ---- */"; + s.op->newline(); for (unsigned i = 0; i < probes.size(); ++i) { tracepoint_derived_probe *p = probes[i]; - s.op->newline(); + + // emit a separate entry function for each probe, since tracepoints + // don't provide any sort of context pointer. s.op->newline() << "#include <" << p->header << ">"; s.op->newline() << "static void enter_tracepoint_probe_" << i << "("; for (unsigned j = 0; j < p->args.size(); ++j) @@ -9765,8 +9768,34 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << p->name << " (c);"; common_probe_entryfn_epilogue (s.op); s.op->newline(-1) << "}"; + + // emit normalized registration functions + s.op->newline() << "static int register_tracepoint_probe_" << i << "(void) {"; + s.op->newline(1) << "return register_trace_" << p->tracepoint_name + << "(enter_tracepoint_probe_" << i << ");"; + s.op->newline(-1) << "}"; + s.op->newline() << "static int unregister_tracepoint_probe_" << i << "(void) {"; + s.op->newline(1) << "return unregister_trace_" << p->tracepoint_name + << "(enter_tracepoint_probe_" << i << ");"; + s.op->newline(-1) << "}"; s.op->newline(); } + + // emit an array of registration functions for easy init/shutdown + s.op->newline() << "static struct stap_tracepoint_probe {"; + s.op->newline(1) << "int (*reg)(void);"; + s.op->newline(0) << "int (*unreg)(void);"; + s.op->newline(-1) << "} stap_tracepoint_probes[] = {"; + s.op->indent(1); + for (unsigned i = 0; i < probes.size(); ++i) + { + s.op->newline () << "{"; + s.op->line() << " .reg=®ister_tracepoint_probe_" << i << ","; + s.op->line() << " .unreg=&unregister_tracepoint_probe_" << i; + s.op->line() << " },"; + } + s.op->newline(-1) << "};"; + s.op->newline(); } @@ -9777,28 +9806,14 @@ tracepoint_derived_probe_group::emit_module_init (systemtap_session &s) return; s.op->newline() << "/* init tracepoint probes */"; - - // We can't use a simple runtime loop because the probe registration - // functions are distinct inlines. Instead, this will generate nesting as - // deep as the number of probe points. Gotos are also possible, but the end - // result is the same. - - for (unsigned i = 0; i < probes.size(); ++i) - { - s.op->newline() << "if (!rc) {"; - s.op->newline(1) << "probe_point = " - << lex_cast_qstring (*probes[i]->sole_location()) << ";"; - s.op->newline() << "rc = register_trace_" << probes[i]->tracepoint_name - << "(enter_tracepoint_probe_" << i << ");"; - } - - for (unsigned i = probes.size() - 1; i < probes.size(); --i) - { - s.op->newline() << "if (rc)"; - s.op->newline(1) << "unregister_trace_" << probes[i]->tracepoint_name - << "(enter_tracepoint_probe_" << i << ");"; - s.op->newline(-2) << "}"; - } + s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {"; + s.op->newline(1) << "rc = stap_tracepoint_probes[i].reg();"; + s.op->newline() << "if (rc) {"; + s.op->newline(1) << "for (j=i-1; j>=0; j--)"; // partial rollback + s.op->newline(1) << "stap_tracepoint_probes[j].unreg();"; + s.op->newline(-1) << "break;"; // don't attempt to register any more probes + s.op->newline(-1) << "}"; + s.op->newline(-1) << "}"; // This would be technically proper (on those autoconf-detectable // kernels that include this function in tracepoint.h), however we @@ -9817,10 +9832,10 @@ tracepoint_derived_probe_group::emit_module_exit (systemtap_session& s) if (probes.empty()) return; - s.op->newline() << "/* deregister tracepointer probes */"; - for (unsigned i = 0; i < probes.size(); ++i) - s.op->newline() << "unregister_trace_" << probes[i]->tracepoint_name - << "(enter_tracepoint_probe_" << i << ");"; + s.op->newline() << "/* deregister tracepoint probes */"; + s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)"; + s.op->newline(1) << "stap_tracepoint_probes[i].unreg();"; + s.op->indent(-1); // Not necessary: see above. -- cgit