public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Fix TestFtrace to use -sys commandline option
@ 2008-02-07 19:28 pmachata
  0 siblings, 0 replies; only message in thread
From: pmachata @ 2008-02-07 19:28 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  eac0c5123c615be6efa3ca1738175ea0a59be132 (commit)
       via  21a3a0c9c925dedd11d3d808c9e542930fb44197 (commit)
       via  9ca35ed4d1a06162a77b0030143cb4591e3ac69c (commit)
      from  0fb13e7cc5f975675b50a0e349db34cbcdb0470d (commit)

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

- Log -----------------------------------------------------------------
commit eac0c5123c615be6efa3ca1738175ea0a59be132
Author: Petr Machata <pmachata@redhat.com>
Date:   Thu Feb 7 20:25:50 2008 +0100

    Fix TestFtrace to use -sys commandline option

commit 21a3a0c9c925dedd11d3d808c9e542930fb44197
Author: Petr Machata <pmachata@redhat.com>
Date:   Thu Feb 7 17:52:37 2008 +0100

    Support fine-grained selection of syscalls to trace
    
    * Option -sys, behaves much like -plt/-sym/-dyn (no @/@@ support)
    * The code calls for some refactoring, there's a lot of duplication.

commit 9ca35ed4d1a06162a77b0030143cb4591e3ac69c
Author: Petr Machata <pmachata@redhat.com>
Date:   Thu Feb 7 17:34:22 2008 +0100

    Making SyscallTable more public about its syscalls
    
    * getNumSyscalls: public function answers number of entries in system call table.
    * getSyscall(long): has become public

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

Summary of changes:
 frysk-core/frysk/bindir/ChangeLog                  |   15 +-
 frysk-core/frysk/bindir/TestFtrace.java            |    4 +
 frysk-core/frysk/bindir/ftrace.java                |  266 +++++++++++++++-----
 frysk-core/frysk/ftrace/ChangeLog                  |   11 +
 frysk-core/frysk/ftrace/Ftrace.java                |  109 +++++----
 frysk-core/frysk/isa/syscalls/ChangeLog            |    9 +
 .../frysk/isa/syscalls/LinuxIA32SyscallTable.java  |    6 +-
 .../frysk/isa/syscalls/LinuxPPC32SyscallTable.java |    6 +-
 .../frysk/isa/syscalls/LinuxPPC64SyscallTable.java |    6 +-
 .../frysk/isa/syscalls/LinuxX8664SyscallTable.java |    6 +-
 frysk-core/frysk/isa/syscalls/SyscallTable.java    |    7 +-
 11 files changed, 332 insertions(+), 113 deletions(-)

First 500 lines of diff:
diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog
index 5525a65..ee65d19 100644
--- a/frysk-core/frysk/bindir/ChangeLog
+++ b/frysk-core/frysk/bindir/ChangeLog
@@ -2,10 +2,21 @@
 
 	* fmaps.java: Refactor to use ProcStopUtil.
 
+2008-02-07  Petr Machata  <pmachata@redhat.com>
+
+	* ftrace.java: Support fine-grained selection of syscalls to
+	trace/stack trace on.  Remove -t, -s options.
+	(Rule): New abstract class.
+	(SyscallRule, ByNumberSyscallRule, ByRegexpSyscallRule): New classes.
+	(MyFtraceController.sysRules): New variable.
+	(.gotSysRules): New method.
+	(.computeSyscallWorkingSet): New method.
+	(.parseSyscallRules): New method.
+
 2008-02-07  Andrew Cagney  <cagney@redhat.com>
-	
+
 	* fstep.java: Update to use Host.requestProc(int,FindProc).
-	
+
 2008-02-06  Teresa Thomas  <tthomas@redhat.com>
 
 	* fdebuginfo.java: Refactor, use ProcStopUtil.
diff --git a/frysk-core/frysk/bindir/TestFtrace.java b/frysk-core/frysk/bindir/TestFtrace.java
index d887ed7..1692d7c 100644
--- a/frysk-core/frysk/bindir/TestFtrace.java
+++ b/frysk-core/frysk/bindir/TestFtrace.java
@@ -62,6 +62,7 @@ public class TestFtrace extends TestLib {
 	    return;
 	TearDownExpect e = new TearDownExpect(new String[] {
 		Config.getBinFile("ftrace").getAbsolutePath(),
+		"-sys=",
 		"/bin/ls"
 	    });
 	e.expect("execve");
@@ -74,6 +75,7 @@ public class TestFtrace extends TestLib {
 	Task task = child.findTaskUsingRefresh(true);
 	TearDownExpect e = new TearDownExpect(new String[] {
 		Config.getBinFile("ftrace").getAbsolutePath(),
+		"-sys=",
 		""+task.getProc().getPid()
 	    });
 	e.expect(""+task.getProc().getPid()+"."+ task.getTid());
@@ -88,6 +90,7 @@ public class TestFtrace extends TestLib {
 	Task task = child.findTaskUsingRefresh(true);
         TearDownExpect e = new TearDownExpect(new String[] {
 		Config.getBinFile("ftrace").getAbsolutePath(),
+		"-sys=",
 		"-c",
 		""+task.getProc().getPid()
 	    });
@@ -100,6 +103,7 @@ public class TestFtrace extends TestLib {
     public void testFtraceHandlesPrcoessNotFound() {
 	TearDownExpect e = new TearDownExpect(new String[] {
 		Config.getBinFile("ftrace").getAbsolutePath(),
+		"-sys=",
 		"0"
 	    });
 	e.expect("No process with ID 0 found");
diff --git a/frysk-core/frysk/bindir/ftrace.java b/frysk-core/frysk/bindir/ftrace.java
index 9dde5c7..2a6501b 100644
--- a/frysk-core/frysk/bindir/ftrace.java
+++ b/frysk-core/frysk/bindir/ftrace.java
@@ -42,17 +42,21 @@ package frysk.bindir;
 import inua.util.PrintWriter;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
-import java.util.StringTokenizer;
 import java.util.logging.*;
 import java.util.regex.*;
 
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 
+import frysk.isa.syscalls.SyscallTable;
+import frysk.isa.syscalls.Syscall;
+
 import frysk.proc.ProcId;
 import frysk.proc.Task;
 
@@ -69,41 +73,103 @@ import lib.dwfl.ElfSymbolVersion;
 import gnu.classpath.tools.getopt.Option;
 import gnu.classpath.tools.getopt.OptionException;
 
-class WorkingSetRule
+abstract class Rule
 {
     final public boolean addition;
     final public boolean stackTrace;
 
-    /**
-     * Object that performs a pattern matching of symbol
-     * name. null for "anything" matcher.
-     */
-    final public Pattern namePattern;
+    protected Rule(boolean addition, boolean stackTrace) {
+	this.addition = addition;
+	this.stackTrace = stackTrace;
+    }
+
+    public String toString() {
+	return ""
+	    + (this.addition ? "" : "-")
+	    + (this.stackTrace ? "#" : "");
+    }
+
+    abstract public boolean matches(Object traceable);
+}
 
+class WorkingSetRule
+    extends Rule
+{
     /** See namePattern */
     final public Pattern sonamePattern, versionPattern;
 
-    public WorkingSetRule(boolean addition, boolean stackTrace, String nameRe, String sonameRe, String versionRe) {
-	this.addition = addition;
-	this.stackTrace = stackTrace;
-	this.namePattern = Pattern.compile((nameRe != null) ? nameRe : ".*");
+    /**
+     * Object that performs a pattern matching of a symbol name. null
+     * for "anything" matcher.
+     */
+    final public Pattern namePattern;
+
+    public WorkingSetRule(boolean addition, boolean stackTrace,
+			  String nameRe, String sonameRe, String versionRe) {
+	super (addition, stackTrace);
 	this.sonamePattern = Pattern.compile((sonameRe != null) ? sonameRe : ".*");
 	this.versionPattern = Pattern.compile((versionRe != null) ? versionRe : ".*");
+	this.namePattern = Pattern.compile((nameRe != null) ? nameRe : ".*");
     }
 
     public String toString() {
-	return ""
-	    + (this.addition ? "" : "-")
-	    + (this.stackTrace ? "#" : "")
+	return super.toString()
 	    + this.namePattern.pattern()
 	    + "@" + this.sonamePattern.pattern()
 	    + "@@" + this.versionPattern.pattern();
     }
+
+    public boolean matches(Object traceable) {
+	throw new AssertionError("NYI");
+    }
+}
+
+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 = Pattern.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.StackTracedSymbolsProvider,
+	       Ftrace.TracedSyscallProvider
 {
     protected static final Logger logger = Logger.getLogger("frysk");
 
@@ -111,11 +177,12 @@ class MyFtraceController
     private final List pltRules = new ArrayList();
     private final List dynRules = new ArrayList();
     private final List symRules = new ArrayList();
+    private final List sysRules = new ArrayList();
 
     // Which symbols should yield a stack trace.
     private HashSet symbolsStackTraceSet = new HashSet();
 
-    public boolean shouldStackTraceOn(Symbol symbol) {
+    public boolean shouldStackTraceOnSymbol(Symbol symbol) {
 	return symbolsStackTraceSet.contains(symbol);
     }
 
@@ -136,6 +203,11 @@ class MyFtraceController
 	this.symRules.addAll(rules);
     }
 
+    public void gotSysRules(List rules) {
+	logger.log(Level.FINER, "Got " + rules.size() + " syscall rules.");
+	this.sysRules.addAll(rules);
+    }
+
     private boolean checkVersionMatches(final TracePoint tp, final WorkingSetRule rule)
     {
 	ElfSymbolVersion[] vers = (tp.origin == TracePointOrigin.PLT)
@@ -178,6 +250,59 @@ class MyFtraceController
 	return false;
     }
 
+    public Map computeSyscallWorkingSet(Task task) {
+	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(); ) {
+	    final Rule rule = (Rule)it.next();
+	    logger.log(Level.FINEST, "Considering syscall rule " + rule + ".");
+
+	    if (rule.addition)
+		// For '+' rules iterate over candidates,
+		// and add what matches to workingSet, and
+		// maybe to stackTraceSet.
+		for (Iterator jt = candidates.iterator(); jt.hasNext(); ) {
+		    Object candidate = jt.next();
+		    if (rule.matches(candidate)) {
+			if (workingSet.add(candidate))
+			    logger.log(Level.CONFIG, rule + ": add `" + candidate + "'.");
+			if (rule.stackTrace
+			    && stackTraceSet.add(candidate))
+			    logger.log(Level.CONFIG, rule + ": stack trace on `" + candidate + "'.");
+		    }
+		}
+	    else {
+		// For '-' or '-#' rules iterate over
+		// workingSet or stackTraceSet, and remove
+		// what matches.
+		Set iterateOver = rule.stackTrace ? stackTraceSet : workingSet;
+		for (Iterator jt = iterateOver.iterator(); jt.hasNext(); ) {
+		    Object candidate = jt.next();
+		    if (rule.matches(candidate)) {
+			jt.remove();
+			if (!rule.stackTrace)
+			    stackTraceSet.remove(candidate);
+			logger.log(Level.CONFIG, rule + ": remove `" + candidate + "'.");
+		    }
+		}
+	    }
+	}
+
+	// Apply the two sets.
+	Map ret = new HashMap();
+	for (Iterator it = workingSet.iterator(); it.hasNext(); ) {
+	    Object syscall = it.next();
+	    ret.put(syscall, Boolean.valueOf(stackTraceSet.contains(syscall)));
+	}
+	return ret;
+    }
+
     private boolean isInterpOf(ObjectFile objf, String exe)
     {
 	java.io.File exefn = new java.io.File(exe);
@@ -204,6 +329,8 @@ class MyFtraceController
 	// Set<TracePoint>, incrementally built set of tracepoints
 	// that should stacktrace.
 	final Set stackTraceSet = new HashSet();
+
+	// Do a lazy init.  With symbol tables this can be very beneficial, because certain symbol 
 	boolean candidatesInited = false;
 
 	// Loop through all the rules, and use them to build
@@ -211,7 +338,7 @@ class MyFtraceController
 	// lazily inside the loop.
 	for (Iterator it = rules.iterator(); it.hasNext(); ) {
 	    final WorkingSetRule rule = (WorkingSetRule)it.next();
-	    logger.log(Level.FINEST, "Considering rule " + rule + ".");
+	    logger.log(Level.FINEST, "Considering symbol rule " + rule + ".");
 
 	    // MAIN is meta-soname meaning "main executable".
 	    if ((rule.sonamePattern.pattern().equals("MAIN")
@@ -305,12 +432,13 @@ class ftrace
     final List pltRules = new ArrayList();
     final List dynRules = new ArrayList();
     final List symRules = new ArrayList();
+    final List sysRules = new ArrayList();
     final MyFtraceController controller = new MyFtraceController();
     boolean allowInterpTracing = false;
 
     Ftrace tracer = new Ftrace();
 
-    private List parseRules(String arg) {
+    private List parseSymbolRules(String arg) {
 	String[] strs = arg.split(",", -1);
 	List rules = new ArrayList();
 	for (int i = 0; i < strs.length; ++i) {
@@ -368,6 +496,53 @@ class ftrace
 	return rules;
     }
 
+    private List parseSyscallRules(String arg) {
+	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
+	    String str = strs[i];
+	    final SyscallRule rule;
+	    final boolean addition;
+	    final boolean stackTrace;
+
+	    if (str.length() > 0 && str.charAt(0) == '-') {
+		addition = false;
+		str = str.substring(1);
+	    }
+	    else
+		addition = true;
+
+	    if (str.length() > 0 && str.charAt(0) == '#') {
+		stackTrace = true;
+		str = str.substring(1);
+	    }
+	    else
+		stackTrace = false;
+
+	    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);
+	    }
+	    else if (!str.equals("")) {
+		logger.log(Level.FINE, i + ": " + str + ": by regexp rule");
+		rule = new ByRegexpSyscallRule(addition, stackTrace, str);
+	    }
+	    else {
+		logger.log(Level.FINE, i + ": " + str + ": \"everything\" rule");
+		rule = new SyscallRule(addition, stackTrace);
+	    }
+
+	    rules.add(rule);
+	}
+	return rules;
+    }
+
     private void addOptions(CommandlineParser parser)
     {
         parser.add(new Option('o', "output file name", "FILE") {
@@ -391,22 +566,6 @@ class ftrace
             }
         });
 
-	parser.add(new Option("trace", 't', "syscalls to trace", "CALL[,CALL]...") {
-            public void parsed(String arg) throws OptionException
-            {
-                StringTokenizer st = new StringTokenizer(arg, ",");
-                while (st.hasMoreTokens())
-                {
-                    String name = st.nextToken();
-                    // FIXME: there's no good way to error out if the
-                    // syscall is unknown.
-                    if (tracedCalls == null)
-                        tracedCalls = new HashSet();
-                    tracedCalls.add(name);
-                }
-            }
-        });
-
 	parser.add(new Option('p', "pid to trace", "PID") {
             public void parsed(String arg) throws OptionException
             {
@@ -422,29 +581,6 @@ class ftrace
             }
         });
 
-        parser.add(new Option('s', "stack trace system calls", "CALL[,CALL]...") {
-          public void parsed(String arg) throws OptionException
-          {
-            StringTokenizer st = new StringTokenizer(arg, ",");
-            HashSet set = new HashSet(2);
-            while (st.hasMoreTokens())
-            {
-                String name = st.nextToken();
-                // FIXME: there's no good way to error out if the
-                // syscall is unknown.
-                set.add(name);
-            }
-            tracer.setSyscallStackTracing(set);
-          }
-        });
-
-        parser.add(new Option('S', "don't trace system calls") {
-          public void parsed(String arg) throws OptionException
-          {
-	      tracer.setDontTraceSyscalls();
-          }
-        });
-
         parser.add(new Option('m', "print out when library is mapped or unmapped") {
           public void parsed(String arg) throws OptionException
           {
@@ -459,6 +595,13 @@ class ftrace
           }
         });
 
+        parser.add(new Option("sys", "trace system calls", "CALL[,CALL]...") {
+		public void parsed(String arg) throws OptionException
+		{
+		    sysRules.add(arg);
+		}
+        });
+
 	parser.add(new Option("plt", "trace library calls done via PLT", "RULE[,RULE]...") {
 		public void parsed(String arg) {
 		    pltRules.add(arg);
@@ -524,14 +667,17 @@ class ftrace
 	// We need to load and apply rules separately, to get all log
 	// messages.
 	for (Iterator it = pltRules.iterator(); it.hasNext(); )
-	    controller.gotPltRules(parseRules((String)it.next()));
+	    controller.gotPltRules(parseSymbolRules((String)it.next()));
 	for (Iterator it = dynRules.iterator(); it.hasNext(); )
-	    controller.gotDynRules(parseRules((String)it.next()));
+	    controller.gotDynRules(parseSymbolRules((String)it.next()));
 	for (Iterator it = symRules.iterator(); it.hasNext(); )
-	    controller.gotSymRules(parseRules((String)it.next()));
+	    controller.gotSymRules(parseSymbolRules((String)it.next()));
+	for (Iterator it = sysRules.iterator(); it.hasNext(); )
+	    controller.gotSysRules(parseSyscallRules((String)it.next()));
 
         tracer.setWriter(writer);
 	tracer.setTraceFunctions(controller, controller);
+	tracer.setTraceSyscalls(controller);
 
         if (commandAndArguments != null) {
             String[] cmd = (String[]) commandAndArguments.toArray(new String[0]);
diff --git a/frysk-core/frysk/ftrace/ChangeLog b/frysk-core/frysk/ftrace/ChangeLog
index 904015c..ed886b1 100644
--- a/frysk-core/frysk/ftrace/ChangeLog
+++ b/frysk-core/frysk/ftrace/ChangeLog
@@ -2,6 +2,17 @@
 
 	* Ftrace.java: Update to use Host.requestProc(int,FindProc).
 
+2008-02-07  Petr Machata  <pmachata@redhat.com>
+
+	* Ftrace.java: Support fine-grained selection of syscalls to
+	trace/stack trace on.
+	(TracedSyscallProvider): New interface.
+	(shouldStackTraceOn): Reanamed to shouldStackTraceOnSymbol.
+	(tracedSyscallProvider): New member variable.
+	(setDontTraceSyscalls): Renamed to setTraceSyscalls.
+	(setSyscallStackTracing): Deleted.
+	(syscallSetForTask): New member variable.
+
 2008-01-24  Andrew Cagney  <cagney@redhat.com>
 
 	* MappingGuard.java: Update to match
diff --git a/frysk-core/frysk/ftrace/Ftrace.java b/frysk-core/frysk/ftrace/Ftrace.java
index d49eef1..ca8ce0f 100644
--- a/frysk-core/frysk/ftrace/Ftrace.java
+++ b/frysk-core/frysk/ftrace/Ftrace.java
@@ -72,13 +72,11 @@ public class Ftrace
     boolean traceChildren = false;
 
     // True if we're tracing syscalls.


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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-02-07 19:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-07 19:28 [SCM] master: Fix TestFtrace to use -sys commandline option pmachata

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).