public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Symbol aliasing is handled properly in ftrace
@ 2007-12-12 21:40 pmachata
  0 siblings, 0 replies; only message in thread
From: pmachata @ 2007-12-12 21:40 UTC (permalink / raw)
  To: frysk-cvs

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


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

only message in thread, other threads:[~2007-12-12 21:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-12 21:40 [SCM] master: Symbol aliasing is handled properly in ftrace 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).