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: link
Be 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).