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 "event" will be used to + mean "signal or syscall, whatever applies".</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. + "12"), 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. "12"), 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 "SIG".</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=".*stat.*",3 ls</command></cmdsynopsis> + <cmdsynopsis><command>ftrace -sys='*stat*,3' 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: linkBe 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).