From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23456 invoked by alias); 21 Dec 2007 13:01:40 -0000 Received: (qmail 23395 invoked by uid 9697); 21 Dec 2007 13:01:36 -0000 Date: Fri, 21 Dec 2007 13:01:00 -0000 Message-ID: <20071221130136.23379.qmail@sourceware.org> From: pmachata@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: New ltrace test testRecursive. X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 5f345af74c688d16da9c1edd8c79b6786ddba380 X-Git-Newrev: f9ead2a82c1c952359e78ac9b381250a70ebd97c Mailing-List: contact frysk-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-cvs-owner@sourceware.org Reply-To: frysk@sourceware.org X-SW-Source: 2007-q4/txt/msg00618.txt.bz2 The branch, master has been updated via f9ead2a82c1c952359e78ac9b381250a70ebd97c (commit) via 4da0a3084a95a97800ac27133f342a82f582fca9 (commit) via 66db8e191dce8a8108603f7cf5b77416a1322f38 (commit) via b55639cdbe386d1f621e96f37b5c23448bb8293b (commit) via 608c705c74c91801b90212134442c9fe5d413235 (commit) via 5a99f3ef410d7d024cf4d465dcb9d005a2362fff (commit) via cc8f368113a4ce80ec0d2c2c964592a34cea3d93 (commit) via 3521fe061ae8830f26ddd500146a4642f48c97f4 (commit) via 735aa4afa7e7532ebd7c4c8313412abf8c1874f0 (commit) via e900c2b7839a8b8661759ddf43e4faaf43b38c14 (commit) from 5f345af74c688d16da9c1edd8c79b6786ddba380 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit f9ead2a82c1c952359e78ac9b381250a70ebd97c Author: Petr Machata Date: Fri Dec 21 13:45:14 2007 +0100 New ltrace test testRecursive. commit 4da0a3084a95a97800ac27133f342a82f582fca9 Author: Petr Machata Date: Thu Dec 20 17:53:16 2007 +0100 New ltrace test testMultipleControlers. * This one caused all the rewrites in last few days. Yaaay! commit 66db8e191dce8a8108603f7cf5b77416a1322f38 Author: Petr Machata Date: Thu Dec 20 17:35:44 2007 +0100 Ltrace testMultipleObservers turned on commit b55639cdbe386d1f621e96f37b5c23448bb8293b Author: Petr Machata Date: Thu Dec 20 16:44:36 2007 +0100 Ltrace testTracingAlias turned on commit 608c705c74c91801b90212134442c9fe5d413235 Author: Petr Machata Date: Thu Dec 20 16:20:26 2007 +0100 Ltrace testArgumentsCorrect1 turned on * Also some refactoring took place to reduce boilerplate code. commit 5a99f3ef410d7d024cf4d465dcb9d005a2362fff Author: Petr Machata Date: Thu Dec 20 15:46:12 2007 +0100 Ltrace testCallRecorded turned on commit cc8f368113a4ce80ec0d2c2c964592a34cea3d93 Author: Petr Machata Date: Thu Dec 20 14:28:14 2007 +0100 MappingGuard tests moved to their own file * ... and turned on. The rest of ltrace suite still off. commit 3521fe061ae8830f26ddd500146a4642f48c97f4 Author: Petr Machata Date: Thu Dec 20 05:14:41 2007 +0100 Ltrace a step closer to true observer. * Ltrace was refactored to allow being used by independent clients. In particular: ** No more shared Controller necessary. Ltrace doesn't know about controller, and is now able to observe particular TracePoints. ** Ltrace doesn't observe mapping, controller does (if there is any). ** Mapping events moved over from FunctionObserver to MappingObserver. MappingGuard now calculates detailed mapping changes as needed. ** It's in semi-broken state, and testsuite was turned off. Will work on that tomorrow. commit 735aa4afa7e7532ebd7c4c8313412abf8c1874f0 Author: Petr Machata Date: Tue Dec 18 18:09:05 2007 +0100 ftrace displays terminating task info commit e900c2b7839a8b8661759ddf43e4faaf43b38c14 Author: Petr Machata Date: Thu Dec 13 14:59:21 2007 +0100 New function observer test. ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/bindir/ChangeLog | 5 + frysk-core/frysk/bindir/ftrace.java | 14 +- frysk-core/frysk/ftrace/ChangeLog | 65 +++ frysk-core/frysk/ftrace/Ftrace.java | 503 +++++++++++++------ frysk-core/frysk/ftrace/FunctionObserver.java | 8 - frysk-core/frysk/ftrace/Ltrace.java | 662 +++++++++---------------- frysk-core/frysk/ftrace/LtraceController.java | 53 -- frysk-core/frysk/ftrace/MappingGuard.java | 128 +++++- frysk-core/frysk/ftrace/MappingObserver.java | 29 +- frysk-core/frysk/ftrace/TestLtrace.java | 498 ++++++++++++------- frysk-core/frysk/ftrace/TestMappingGuard.java | 138 +++++ frysk-core/frysk/pkglibdir/ChangeLog | 5 + frysk-core/frysk/pkglibdir/funit-calls.c | 9 + 13 files changed, 1273 insertions(+), 844 deletions(-) delete mode 100644 frysk-core/frysk/ftrace/LtraceController.java create mode 100644 frysk-core/frysk/ftrace/TestMappingGuard.java First 500 lines of diff: diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog index f01a5c8..1bbe15f 100644 --- a/frysk-core/frysk/bindir/ChangeLog +++ b/frysk-core/frysk/bindir/ChangeLog @@ -2,6 +2,11 @@ * TestFauxv.java (fauxv): Delete System.out. +2007-12-20 Petr Machata + + * ftrace.java (MyLtraceController): renamed to MyFtraceController. + Using Ftrace.Driver instead of Ltrace.Driver consistently. + 2007-12-19 cagney * fhpd.java: Explicitly import frysk.sys.FileDescriptor. diff --git a/frysk-core/frysk/bindir/ftrace.java b/frysk-core/frysk/bindir/ftrace.java index 55e8524..9dde5c7 100644 --- a/frysk-core/frysk/bindir/ftrace.java +++ b/frysk-core/frysk/bindir/ftrace.java @@ -59,8 +59,6 @@ import frysk.proc.Task; import frysk.util.CommandlineParser; import frysk.ftrace.Ftrace; -import frysk.ftrace.Ltrace; -import frysk.ftrace.LtraceController; import frysk.ftrace.ObjectFile; import frysk.ftrace.TracePoint; import frysk.ftrace.TracePointOrigin; @@ -103,8 +101,8 @@ class WorkingSetRule } } -class MyLtraceController - implements LtraceController, +class MyFtraceController + implements Ftrace.Controller, Ftrace.StackTracedSymbolsProvider { protected static final Logger logger = Logger.getLogger("frysk"); @@ -121,7 +119,7 @@ class MyLtraceController return symbolsStackTraceSet.contains(symbol); } - public MyLtraceController() { } + public MyFtraceController() { } public void gotPltRules(List rules) { logger.log(Level.FINER, "Got " + rules.size() + " PLT rules."); @@ -189,7 +187,7 @@ class MyLtraceController return objffn.equals(interpfn); } - public void applyTracingRules(final Task task, final ObjectFile objf, final Ltrace.Driver driver, + public void applyTracingRules(final Task task, final ObjectFile objf, final Ftrace.Driver driver, final List rules, final TracePointOrigin origin) throws lib.dwfl.ElfException { @@ -276,7 +274,7 @@ class MyLtraceController symbolsStackTraceSet.add(((TracePoint)it.next()).symbol); } - public void fileMapped(final Task task, final ObjectFile objf, final Ltrace.Driver driver) { + public void fileMapped(final Task task, final ObjectFile objf, final Ftrace.Driver driver) { try { applyTracingRules(task, objf, driver, pltRules, TracePointOrigin.PLT); applyTracingRules(task, objf, driver, dynRules, TracePointOrigin.DYNAMIC); @@ -307,7 +305,7 @@ class ftrace final List pltRules = new ArrayList(); final List dynRules = new ArrayList(); final List symRules = new ArrayList(); - final MyLtraceController controller = new MyLtraceController(); + final MyFtraceController controller = new MyFtraceController(); boolean allowInterpTracing = false; Ftrace tracer = new Ftrace(); diff --git a/frysk-core/frysk/ftrace/ChangeLog b/frysk-core/frysk/ftrace/ChangeLog index 7e53eef..c28dc52 100644 --- a/frysk-core/frysk/ftrace/ChangeLog +++ b/frysk-core/frysk/ftrace/ChangeLog @@ -1,3 +1,68 @@ +2007-12-21 Petr Machata + + * TestLtrace.java (testRecursive): New test. + +2007-12-20 Petr Machata + + * TestLtrace.java: Refactoring. + (testArgumentsCorrect1): Turned the test on. + (testTracingAlias): Dtto. + (testMultipleObservers): Dtto. + (testMultipleControlers): New test. + +2007-12-20 Petr Machata + + * Ftrace.java: Commentary changes & reorganizations. + * TestMappingGuard: Dtto. + * TestLtrace.java (testCallRecorded): Turned on the test. + +2007-12-20 Petr Machata + + * TestMappingGuard: New file. + (testDebugStateMappingGuard): New test, moved from TestLtrace. + (testSyscallMappingGuard): Dtto. + +2007-12-20 Petr Machata + + * MappingGuard.java: Now provides more fine-grained events. + (updateMappedPart): New method, brought over from Ltrace. + (updateUnmappedPart): Dtto. + (updateMappedFile): Dtto. + (updateUnmappedFile): Dtto. + (updateMapping): Dtto. + (DebugStateMappingGuard): Now implements terminating observer. + * MappingObserver.java: Added more fine-grained events. + * Ltrace.java: Doesn't use mapping guard at all. Rewritten to + allow adding several observers to single tracepoint, without a + need to share one controller. Ltrace doesn't know about the + controller anymore. + (Driver): Interface moved to Ftrace. + (requestAddFunctionObserver): Now provides observing per tracepoint. + (requestDeleteMappingObserver): Dtto. + * FunctionObserver.java: Doesn't provide mapping events anymore. + * Ftrace.java: Reindent. + Using terminated observer instead of terminating, which didn't + fire with fatal signals. + Uses mapping guard to direct Ltrace tracing. + (Driver, Controller): New interfaces, brought over from Ltrace and + LtraceController. Using new interfaces where appropriate. + (functionObserver): New member variable. + (TracePointWorkingSet): New class, mostly brought over from Ltrace. + (MyMappingObserver): Dtto. + * TestLtrace.java: Temporarily shut down. + +2007-12-18 Petr Machata + + * Ftrace.java: Use terminating observer to inform about the task + termination events. + (MyTerminatingObserver): New class. + +2007-12-13 Petr Machata + + * TestLtrace.java: Reindented. + (MyController4): Moved from testTracingAlias to class scope. + (testMultipleObservers): New test. + 2007-12-12 Petr Machata * Ftrace.java (handleTask): Add cloned observer to task. diff --git a/frysk-core/frysk/ftrace/Ftrace.java b/frysk-core/frysk/ftrace/Ftrace.java index e21663b..5a5d7c5 100644 --- a/frysk-core/frysk/ftrace/Ftrace.java +++ b/frysk-core/frysk/ftrace/Ftrace.java @@ -50,23 +50,27 @@ import frysk.proc.ProcTasksObserver; import frysk.proc.Task; import frysk.proc.TaskObserver; -import inua.util.PrintWriter; +import frysk.sys.Signal; +import inua.util.PrintWriter; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Observable; import java.util.Observer; +import java.util.Set; import java.util.Iterator; - -import java.io.File; +import java.util.logging.*; public class Ftrace { + static final Logger logger = Logger.getLogger(FtraceLogger.LOGGER_ID); + // Where to send output. Reporter reporter; - // True if we're tracing children as well. - boolean traceChildren = false; + // True if we're tracing children as well. + boolean traceChildren = false; // True if we're tracing syscalls. boolean traceSyscalls = true; @@ -74,20 +78,52 @@ public class Ftrace // True if we're tracing mmaps/unmaps. boolean traceMmapUnmap = false; - // Non-null if we're using ltrace. - LtraceController ltraceController = null; - StackTracedSymbolsProvider stackTraceSetProvider = null; + HashSet syscallStackTraceSet = null; - HashSet syscallStackTraceSet = null; + // Set of ProcId objects we trace; if traceChildren is set, we also + // look for their children. + HashSet tracedParents = new HashSet(); - // Set of ProcId objects we trace; if traceChildren is set, we also - // look for their children. - HashSet tracedParents = new HashSet(); + HashMap syscallCache = new HashMap(); - HashMap syscallCache = new HashMap(); + // The number of processes we're tracing. + int numProcesses; - // The number of processes we're tracing. - int numProcesses; + /** + * Controller has to be implemented externally. Each time a + * mapping changes, it is called for consulation and has a chance + * to change working set of Ftrace via provided Driver interface. + */ + public static interface Controller { + /** + * New library FILE was mapped in task TASK. Use DRIVER to tell + * ltrace what to do. + */ + void fileMapped(frysk.proc.Task task, ObjectFile file, Driver driver); + } + + /** + * External entity implementing this interface is called out each + * time an entry point is hit. It can decide whether the stack + * trace should be generated or not. + * XXX: Ideally, this would also operate on tracepoints. + */ + public static interface StackTracedSymbolsProvider { + boolean shouldStackTraceOn(Symbol symbol); + } + + /** + * Driver implementation is placed here in Ftrace, and handed over + * via this interface to allow external controller to aid which + * tracepoints should be traced. + */ + public static interface Driver { + void tracePoint(Task task, TracePoint tp); + } + + // Non-null if we're using ltrace. + Controller ftraceController = null; + StackTracedSymbolsProvider stackTraceSetProvider = null; public void setTraceChildren () { @@ -104,91 +140,88 @@ public class Ftrace traceMmapUnmap = true; } - public void setTraceFunctions (LtraceController functionController, + public void setTraceFunctions (Controller ftraceController, StackTracedSymbolsProvider stackTraceSetProvider) { - if (functionController == null + if (ftraceController == null || stackTraceSetProvider == null) - throw new AssertionError("functonController != null && stackTraceSetProvider != null"); + throw new AssertionError("ftraceController != null && stackTraceSetProvider != null"); - if (this.ltraceController == null + if (this.ftraceController == null && this.stackTraceSetProvider == null) { - this.ltraceController = functionController; + this.ftraceController = ftraceController; this.stackTraceSetProvider = stackTraceSetProvider; } else - throw new AssertionError("LtraceController already assigned."); + throw new AssertionError("FtraceController already assigned."); + } + + public void addTracePid (ProcId id) { + tracedParents.add(id); } - public void addTracePid (ProcId id) - { - tracedParents.add(id); - } + public void setSyscallStackTracing (HashSet syscallSet) { + syscallStackTraceSet = syscallSet; + } - public void setSyscallStackTracing (HashSet syscallSet) - { - syscallStackTraceSet = syscallSet; - } + public void setWriter (PrintWriter writer) { + this.reporter = new Reporter(writer); + } - public void setWriter (PrintWriter writer) + private void init () { - this.reporter = new Reporter(writer); + if (reporter == null) + reporter = new Reporter(new PrintWriter(System.out)); + + functionObserver = new MyFunctionObserver(reporter, stackTraceSetProvider); + + // this observer should only be used to pick up a proc if we + // are tracing a process given a pid + // otherwise use forkobserver. + Manager.host.observableProcAddedXXX.addObserver(new Observer() + { + public void update (Observable observable, Object arg) + { + Proc proc = (Proc) arg; + ProcId id = proc.getId(); + if (tracedParents.contains(id)){ + // In case we're tracing a new child, add it. + //tracedParents.add(proc.getId()); XXX: why is this needed ? + // Weird API... unfortunately we can't fetch the + // Proc's main task here, as it will be null. Instead + // we have to request it and handle it in a callback. + addProc(proc); + } + } + }); } - private void init () - { - if (reporter == null) - reporter = new Reporter(new PrintWriter(System.out)); + private void addProc (Proc proc) { + new ProcTasksObserver(proc, tasksObserver); + } - // this observer should only be used to pick up a proc if we - // are tracing a process given a pid - // otherwise use forkobserver. - Manager.host.observableProcAddedXXX.addObserver(new Observer() - { - public void update (Observable observable, Object arg) - { - Proc proc = (Proc) arg; - ProcId id = proc.getId(); - if (tracedParents.contains(id)){ - // In case we're tracing a new child, add it. -// tracedParents.add(proc.getId()); XXX: why is this needed ? - // Weird API... unfortunately we can't fetch the - // Proc's main task here, as it will be null. Instead - // we have to request it and handle it in a callback. - addProc(proc); - } - } - }); - } - - private void addProc(Proc proc){ - new ProcTasksObserver(proc, tasksObserver); - } - - public void trace (String[] command) - { - init(); - Manager.host.requestCreateAttachedProc(command, attachedObserver); - Manager.eventLoop.run(); - } - - public void trace () - { - init(); - for (Iterator it = tracedParents.iterator(); it.hasNext(); ){ - Manager.host.requestFindProc - ((ProcId)it.next(), - new FindProc() { - public void procFound (ProcId procId) {} - public void procNotFound (ProcId procId, Exception e) { - System.err.println("No process with ID " + procId.intValue() + " found."); - Manager.eventLoop.requestStop(); - } - } - ); - Manager.eventLoop.run(); + public void trace (String[] command) { + init(); + Manager.host.requestCreateAttachedProc(command, attachedObserver); + Manager.eventLoop.run(); + } + + public void trace () { + init(); + for (Iterator it = tracedParents.iterator(); it.hasNext(); ){ + Manager.host.requestFindProc + ((ProcId)it.next(), + new FindProc() { + public void procFound (ProcId procId) {} + public void procNotFound (ProcId procId, Exception e) { + System.err.println("No process with ID " + procId.intValue() + " found."); + Manager.eventLoop.requestStop(); + } + } + ); + Manager.eventLoop.run(); + } } - } private HashMap observationCounters = new HashMap(); @@ -229,18 +262,80 @@ public class Ftrace task.requestAddClonedObserver(clonedObserver); observationRequested(task); - if (ltraceController != null) { - MyFunctionObserver functionObserver - = new MyFunctionObserver(reporter, stackTraceSetProvider); - Ltrace.requestAddFunctionObserver(task, functionObserver, ltraceController); - observationRequested(task); - } + task.requestAddTerminatedObserver(new MyTerminatedObserver()); + observationRequested(task); + + MappingGuard.requestAddMappingObserver(task, new MyMappingObserver(ftraceController)); + observationRequested(task); Manager.host.observableProcRemovedXXX.addObserver(new ProcRemovedObserver(proc)); reporter.eventSingle(task, "attached " + proc.getExe()); ++numProcesses; } + /** Remembers working set preferences for each task. + Map<Task, Map<File, TracePointWorkingSet>> */ + private final HashMap driversForTask = new HashMap(); + + private class TracePointWorkingSet + implements Driver + { + private Set tracePoints = new HashSet(); + + public void tracePoint(Task task, TracePoint tp) + { + logger.log(Level.CONFIG, "Request for tracing `{0}'", tp.symbol.name); + tracePoints.add(tp); + } + + public void populateBreakpoints(Task task, MemoryMapping mapping, MemoryMapping.Part part) + { + Set request = new HashSet(); + for (Iterator it = tracePoints.iterator(); it.hasNext(); ) { + TracePoint tp = (TracePoint)it.next(); + if (tp.offset >= part.offset + && tp.offset < part.offset + part.addressHigh - part.addressLow) { + logger.log(Level.FINER, + "Will trace `" + tp.symbol.name + "', " + + "address=0x" + Long.toHexString(tp.address) + "; " + + "offset=0x" + Long.toHexString(tp.offset) + "; " + + "part at=0x" + Long.toHexString(part.addressLow) + + ".." + Long.toHexString(part.addressHigh) + "; " + + "part off=0x" + Long.toHexString(part.offset) + ";"); + + long actualAddress = tp.offset - part.offset + part.addressLow; + logger.log(Level.CONFIG, + "Will trace `" + tp.symbol.name + + "' at 0x" + Long.toHexString(actualAddress)); + + request.add(tp); + } + } + if (!request.isEmpty()) + Ltrace.requestAddFunctionObserver(task, functionObserver, request); + } + + public void evacuateBreakpoints(Task task, MemoryMapping mapping, MemoryMapping.Part part) + { + Set request = new HashSet(); + for (Iterator it = tracePoints.iterator(); it.hasNext(); ) { + TracePoint tp = (TracePoint)it.next(); + if (tp.offset >= part.offset + && tp.offset < part.offset + part.addressHigh - part.addressLow) { + + long actualAddress = tp.offset - part.offset + part.addressLow; + logger.log(Level.CONFIG, + "Stopping tracing of `" + tp.symbol.name + + "' at 0x" + Long.toHexString(actualAddress)); + + request.add(tp); + } + } + if (!request.isEmpty()) + Ltrace.requestDeleteFunctionObserver(task, functionObserver, request); + } + } + ProcObserver.ProcTasks tasksObserver = new ProcObserver.ProcTasks() { public void existingTask (Task task) @@ -270,69 +365,61 @@ public class Ftrace public void deletedFrom (Object observable) {} }; - /** - * An observer to stop the eventloop when the traced process exits. - */ hooks/post-receive -- frysk system monitor/debugger