public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: pmachata@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Support signal tracing in ftrace
Date: Fri, 29 Feb 2008 17:00:00 -0000	[thread overview]
Message-ID: <20080229170040.4150.qmail@sourceware.org> (raw)

The branch, master has been updated
       via  71bf7fec6d61c9c72ab11f33e9c327e2e88ca5fc (commit)
      from  a310d922f9802d47970cf04da6d3ba45cae2f117 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 71bf7fec6d61c9c72ab11f33e9c327e2e88ca5fc
Author: Petr Machata <pmachata@redhat.com>
Date:   Fri Feb 29 17:55:16 2008 +0100

    Support signal tracing in ftrace
    
    * ... and cleanup duplications in ftrace.java code a bit.
    * ... and only actually request syscall/signal tracing when the user wants to.
    * ... and fix small typo (at least I hope it was a typo!) in Signal.java-sh.

-----------------------------------------------------------------------

Summary of changes:
 frysk-core/frysk/bindir/ChangeLog   |   19 +++
 frysk-core/frysk/bindir/ftrace.java |  232 ++++++++++++++++++++---------------
 frysk-core/frysk/bindir/ftrace.xml  |   64 ++++++----
 frysk-core/frysk/ftrace/ChangeLog   |   11 ++
 frysk-core/frysk/ftrace/Ftrace.java |   78 ++++++++++--
 frysk-sys/frysk/sys/ChangeLog       |    4 +
 frysk-sys/frysk/sys/Signal.java-sh  |    2 +-
 7 files changed, 272 insertions(+), 138 deletions(-)

First 500 lines of diff:
diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog
index b4b4092..629f309 100644
--- a/frysk-core/frysk/bindir/ChangeLog
+++ b/frysk-core/frysk/bindir/ChangeLog
@@ -1,3 +1,22 @@
+2008-02-29  Petr Machata  <pmachata@redhat.com>
+
+	* ftrace.java: Support signal tracing, cleanups.
+	(SyscallRule): Deleted class.
+	(ByNumberSyscallRule): Deleted class.
+	(ByRegexpSyscallRule): Deleted class.
+	(MyFtraceController.sigRules): New field.
+	(MyFtraceController.computeWorkingSet): New method.
+	(MyFtraceController.computeSyscallWorkingSet): Use computeWorkingSet.
+	(MyFtraceController.computeSignalWorkingSet): New method.
+	(ftrace.tracedCalls): Delete unused field.
+	(ftrace.sigRules): New field.
+	(ftrace.parseSyscallRules): New method.
+	(ftrace.TraceableExaminer): New interface.
+	(ftrace.parseSyscallRules): Rename to parseSigSysRules, use
+	examiner to generalize over both types of traceables.
+	(ftrace.run): Rewrite to only request tracing when rules are present.
+	* ftrace.xml: Update.
+
 2008-02-29  Andrew Cagney  <cagney@redhat.com>
 
 	* ftrace.java: Glob moved to frysk.util.Glob.
diff --git a/frysk-core/frysk/bindir/ftrace.java b/frysk-core/frysk/bindir/ftrace.java
index da886bb..35c76da 100644
--- a/frysk-core/frysk/bindir/ftrace.java
+++ b/frysk-core/frysk/bindir/ftrace.java
@@ -40,7 +40,8 @@
 package frysk.bindir;
 
 import inua.util.PrintWriter;
-import frysk.util.Util;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -49,28 +50,26 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import frysk.proc.Proc;
 import java.util.logging.*;
 import java.util.regex.Pattern;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-
-import frysk.isa.syscalls.SyscallTable;
-import frysk.isa.syscalls.Syscall;
-import frysk.proc.Task;
-
-import frysk.util.CommandlineParser;
 
 import frysk.ftrace.Ftrace;
 import frysk.ftrace.ObjectFile;
+import frysk.ftrace.Symbol;
 import frysk.ftrace.TracePoint;
 import frysk.ftrace.TracePointOrigin;
-import frysk.ftrace.Symbol;
-
-import lib.dwfl.ElfSymbolVersion;
+import frysk.isa.signals.Signal;
+import frysk.isa.signals.SignalTable;
+import frysk.isa.syscalls.Syscall;
+import frysk.isa.syscalls.SyscallTable;
+import frysk.proc.Proc;
+import frysk.proc.Task;
+import frysk.util.CommandlineParser;
 import frysk.util.Glob;
+import frysk.util.Util;
 import gnu.classpath.tools.getopt.Option;
 import gnu.classpath.tools.getopt.OptionException;
+import lib.dwfl.ElfSymbolVersion;
 
 abstract class Rule
 {
@@ -198,52 +197,11 @@ class SymbolRule
     }
 }
 
-class SyscallRule
-    extends Rule
-{
-    public SyscallRule(boolean addition, boolean stackTrace) {
-	super (addition, stackTrace);
-    }
-
-    public boolean matches(Object traceable) {
-	return true;
-    }
-}
-
-class ByNumberSyscallRule
-    extends SyscallRule
-{
-    long number;
-    public ByNumberSyscallRule(boolean addition, boolean stackTrace, long number) {
-	super (addition, stackTrace);
-	this.number = number;
-    }
-
-    public boolean matches(Object traceable) {
-	Syscall syscall = (Syscall)traceable;
-	return syscall.getNumber() == number;
-    }
-}
-
-class ByRegexpSyscallRule
-    extends SyscallRule
-{
-    Pattern pattern;
-    public ByRegexpSyscallRule(boolean addition, boolean stackTrace, String regexp) {
-	super (addition, stackTrace);
-	this.pattern = Glob.compile(regexp);
-    }
-
-    public boolean matches(Object traceable) {
-	Syscall syscall = (Syscall)traceable;
-	return this.pattern.matcher(syscall.getName()).matches();
-    }
-}
-
 class MyFtraceController
     implements Ftrace.Controller,
 	       Ftrace.StackTracedSymbolsProvider,
-	       Ftrace.TracedSyscallProvider
+	       Ftrace.TracedSyscallProvider,
+	       Ftrace.TracedSignalProvider
 {
     protected static final Logger logger = Logger.getLogger("frysk");
 
@@ -252,6 +210,7 @@ class MyFtraceController
     private final List dynRules = new ArrayList();
     private final List symRules = new ArrayList();
     private final List sysRules = new ArrayList();
+    private final List sigRules = new ArrayList();
 
     // Which symbols should yield a stack trace.
     private HashSet symbolsStackTraceSet = new HashSet();
@@ -288,19 +247,18 @@ class MyFtraceController
 	this.sysRules.addAll(rules);
     }
 
-    // Syscall working and stack trace sets can be pre-computed for
-    // each task.  This is in contrast to tracing rules, that are
-    // computed incrementally when DSOs are mapped.
-    public Map computeSyscallWorkingSet(Task task) {
+    public void gotSigRules(List rules) {
+	logger.log(Level.FINER, "Got " + rules.size() + " signal rules.");
+	this.sigRules.addAll(rules);
+    }
+
+    private Map computeWorkingSet(Task task, String what,
+				 List rules, ArrayList candidates)
+    {
 	HashSet workingSet = new HashSet();
 	HashSet stackTraceSet = new HashSet();
-	SyscallTable syscallTable = task.getSyscallTable();
-	long n = syscallTable.getNumSyscalls();
-	ArrayList candidates = new ArrayList();
-	for (long i = 0; i < n; ++i)
-	    candidates.add(syscallTable.getSyscall(i));
 
-	for (Iterator it = sysRules.iterator(); it.hasNext(); ) {
+	for (Iterator it = rules.iterator(); it.hasNext(); ) {
 	    final Rule rule = (Rule)it.next();
 	    logger.log(Level.FINEST, "Considering syscall rule " + rule + ".");
 	    rule.apply(logger, candidates, workingSet, stackTraceSet);
@@ -316,6 +274,31 @@ class MyFtraceController
 	return ret;
     }
 
+    // Syscall working and stack trace sets can be pre-computed for
+    // each task.  This is in contrast to tracing rules, that are
+    // computed incrementally when DSOs are mapped.
+    public Map computeSyscallWorkingSet(Task task) {
+	SyscallTable syscallTable = task.getSyscallTable();
+	long n = syscallTable.getNumSyscalls();
+	ArrayList candidates = new ArrayList();
+	for (long i = 0; i < n; ++i)
+	    candidates.add(syscallTable.getSyscall(i));
+
+	return computeWorkingSet(task, "syscall", sysRules, candidates);
+    }
+
+    // Compute signal working and stack trace sets.
+    public Map computeSignalWorkingSet(Task task) {
+	frysk.sys.Signal[] hostSignals
+	    = frysk.sys.Signal.getHostSignalSet().toArray();
+	SignalTable signalTable = task.getSignalTable();
+	ArrayList candidates = new ArrayList();
+	for (int i = 0; i < hostSignals.length; i++)
+	    candidates.add(signalTable.get(hostSignals[i].intValue()));
+
+	return computeWorkingSet(task, "signal", sigRules, candidates);
+    }
+
     private boolean isInterpOf(ObjectFile objf, String exe)
     {
 	java.io.File exefn = new java.io.File(exe);
@@ -402,19 +385,19 @@ class ftrace
 
     protected static final Logger logger = Logger.getLogger("frysk");
 
-    // Set of all Syscalls we want to trace.
-    // This is null if the user hasn't specified any.
-    HashSet tracedCalls;
     // True if a PID was requested.
     boolean requestedPid;
     // Command and arguments to exec.
     ArrayList commandAndArguments;
 
-    // For Ltrace.
+    // For configuration of overall working set.  We need to load and
+    // apply rules separately, to get all log messages, that's the
+    // reason we need these temporary array lists.
     final List pltRules = new ArrayList();
     final List dynRules = new ArrayList();
     final List symRules = new ArrayList();
     final List sysRules = new ArrayList();
+    final List sigRules = new ArrayList();
     final MyFtraceController controller = new MyFtraceController();
     boolean allowInterpTracing = false;
 
@@ -478,15 +461,21 @@ class ftrace
 	return rules;
     }
 
-    private List parseSyscallRules(String arg) {
+    private static interface TraceableExaminer {
+	int traceableNumber(Object traceable);
+	String traceableName(Object traceable);
+    }
+
+    private List parseSigSysRules(String arg, final TraceableExaminer examiner) {
 	String[] strs = arg.split(",", -1);
 	Pattern sysnumPat = Pattern.compile("[0-9]+");
 	List rules = new ArrayList();
 	for (int i = 0; i < strs.length; ++i) {
-	    // 14, SYS14: syscall number 14
-	    // otherwise: syscall whose name matches regular expression
+	    // "14": traceable number 14
+	    // "foo*": traceable whose name matches glob
+	    // "": wildcard matching all traceables
 	    String str = strs[i];
-	    final SyscallRule rule;
+	    final Rule rule;
 	    final boolean addition;
 	    final boolean stackTrace;
 
@@ -506,18 +495,30 @@ class ftrace
 
 	    if (sysnumPat.matcher(str).matches()) {
 		logger.log(Level.FINE, i + ": " + str + ": by number rule");
-		if (str.startsWith("SYS"))
-		    str = str.substring(3);
-		long sysnum = (new Long(str)).longValue();
-		rule = new ByNumberSyscallRule(addition, stackTrace, sysnum);
+		final int number = (new Integer(str)).intValue();
+		rule = new Rule(addition, stackTrace) {
+			public boolean matches(final Object traceable) {
+			    return number == examiner.traceableNumber(traceable);
+			}
+		    };
 	    }
 	    else if (!str.equals("")) {
-		logger.log(Level.FINE, i + ": " + str + ": by regexp rule");
-		rule = new ByRegexpSyscallRule(addition, stackTrace, str);
+		logger.log(Level.FINE, i + ": " + str + ": by name rule");
+		final Pattern pattern = Glob.compile(str);
+		rule = new Rule(addition, stackTrace) {
+			public boolean matches(final Object traceable) {
+			    String name = examiner.traceableName(traceable);
+			    return pattern.matcher(name).matches();
+			}
+		    };
 	    }
 	    else {
 		logger.log(Level.FINE, i + ": " + str + ": \"everything\" rule");
-		rule = new SyscallRule(addition, stackTrace);
+		rule = new Rule(addition, stackTrace) {
+			public boolean matches(Object traceable) {
+			    return true;
+			}
+		    };
 	    }
 
 	    rules.add(rule);
@@ -576,6 +577,13 @@ class ftrace
           }
         });
 
+        parser.add(new Option("sig", "trace signals", "SIG[,SIG]...") {
+		public void parsed(String arg) throws OptionException
+		{
+		    sigRules.add(arg);
+		}
+        });
+
         parser.add(new Option("sys", "trace system calls", "CALL[,CALL]...") {
 		public void parsed(String arg) throws OptionException
 		{
@@ -637,32 +645,56 @@ class ftrace
         parser.parse(args);
         if (writer == null)
             writer = new PrintWriter(System.out);
+        tracer.setWriter(writer);
 
-	// If tracing dynamic linker disabled, generate implicit
-	// -@INTERP rule at the end of the chain.
-	if (!allowInterpTracing) {
-	    if (pltRules.size() > 0)
+	if (!pltRules.isEmpty() || !dynRules.isEmpty() || !symRules.isEmpty()) {
+	    // If tracing dynamic linker disabled, generate implicit
+	    // -@INTERP rule at the end of the chain.
+	    if (!allowInterpTracing) {
 		pltRules.add("-@INTERP");
-	    if (dynRules.size() > 0)
 		dynRules.add("-@INTERP");
-	    if (symRules.size() > 0)
 		symRules.add("-@INTERP");
+	    }
+
+	    for (Iterator it = pltRules.iterator(); it.hasNext(); )
+		controller.gotPltRules(parseSymbolRules((String)it.next()));
+	    for (Iterator it = dynRules.iterator(); it.hasNext(); )
+		controller.gotDynRules(parseSymbolRules((String)it.next()));
+	    for (Iterator it = symRules.iterator(); it.hasNext(); )
+		controller.gotSymRules(parseSymbolRules((String)it.next()));
+
+	    tracer.setTraceFunctions(controller, controller);
 	}
 
-	// We need to load and apply rules separately, to get all log
-	// messages.
-	for (Iterator it = pltRules.iterator(); it.hasNext(); )
-	    controller.gotPltRules(parseSymbolRules((String)it.next()));
-	for (Iterator it = dynRules.iterator(); it.hasNext(); )
-	    controller.gotDynRules(parseSymbolRules((String)it.next()));
-	for (Iterator it = symRules.iterator(); it.hasNext(); )
-	    controller.gotSymRules(parseSymbolRules((String)it.next()));
-	for (Iterator it = sysRules.iterator(); it.hasNext(); )
-	    controller.gotSysRules(parseSyscallRules((String)it.next()));
+	if (!sysRules.isEmpty()) {
+	    TraceableExaminer syscallExaminer = new TraceableExaminer() {
+		    public int traceableNumber(Object traceable) {
+			return ((Syscall)traceable).getNumber();
+		    }
+		    public String traceableName(Object traceable) {
+			return ((Syscall)traceable).getName();
+		    }
+		};
+	    for (Iterator it = sysRules.iterator(); it.hasNext(); )
+		controller.gotSysRules(parseSigSysRules((String)it.next(),
+							syscallExaminer));
+	    tracer.setTraceSyscalls(controller);
+	}
 
-        tracer.setWriter(writer);
-	tracer.setTraceFunctions(controller, controller);
-	tracer.setTraceSyscalls(controller);
+	if (!sigRules.isEmpty()) {
+	    TraceableExaminer signalExaminer = new TraceableExaminer() {
+		    public int traceableNumber(Object traceable) {
+			return ((Signal)traceable).intValue();
+		    }
+		    public String traceableName(Object traceable) {
+			return ((Signal)traceable).getName();
+		    }
+		};
+	    for (Iterator it = sigRules.iterator(); it.hasNext(); )
+		controller.gotSigRules(parseSigSysRules((String)it.next(),
+							signalExaminer));
+	    tracer.setTraceSignals(controller);
+	}
 
         if (commandAndArguments != null) {
             String[] cmd = (String[]) commandAndArguments.toArray(new String[0]);
diff --git a/frysk-core/frysk/bindir/ftrace.xml b/frysk-core/frysk/bindir/ftrace.xml
index ab67392..1719f77 100644
--- a/frysk-core/frysk/bindir/ftrace.xml
+++ b/frysk-core/frysk/bindir/ftrace.xml
@@ -74,6 +74,7 @@
       <arg choice="opt">-o=<replaceable>FILE</replaceable></arg>
       <arg choice="opt" rep="repeat">-p=<replaceable>PID</replaceable></arg>
       <arg choice="opt">-sys=<replaceable>SYSCALL</replaceable>[,<replaceable>SYSCALL</replaceable>...]</arg>
+      <arg choice="opt">-sig=<replaceable>SIG</replaceable>[,<replaceable>SIG</replaceable>...]</arg>
       <arg choice="opt">-plt=<replaceable>RULE</replaceable>[,<replaceable>RULE</replaceable>...]</arg>
       <arg choice="opt">-dyn=<replaceable>RULE</replaceable>[,<replaceable>RULE</replaceable>...]</arg>
       <arg choice="opt">-sym=<replaceable>RULE</replaceable>[,<replaceable>RULE</replaceable>...]</arg>
@@ -118,20 +119,30 @@
     </refsect2>
 
     <refsect2>
-	<title>System Call Tracing</title>
+	<title>System Call and Signal Tracing</title>
 
 	<variablelist>
 	  <varlistentry>
 	    <term>-sys=<replaceable>SYSCALL</replaceable>[,<replaceable>SYSCALL</replaceable>...]</term>
 	    <listitem>
 	      <para>Trace system calls that match given
-	      <replaceable>SYSCALL</replaceable> ruleset are.  See
+	      <replaceable>SYSCALL</replaceable> ruleset.  See
 	      below for description of
 	      <replaceable>SYSCALL</replaceable> syntax.</para>
 	    </listitem>
 	  </varlistentry>
 
 	  <varlistentry>
+	    <term>-sig=<replaceable>SIGNAL</replaceable>[,<replaceable>SIGNAL</replaceable>...]</term>
+	    <listitem>
+	      <para>Trace signals that match given
+	      <replaceable>SIGNAL</replaceable> ruleset.  See
+	      below for description of
+	      <replaceable>SIGNAL</replaceable> syntax.</para>
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
 	    <term>-stack</term>
 	    <listitem>
 	      <para>Stack trace when traced system call is hit.  Note
@@ -246,7 +257,7 @@
     that the call should still be traced, but stack trace shouldn't be
     generated.  <replaceable>pattern</replaceable> defines which PLT
     entries from which libraries should be added or removed from
-    working set.  Syntax of pattern is the following:</para>
+    working sennt.  Syntax of pattern is the following:</para>
 
     <para><optional><replaceable>symbol</replaceable></optional><optional>@<replaceable>soname</replaceable></optional><optional>@@<replaceable>version</replaceable></optional></para>
 
@@ -276,34 +287,38 @@
     is possible to request symbol without a version with the pattern
     "foo@@".)</para>
 
-    <para>Empty rule is considered to miss all components.  If you
-    need to match an empty symbol, use regular expression "^$".</para>
+    <para>Empty rule is considered to miss all components.</para>
   </refsect1>
 
   <refsect1>
-    <title>SYSCALL RULE SYNTAX</title>
+    <title>SYSCALL AND SIGNAL RULE SYNTAX</title>
 
-    <para>Under the presence of the <option>-sys</option> option, all
-    system calls are always traced.  This is a limitation of the
-    ptrace layer.  The system call rules however serve as a simple way
-    of filtering the output.</para>
+    <para>Under the presence of the <option>-sys</option> (or
+    <option>-sig</option>) option, ALL system calls (or signals) are
+    ALWAYS traced.  This is a limitation of the ptrace layer.  The
+    system call and signal rules however serve as a simple way of
+    filtering out the output that you are not interested in.  In
+    following paragraphs, the word &quot;event&quot; will be used to
+    mean &quot;signal or syscall, whatever applies&quot;.</para>
 
-    <para>System call rule syntax and semantics are the same as the
-    symbol rule syntax:</para>
+    <para>The system call and signal rule syntax and semantics are the
+    same as the symbol rule syntax:</para>
 
     <para>[-][#]<replaceable>pattern</replaceable></para>
 
-    <para>System call selection pattern syntax is then as
-    follows:</para>
+    <para>Event selection pattern syntax is then as follows:</para>
 
     <para><optional><replaceable>syscall name</replaceable>|<replaceable>syscall number</replaceable></optional></para>
+    <para><optional><replaceable>SIGNAME</replaceable>|<replaceable>signal number</replaceable></optional></para>
+
+    <para>When the pattern is empty, then it matches all events known
+    to frysk.  When the pattern is simple number (e.g.
+    &quot;12&quot;), then the pattern matches the event with the given
+    number.  Otherwise the pattern is considered to be written using
+    glob syntax, and matched against event names.</para>
 
-    <para>When the pattern is empty, then it matches all system calls
-    known to frysk.  When the pattern is simple number
-    (e.g. &quot;12&quot;), then the pattern matches system call with
-    the given number.  Otherwise the pattern is considered to be
-    written using extended regular expression syntax, and matched
-    agains system call names.</para>
+    <para>Signal names have to be given in upper case and include the
+    leading &quot;SIG&quot;.</para>
   </refsect1>
 
   <refsect1>
@@ -313,18 +328,18 @@
       <para>Trace all system calls:</para>
       <cmdsynopsis><command>ftrace -sys= ls</command></cmdsynopsis>
       <para>Trace variants of stat system call and moreover a system call #3:</para>
-      <cmdsynopsis><command>ftrace -sys=&quot;.*stat.*&quot;,3 ls</command></cmdsynopsis>
+      <cmdsynopsis><command>ftrace -sys=&apos;*stat*,3&apos; ls</command></cmdsynopsis>
       <para>Trace all library calls:</para>
       <cmdsynopsis><command>ftrace -plt= ls</command></cmdsynopsis>


hooks/post-receive
--
frysk system monitor/debugger


                 reply	other threads:[~2008-02-29 17:00 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080229170040.4150.qmail@sourceware.org \
    --to=pmachata@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).