This is the mail archive of the frysk-cvs@sources.redhat.com mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[SCM] master: Support signal tracing in ftrace


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]