public inbox for frysk-cvs@sourceware.org help / color / mirror / Atom feed
From: pmachata@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Symbol aliasing is handled properly in ftrace Date: Wed, 12 Dec 2007 21:40:00 -0000 [thread overview] Message-ID: <20071212214008.17448.qmail@sourceware.org> (raw) The branch, master has been updated via 3365da12a517b83f255cd2ebff24c00ac43bd8d4 (commit) from 75155ba51e20e84ea19a4417c545bcec4a9cc184 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 3365da12a517b83f255cd2ebff24c00ac43bd8d4 Author: Petr Machata <pmachata@redhat.com> Date: Wed Dec 12 22:34:37 2007 +0100 Symbol aliasing is handled properly in ftrace ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/bindir/ChangeLog | 5 + frysk-core/frysk/bindir/ftrace.java | 19 ++++- frysk-core/frysk/ftrace/ChangeLog | 14 ++++ frysk-core/frysk/ftrace/Ftrace.java | 54 +++++++++++-- frysk-core/frysk/ftrace/Ltrace.java | 1 - frysk-core/frysk/ftrace/ObjectFile.java | 123 ++++++++++++++++++------------ frysk-core/frysk/ftrace/Symbol.java | 40 ++++++++++- frysk-core/frysk/ftrace/TestLtrace.java | 109 ++++++++++++++++++++++++-- frysk-core/frysk/pkglibdir/ChangeLog | 5 + frysk-core/frysk/pkglibdir/funit-calls.c | 5 + 10 files changed, 306 insertions(+), 69 deletions(-) First 500 lines of diff: diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog index 803fea7..835f14a 100644 --- a/frysk-core/frysk/bindir/ChangeLog +++ b/frysk-core/frysk/bindir/ChangeLog @@ -1,3 +1,8 @@ +2007-12-12 Petr Machata <pmachata@redhat.com> + + * ftrace.java: Use aliasing capabilities of Symbol. + (checkNameMatches): New method. + 2007-12-11 Phil Muldoon <pmuldoon@redhat.com> * faux.xml: Fix fmap references. diff --git a/frysk-core/frysk/bindir/ftrace.java b/frysk-core/frysk/bindir/ftrace.java index 5ac7578..a0c416b 100644 --- a/frysk-core/frysk/bindir/ftrace.java +++ b/frysk-core/frysk/bindir/ftrace.java @@ -165,6 +165,21 @@ class MyLtraceController return false; } + private boolean checkNameMatches(final WorkingSetRule rule, Symbol symbol) + { + if (rule.namePattern.matcher(symbol.name).matches()) + return true; + + if (symbol.aliases != null) + for (int i = 0; i < symbol.aliases.size(); ++i) { + String alias = (String)symbol.aliases.get(i); + if (rule.namePattern.matcher(alias).matches()) + return true; + } + + return false; + } + private boolean isInterpOf(ObjectFile objf, String exe) { java.io.File exefn = new java.io.File(exe); @@ -223,7 +238,7 @@ class MyLtraceController // maybe to stackTraceSet. for (Iterator jt = candidates.iterator(); jt.hasNext(); ) { TracePoint tp = (TracePoint)jt.next(); - if (rule.namePattern.matcher(tp.symbol.name).matches() + if (checkNameMatches(rule, tp.symbol) && checkVersionMatches(tp, rule)) { if (workingSet.add(tp)) @@ -240,7 +255,7 @@ class MyLtraceController Set iterateOver = rule.stackTrace ? stackTraceSet : workingSet; for (Iterator jt = iterateOver.iterator(); jt.hasNext(); ) { TracePoint tp = (TracePoint)jt.next(); - if (rule.namePattern.matcher(tp.symbol.name).matches() + if (checkNameMatches(rule, tp.symbol) && checkVersionMatches(tp, rule)) { jt.remove(); if (!rule.stackTrace) diff --git a/frysk-core/frysk/ftrace/ChangeLog b/frysk-core/frysk/ftrace/ChangeLog index 3d97d1a..7e53eef 100644 --- a/frysk-core/frysk/ftrace/ChangeLog +++ b/frysk-core/frysk/ftrace/ChangeLog @@ -1,3 +1,17 @@ +2007-12-12 Petr Machata <pmachata@redhat.com> + + * Ftrace.java (handleTask): Add cloned observer to task. + (tasksObserver.existingTask): Unblock cloned observer. + (ForkCloneObserverBase): Refactored from forkedObserver code. + (MyForkedObserver): New class deriving off ForkCloneObserverBase. + (MyClonedObserver): New class deriving off ForkCloneObserverBase. + * ObjectFile.java (symbol): Implemented symbol aliases. + (symbolWithValue): New field. + * Symbol.java (aliases): New field, holds alias names of symbol. + (addAlias): New method. + (hasName): New method. + * TestLtrace.java (testTracingAlias): New test. + 2007-12-03 Jose Flavio Aguilar Paulino <joseflavio@gmail.com> * Ltrace.java: Changed HashMap.Entry to Map.Entry. This was diff --git a/frysk-core/frysk/ftrace/Ftrace.java b/frysk-core/frysk/ftrace/Ftrace.java index 5c0c1c2..e21663b 100644 --- a/frysk-core/frysk/ftrace/Ftrace.java +++ b/frysk-core/frysk/ftrace/Ftrace.java @@ -49,7 +49,6 @@ import frysk.proc.ProcObserver; import frysk.proc.ProcTasksObserver; import frysk.proc.Task; import frysk.proc.TaskObserver; -import frysk.proc.TaskObserver.Forked; import inua.util.PrintWriter; @@ -227,6 +226,9 @@ public class Ftrace task.requestAddForkedObserver(forkedObserver); observationRequested(task); + task.requestAddClonedObserver(clonedObserver); + observationRequested(task); + if (ltraceController != null) { MyFunctionObserver functionObserver = new MyFunctionObserver(reporter, stackTraceSetProvider); @@ -245,10 +247,13 @@ public class Ftrace { handleTask(task); - if (task == task.getProc().getMainTask()) - // Unblock forked observer, which blocks main task - // after the fork, to give us a chance to pick it up. + if (task == task.getProc().getMainTask()) { + // Unblock forked and cloned observer, which blocks + // main task after the fork or clone, to give us a + // chance to pick it up. task.requestUnblock(forkedObserver); + task.requestUnblock(clonedObserver); + } } public void taskAdded (Task task) @@ -388,9 +393,10 @@ public class Ftrace public void deletedFrom (Object observable) { } } - TaskObserver.Forked forkedObserver = new Forked() + class ForkCloneObserverBase + implements TaskObserver { - public Action updateForkedOffspring (Task parent, Task offspring) + protected Action updateOffspring (Task parent, Task offspring) { if(traceChildren){ addProc(offspring.getProc()); @@ -408,7 +414,7 @@ public class Ftrace return Action.CONTINUE; } - public Action updateForkedParent (Task parent, Task offspring) + protected Action updateParent (Task parent, Task offspring) { return Action.CONTINUE; } @@ -426,7 +432,39 @@ public class Ftrace public void deletedFrom (Object observable) { } - }; + } + + class MyForkedObserver + extends ForkCloneObserverBase + implements TaskObserver.Forked + { + public Action updateForkedOffspring (Task parent, Task offspring) + { + return updateOffspring (parent, offspring); + } + + public Action updateForkedParent (Task parent, Task offspring) + { + return updateParent (parent, offspring); + } + } + TaskObserver.Forked forkedObserver = new MyForkedObserver(); + + class MyClonedObserver + extends ForkCloneObserverBase + implements TaskObserver.Cloned + { + public Action updateClonedOffspring (Task parent, Task offspring) + { + return updateOffspring (parent, offspring); + } + + public Action updateClonedParent (Task parent, Task offspring) + { + return updateParent (parent, offspring); + } + } + TaskObserver.Cloned clonedObserver = new MyClonedObserver(); public static interface StackTracedSymbolsProvider { boolean shouldStackTraceOn(Symbol symbol); diff --git a/frysk-core/frysk/ftrace/Ltrace.java b/frysk-core/frysk/ftrace/Ltrace.java index 6ffd3e8..bf2ac00 100644 --- a/frysk-core/frysk/ftrace/Ltrace.java +++ b/frysk-core/frysk/ftrace/Ltrace.java @@ -367,7 +367,6 @@ public class Ltrace "Stopping tracing of `" + tp.symbol.name + "' at 0x" + Long.toHexString(actualAddress)); - // FIXME: Handle aliases. Object observer = functionObserversForAddr.remove(laddr); if (observer == null) throw new AssertionError("Couldn't find observer to remove!"); diff --git a/frysk-core/frysk/ftrace/ObjectFile.java b/frysk-core/frysk/ftrace/ObjectFile.java index 85ec434..7c99f99 100644 --- a/frysk-core/frysk/ftrace/ObjectFile.java +++ b/frysk-core/frysk/ftrace/ObjectFile.java @@ -110,12 +110,15 @@ public class ObjectFile /** * All-purpose builder for ftrace Symbols and TracePoints. */ - private class ObjFBuilder - implements ElfSymbol.Builder - { + private class ObjFBuilder + implements ElfSymbol.Builder + { /** Used for tracking of what is currently being loaded. */ private TracePointOrigin origin = null; + /** For alias detection. */ + private Map symbolWithValue = new HashMap(); + /** This is the array where newly created tracepoints go to. */ private ArrayList tracePoints = null; @@ -135,53 +138,77 @@ public class ObjectFile /** Whether this file takes part in dynamic linking. */ private boolean haveDynamic = false; - public void symbol (long index, String name, - long value, long size, - ElfSymbolType type, ElfSymbolBinding bind, ElfSymbolVisibility visibility, - long shndx, List versions) - { - /// XXX FIXME: We probably want to share symbols to some extent, - /// so that entries from SYMTAB that are also present in DYNSYM - /// end up being the same symbol actually. This seems to - /// indicate we want a mapping of (name x verdefs) -> symbol. - - long offset = 0; - // Offset isn't stored in ELF file, value is; but value can be - // prelinked, so we have to compute the offset from symbol - // value and the address of first loadable segment. Don't - // deduce offset of undefined and special symbols. - if (shndx != ElfSectionHeader.ELF_SHN_UNDEF - && shndx < ElfSectionHeader.ELF_SHN_LORESERVE) - offset = value - ObjectFile.this.baseAddress; - - String dName = Demangler.demangle(name); - logger.log(Level.FINEST, "Got new symbol `" + dName + "' with origin " + this.origin + "."); - Symbol sym = new Symbol(dName, type, value, offset, size, shndx, versions); - sym.addedTo(ObjectFile.this); - - // Keep track of loaded dynamic symbols. We will need this when - // building PLT entries. - if (this.origin == TracePointOrigin.DYNAMIC - || this.origin == TracePointOrigin.PLT) + /** Keep track of loaded dynamic symbols. We will need this + * when building PLT entries. */ + private void recordDynamicSymbol (long index, Symbol sym) { - assertFitsToInt(index, "Symbol index"); - this.dynamicSymbolList[(int)index] = sym; + if (this.origin == TracePointOrigin.DYNAMIC + || this.origin == TracePointOrigin.PLT) { + assertFitsToInt(index, "Symbol index"); + this.dynamicSymbolList[(int)index] = sym; + } } - if (type == ElfSymbolType.ELF_STT_FUNC - && value != 0) - this.addNewTracepoint(value, sym.offset, sym); - } + public void symbol (long index, String name, + long value, long size, + ElfSymbolType type, ElfSymbolBinding bind, ElfSymbolVisibility visibility, + long shndx, List versions) + { + /// XXX FIXME: We probably want to share symbols to some extent, + /// so that entries from SYMTAB that are also present in DYNSYM + /// end up being the same symbol actually. This seems to + /// indicate we want a mapping of (name x verdefs) -> symbol. - public void addNewTracepoint(long address, long offset, Symbol symbol) - { - logger.log(Level.FINE, - "New tracepoint for `" + symbol + "', origin " + this.origin - + ", address=0x" + Long.toHexString(address) - + ", offset=0x" + Long.toHexString(offset) + "."); - TracePoint tp = new TracePoint(address, offset, symbol, this.origin); - tracePoints.add(tp); - } + String dName = Demangler.demangle(name); + logger.log(Level.FINEST, "Got new symbol `" + dName + "' with origin " + this.origin + "."); + + Long valueL = null; + Symbol sym = null; + + if (value != 0) { + valueL = new Long(value); + sym = (Symbol)symbolWithValue.get(valueL); + } + + if (sym != null) { + logger.log(Level.FINEST, "... aliasing `" + sym.name + "'."); + sym.addAlias(dName); + recordDynamicSymbol(index, sym); + } + else { + // Offset isn't stored in ELF file, value is; but value can be + // prelinked, so we have to compute the offset from symbol + // value and the address of first loadable segment. + long offset = 0; + + // Don't deduce offset of undefined and special symbols. + if (shndx != ElfSectionHeader.ELF_SHN_UNDEF + && shndx < ElfSectionHeader.ELF_SHN_LORESERVE) + offset = value - ObjectFile.this.baseAddress; + + sym = new Symbol(dName, type, value, offset, size, shndx, versions); + sym.addedTo(ObjectFile.this); + + recordDynamicSymbol(index, sym); + + if (type == ElfSymbolType.ELF_STT_FUNC + && value != 0) + this.addNewTracepoint(value, sym.offset, sym); + + if (valueL != null) + symbolWithValue.put(valueL, sym); + } + } + + public void addNewTracepoint(long address, long offset, Symbol symbol) + { + logger.log(Level.FINE, + "New tracepoint for `" + symbol + "', origin " + this.origin + + ", address=0x" + Long.toHexString(address) + + ", offset=0x" + Long.toHexString(offset) + "."); + TracePoint tp = new TracePoint(address, offset, symbol, this.origin); + tracePoints.add(tp); + } public synchronized ArrayList getTracePoints(TracePointOrigin origin) throws lib.dwfl.ElfException @@ -280,8 +307,8 @@ public class ObjectFile return this.tracePoints; } - } - private ObjFBuilder builder; + } + private ObjFBuilder builder; protected ObjectFile(File file, final Elf elfFile, ElfEHeader eh) throws lib.dwfl.ElfException diff --git a/frysk-core/frysk/ftrace/Symbol.java b/frysk-core/frysk/ftrace/Symbol.java index 39101e2..050f95e 100644 --- a/frysk-core/frysk/ftrace/Symbol.java +++ b/frysk-core/frysk/ftrace/Symbol.java @@ -51,7 +51,14 @@ import lib.dwfl.ElfSymbolVersion; */ public class Symbol { - public final String name; + /** Canonical name. Initially the one this symbol was created + * with, later can change as "more canonical" name appears. */ + public String name; + + /** Additional names. Initially null, only created if there are + * alternative names. */ + public ArrayList aliases = null; + public final long value; public final long size; public final long offset; // Relative to ELF file start. @@ -80,6 +87,7 @@ public class Symbol long offset, long size, long shndx, List versions) { this.name = name; + this.aliases = null; this.type = type; this.value = value; this.offset = offset; @@ -117,6 +125,21 @@ public class Symbol } } + public void addAlias(String alias) + { + if (this.aliases == null) + this.aliases = new ArrayList(); + + // If this alias has a shorter name, make it a canonical one. + if (alias.length() < this.name.length()) { + String tmp = alias; + alias = this.name; + this.name = tmp; + } + + this.aliases.add(alias); + } + public String toString() { StringBuffer buf = new StringBuffer(); @@ -124,6 +147,21 @@ public class Symbol return buf.toString(); } + /** Answer true, if name of the symbol, or one of the aliases, + * match given NAME. */ + public boolean hasName(String name) + { + if (this.name.equals(name)) + return true; + + if (this.aliases != null) + for (int i = 0; i < this.aliases.size(); ++i) + if (this.aliases.get(i).equals(name)) + return true; + + return false; + } + public void addedTo(ObjectFile of) { this.parent = of; } diff --git a/frysk-core/frysk/ftrace/TestLtrace.java b/frysk-core/frysk/ftrace/TestLtrace.java index 7813268..404c82f 100644 --- a/frysk-core/frysk/ftrace/TestLtrace.java +++ b/frysk-core/frysk/ftrace/TestLtrace.java @@ -73,7 +73,7 @@ public class TestLtrace Manager.eventLoop.requestStop(); } public void deletedFrom (Object observable) { } - public void addFailed (Object observable, Throwable w) { } + public void addFailed (Object observable, Throwable w) {} } public void performTestAllLibrariesGetDetected() @@ -193,14 +193,13 @@ public class TestLtrace "enter close", "leave close" }; - for (int i = 0; i < expectedEvents.length; ++i) - { - String event = (String)observer.events.get(i); - assertTrue("event `" + event + "' detected", - Pattern.matches(expectedEvents[i], event)); - } - assertEquals("number of recorded events", expectedEvents.length, observer.events.size()); - } + for (int i = 0; i < expectedEvents.length; ++i) { + String event = (String)observer.events.get(i); + assertTrue("event `" + event + "' detected", + Pattern.matches(expectedEvents[i], event)); + } + assertEquals("number of recorded events", expectedEvents.length, observer.events.size()); + } public void testArgumentsCorrect1() { @@ -296,6 +295,98 @@ public class TestLtrace assertEquals("number of unprocessed returns", 0, observer.expectedReturns.size()); } + public void testTracingAlias() + { + if(unresolvedOffUtrace(5053)) + return; + + class MyController4 + implements LtraceController + { + final String name; + int found = 0; + + MyController4(String name) { + this.name = name; + } + + public void fileMapped(final Task task, final ObjectFile objf, final Ltrace.Driver driver) + { + if (!task.getProc().getExe().equals(objf.getFilename().getPath())) + return; + + try { + objf.eachTracePoint(new ObjectFile.TracePointIterator() { + public void tracePoint(TracePoint tp) { + if (tp.symbol.hasName(MyController4.this.name)) { + ++MyController4.this.found; + driver.tracePoint(task, tp); + } + } + }, TracePointOrigin.SYMTAB); + } + catch (lib.dwfl.ElfException ee) { + ee.printStackTrace(); + } + } + } + + class MyObserver4 extends DummyFunctionObserver { + String name; + HashSet enterAliases = new HashSet(); + HashSet leaveAliases = new HashSet(); + hooks/post-receive -- frysk system monitor/debugger
reply other threads:[~2007-12-12 21:40 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=20071212214008.17448.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).