public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
* Corefile -arch 32 test failures with breakpoint and stacktrace tests
@ 2007-10-06  8:12 Phil Muldoon
  2007-10-08 10:46 ` Mark Wielaard
  0 siblings, 1 reply; 5+ messages in thread
From: Phil Muldoon @ 2007-10-06  8:12 UTC (permalink / raw)
  To: Frysk Hackers

I've spent the last week fixing 32 on 64 test failures with core files, 
and while all tests passed on my local build, when I merged with HEAD, I 
got as noted below in the email. I suspect these are  changes made in 
the last week or so.

Basically the tests now failing are:

1) 
testInsertedBreakpoint(frysk.proc.dead.TestLinuxCore)lib.dwfl.ElfFileException
1) 
testLinuxCoreFileStackTrace(frysk.proc.dead.TestLinuxCore)junit.framework.ComparisonFailure: 
Compare stack traces expected:<...489234dc in __libc_sigsuspend ()

Both these tests work on native bit size (ie 64 on 64, and both worked 
with my copy of HEAD from earlier this week with -arch 32 and my local 
changes)

Regards

Phil

[pmuldoon@localhost frysk-core]$ ./TestRunner -arch 32 
frysk.proc.dead.TestLinuxCore frysk.proc.dead.TestCorefileByteBuffer 
frysk.util.TestFCore
Running testLinuxCoreFileMaps(frysk.proc.dead.TestLinuxCore) ...PASS
Running testLinuxCoreFileStackTrace(frysk.proc.dead.TestLinuxCore) ...FAIL
  junit.framework.ComparisonFailure: Compare stack traces 
expected:<...489234dc in __libc_sigsuspend ()
#2 0x080491fe in server ()
#3 0x08049d11 in main ()
#4 0x4890ff70 in __libc_start_main ()
#5 0x08048c31 in _start ()...> but was:<...00000000 in [unknown]...>
Running testLinuxHostPopulation(frysk.proc.dead.TestLinuxCore) ...PASS
Running testLinuxProcPopulation(frysk.proc.dead.TestLinuxCore) ...PASS
Running testLinuxProcAuxV(frysk.proc.dead.TestLinuxCore) ...PASS
Running testLinuxTaskMemory(frysk.proc.dead.TestLinuxCore) ...PASS
Running testLinuxTaskPopulation(frysk.proc.dead.TestLinuxCore) ...PASS
Running testInsertedBreakpoint(frysk.proc.dead.TestLinuxCore) ...ERROR
  lib.dwfl.ElfFileException
Running 
testCorefileByteBufferSlice(frysk.proc.dead.TestCorefileByteBuffer) ...PASS
Running 
testCoreFileByteBufferPeek(frysk.proc.dead.TestCorefileByteBuffer) ...PASS
Running 
testCoreFileByteBufferMapOverrun(frysk.proc.dead.TestCorefileByteBuffer) 
...PASS
Running 
testCoreFileByteBufferMapUnderrun(frysk.proc.dead.TestCorefileByteBuffer) 
...PASS
Running 
testCoreFileByteBufferSequentialGet(frysk.proc.dead.TestCorefileByteBuffer) 
...PASS
Running 
testCoreFileByteBufferPeekArray(frysk.proc.dead.TestCorefileByteBuffer) 
...PASS
Running 
testCoreFileByteBufferPoke(frysk.proc.dead.TestCorefileByteBuffer) ...PASS
Running testCoreFileCreated(frysk.util.TestFCore) ...PASS
Running testElfCoreHeader(frysk.util.TestFCore) ...PASS
Running testProgramSegmentHeader(frysk.util.TestFCore) ...PASS
Running testGeneralPurposeRegisters(frysk.util.TestFCore) ...PASS
Running testFloatingPointRegisters(frysk.util.TestFCore) ...PASS
Running testXFloatingPointRegisters(frysk.util.TestFCore) ...UNRESOLVED
  http://sourceware.org/bugzilla/show_bug.cgi?id=4890
Running testAuxv(frysk.util.TestFCore) ...PASS

Time: 0.338
There were 1 unresolved:
  http://sourceware.org/bugzilla/show_bug.cgi?id=4890
There was 1 error:
1) 
testInsertedBreakpoint(frysk.proc.dead.TestLinuxCore)lib.dwfl.ElfFileException
   at lib.dwfl.Elf.<init>(TestRunner)
   at frysk.proc.dead.TestLinuxCore.getFunctionEntryAddress(TestRunner)
   at frysk.proc.dead.TestLinuxCore.testInsertedBreakpoint(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArch32Cases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)
There was 1 failure:
1) 
testLinuxCoreFileStackTrace(frysk.proc.dead.TestLinuxCore)junit.framework.ComparisonFailure: 
Compare stack traces expected:<...489234dc in __libc_sigsuspend ()
#2 0x080491fe in server ()
#3 0x08049d11 in main ()
#4 0x4890ff70 in __libc_start_main ()
#5 0x08048c31 in _start ()...> but was:<...00000000 in [unknown]...>
   at frysk.proc.dead.TestLinuxCore.testLinuxCoreFileStackTrace(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArch32Cases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)

FAILURES!!!
Tests run: 22,  Failures: 1,  Errors: 1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Corefile -arch 32 test failures with breakpoint and stacktrace  tests
  2007-10-06  8:12 Corefile -arch 32 test failures with breakpoint and stacktrace tests Phil Muldoon
@ 2007-10-08 10:46 ` Mark Wielaard
  2007-10-09 17:08   ` Andrew Cagney
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Wielaard @ 2007-10-08 10:46 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Frysk Hackers

[-- Attachment #1: Type: text/plain, Size: 1182 bytes --]

Hi Phil,

On Sat, 2007-10-06 at 09:12 +0100, Phil Muldoon wrote:
> I've spent the last week fixing 32 on 64 test failures with core files, 
> and while all tests passed on my local build, when I merged with HEAD, I 
> got as noted below in the email. I suspect these are  changes made in 
> the last week or so.
> 
> Basically the tests now failing are:
> 
> 1) 
> testInsertedBreakpoint(frysk.proc.dead.TestLinuxCore)lib.dwfl.ElfFileException

This one works fine for me either with or without -arch 32 given to
TestRunner. But I noticed that it tries to create an Elf object directly
using the result of getProc() which isn't reliably since getProc()
"guesses" the path to the original executable. The attached patch makes
it use the new DwflCache.get(Task) construct for finding symbols. Hope
that helps in your case. If not it is at least more correct.

2007-10-08  Mark Wielaard  <mwielaard@redhat.com>

        * TestLinuxCore.java (Symbol): New static helper class.
        (getFunctionEntryAddress): Use Dwfl directly instead of
        constructing Elf and Dwarf objects directly.

The tests PASS here with or without the patch and with or without -arch
32.

Cheers,

Mark

[-- Attachment #2: elf-dwfl-core.patch --]
[-- Type: text/x-patch, Size: 3515 bytes --]

Index: frysk-core/frysk/proc/dead/ChangeLog
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/dead/ChangeLog,v
retrieving revision 1.32
diff -u -r1.32 ChangeLog
--- frysk-core/frysk/proc/dead/ChangeLog	2 Oct 2007 22:31:50 -0000	1.32
+++ frysk-core/frysk/proc/dead/ChangeLog	8 Oct 2007 10:44:52 -0000
@@ -1,3 +1,9 @@
+2007-10-08  Mark Wielaard  <mwielaard@redhat.com>
+
+	* TestLinuxCore.java (Symbol): New static helper class.
+	(getFunctionEntryAddress): Use Dwfl directly instead of
+	constructing Elf and Dwarf objects directly.
+	
 2007-10-02  Andrew Cagney  <cagney@redhat.com>
 
 	* LinuxProc.java (sendrecISA()): Add.
Index: frysk-core/frysk/proc/dead/TestLinuxCore.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/dead/TestLinuxCore.java,v
retrieving revision 1.16
diff -u -r1.16 TestLinuxCore.java
--- frysk-core/frysk/proc/dead/TestLinuxCore.java	10 Aug 2007 18:54:34 -0000	1.16
+++ frysk-core/frysk/proc/dead/TestLinuxCore.java	8 Oct 2007 10:44:52 -0000
@@ -45,7 +45,6 @@
 import java.io.File;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.ArrayList;
 
 import frysk.proc.Action;
 import frysk.proc.Isa;
@@ -67,6 +66,7 @@
 import frysk.testbed.LegacyOffspring;
 
 import lib.dwfl.*;
+import frysk.dwfl.*;
 
 public class TestLinuxCore
     extends TestLib
@@ -387,22 +387,66 @@
     assertEquals(origb, coreb);
   }
 
+
+  // Helper class since there there isn't a get symbol method in Dwfl,
+  // so we need to wrap it all in a builder pattern.
+  static class Symbol implements SymbolBuilder
+  {
+    private String name;
+    private long address;
+
+    private boolean found;
+
+    private Symbol()
+    {
+      // properties get set in public static get() method.
+    }
+
+    static Symbol get(Dwfl dwfl, String name)
+    {
+      Symbol sym = new Symbol();
+      sym.name = name;
+      DwflModule[] modules = dwfl.getModules();
+      for (int i = 0; i < modules.length && ! sym.found; i++)
+        modules[i].getSymbolByName(name, sym);
+
+      if (sym.found)
+        return sym;
+      else
+        return null;
+    }
+
+    String getName()
+    {
+      return name;
+    }
+
+    long getAddress()
+    {
+      return address;
+    }
+
+    public void symbol(String name, long value, long size,
+                       int type, int bind, int visibility)
+    {
+      if (name.equals(this.name))
+        {
+          this.address = value;
+          this.found = true;
+        }
+    }
+  }
+
   /**
-   * Returns the address of the requested function through query the
-   * Proc Elf and DwarfDie. Asserts that the function has only 1
-   * entry point.
+   * Returns the address of the requested function through query Dwfl
+   * of the main Task of the given Proc.
    */
   private static long getFunctionEntryAddress(Proc proc, String func)
-    throws ElfException
   {
-    Elf elf = new Elf(proc.getExe(), ElfCommand.ELF_C_READ);
-    Dwarf dwarf = new Dwarf(elf, DwarfCommand.READ, null);
-    DwarfDie die = DwarfDie.getDecl(dwarf, func);
-    ArrayList entryAddrs = die.getEntryBreakpoints();
-    
-    // We really expect just one entry point.
-    assertEquals(entryAddrs.size(), 1);
-    return ((Long) entryAddrs.get(0)).longValue();
+    Task task = proc.getMainTask();
+    Dwfl dwfl = DwflCache.getDwfl(task);
+    Symbol sym = Symbol.get(dwfl, func);
+    return sym.getAddress();
   }
 
   /**

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Corefile -arch 32 test failures with breakpoint and stacktrace   tests
  2007-10-08 10:46 ` Mark Wielaard
@ 2007-10-09 17:08   ` Andrew Cagney
  2007-10-09 17:30     ` dl symbol search path; Was: " Andrew Cagney
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Cagney @ 2007-10-09 17:08 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: Phil Muldoon, Frysk Hackers

Mark Wielaard wrote:
> 2007-10-08 Mark Wielaard <mwielaard@redhat.com>
>         * TestLinuxCore.java (Symbol): New static helper class.
>         (getFunctionEntryAddress): Use Dwfl directly instead of
>         constructing Elf and Dwarf objects directly.
>
>   

This much code being wired into a test-case scares me.  Would a better 
place for this be frysk.symtab.SymbolFactory; with a test case?


> ------------------------------------------------------------------------
>
> Index: frysk-core/frysk/proc/dead/ChangeLog
> ===================================================================
> RCS file: /cvs/frysk/frysk-core/frysk/proc/dead/ChangeLog,v
> retrieving revision 1.32
> diff -u -r1.32 ChangeLog
> --- frysk-core/frysk/proc/dead/ChangeLog	2 Oct 2007 22:31:50 -0000	1.32
> +++ frysk-core/frysk/proc/dead/ChangeLog	8 Oct 2007 10:44:52 -0000
> @@ -1,3 +1,9 @@
> +2007-10-08  Mark Wielaard  <mwielaard@redhat.com>
> +
> +	* TestLinuxCore.java (Symbol): New static helper class.
> +	(getFunctionEntryAddress): Use Dwfl directly instead of
> +	constructing Elf and Dwarf objects directly.
> +	
>  2007-10-02  Andrew Cagney  <cagney@redhat.com>
>  
>  	* LinuxProc.java (sendrecISA()): Add.
> Index: frysk-core/frysk/proc/dead/TestLinuxCore.java
> ===================================================================
> RCS file: /cvs/frysk/frysk-core/frysk/proc/dead/TestLinuxCore.java,v
> retrieving revision 1.16
> diff -u -r1.16 TestLinuxCore.java
> --- frysk-core/frysk/proc/dead/TestLinuxCore.java	10 Aug 2007 18:54:34 -0000	1.16
> +++ frysk-core/frysk/proc/dead/TestLinuxCore.java	8 Oct 2007 10:44:52 -0000
> @@ -45,7 +45,6 @@
>  import java.io.File;
>  import java.io.PrintWriter;
>  import java.io.StringWriter;
> -import java.util.ArrayList;
>  
>  import frysk.proc.Action;
>  import frysk.proc.Isa;
> @@ -67,6 +66,7 @@
>  import frysk.testbed.LegacyOffspring;
>  
>  import lib.dwfl.*;
> +import frysk.dwfl.*;
>  
>  public class TestLinuxCore
>      extends TestLib
> @@ -387,22 +387,66 @@
>      assertEquals(origb, coreb);
>    }
>  
> +
> +  // Helper class since there there isn't a get symbol method in Dwfl,
> +  // so we need to wrap it all in a builder pattern.
> +  static class Symbol implements SymbolBuilder
> +  {
> +    private String name;
> +    private long address;
> +
> +    private boolean found;
> +
> +    private Symbol()
> +    {
> +      // properties get set in public static get() method.
> +    }
> +
> +    static Symbol get(Dwfl dwfl, String name)
> +    {
> +      Symbol sym = new Symbol();
> +      sym.name = name;
> +      DwflModule[] modules = dwfl.getModules();
> +      for (int i = 0; i < modules.length && ! sym.found; i++)
> +        modules[i].getSymbolByName(name, sym);
> +
> +      if (sym.found)
> +        return sym;
> +      else
> +        return null;
> +    }
> +
> +    String getName()
> +    {
> +      return name;
> +    }
> +
> +    long getAddress()
> +    {
> +      return address;
> +    }
> +
> +    public void symbol(String name, long value, long size,
> +                       int type, int bind, int visibility)
> +    {
> +      if (name.equals(this.name))
> +        {
> +          this.address = value;
> +          this.found = true;
> +        }
> +    }
> +  }
> +
>    /**
> -   * Returns the address of the requested function through query the
> -   * Proc Elf and DwarfDie. Asserts that the function has only 1
> -   * entry point.
> +   * Returns the address of the requested function through query Dwfl
> +   * of the main Task of the given Proc.
>     */
>    private static long getFunctionEntryAddress(Proc proc, String func)
> -    throws ElfException
>    {
> -    Elf elf = new Elf(proc.getExe(), ElfCommand.ELF_C_READ);
> -    Dwarf dwarf = new Dwarf(elf, DwarfCommand.READ, null);
> -    DwarfDie die = DwarfDie.getDecl(dwarf, func);
> -    ArrayList entryAddrs = die.getEntryBreakpoints();
> -    
> -    // We really expect just one entry point.
> -    assertEquals(entryAddrs.size(), 1);
> -    return ((Long) entryAddrs.get(0)).longValue();
> +    Task task = proc.getMainTask();
> +    Dwfl dwfl = DwflCache.getDwfl(task);
> +    Symbol sym = Symbol.get(dwfl, func);
> +    return sym.getAddress();
>    }
>  
>    /**
>   

^ permalink raw reply	[flat|nested] 5+ messages in thread

* dl symbol search path; Was: Corefile -arch 32 test failures with  breakpoint and stacktrace   tests
  2007-10-09 17:08   ` Andrew Cagney
@ 2007-10-09 17:30     ` Andrew Cagney
  2007-10-16  2:39       ` Roland McGrath
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Cagney @ 2007-10-09 17:30 UTC (permalink / raw)
  To: Mark Wielaard, Roland McGrath; +Cc: Frysk Hackers

Andrew Cagney wrote:
>
>>
>> +    static Symbol get(Dwfl dwfl, String name)
>> +    {
>> +      Symbol sym = new Symbol();
>> +      sym.name = name;
>> +      DwflModule[] modules = dwfl.getModules();
>> +      for (int i = 0; i < modules.length && ! sym.found; i++)
>> +        modules[i].getSymbolByName(name, sym);
>> + 
PS:

The rules for looking up an elf symbol is, unfortunately, subtle and 
complex.  A brute force search through all the modules taking the first 
returned isn't correct.  For instance, consider a search for open.  If 
the current symbol scope has a local open function then that should be 
returned, and not the one from a library like glibc.  The man page for 
dlsym(3) touches on the semantics.

I was hoping that there was a dwfl method for doing this, but none jump 
out from libdwfl.h?  I see DwflModule.getSymbolByName does the best it 
can using dwfl_module_getsymtab.

Andrew



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: dl symbol search path; Was: Corefile -arch 32 test failures with  breakpoint and stacktrace   tests
  2007-10-09 17:30     ` dl symbol search path; Was: " Andrew Cagney
@ 2007-10-16  2:39       ` Roland McGrath
  0 siblings, 0 replies; 5+ messages in thread
From: Roland McGrath @ 2007-10-16  2:39 UTC (permalink / raw)
  To: Frysk Hackers

Sorry, there is indeed no handy function to help you with this.
I'm sure we will have one eventually.  But doing it really right
does involve really severe amounts of hair, which are all in the
90% to get the last 10%.  The best we can try to do for now is to
stub it out with the trivial naive search, but inside an interface
that asks the question the right way.

The goal is to resolve the ELF symbol reference that would have been
done by referring to a particular name in a particular source context.
When reduced to ELF terms, these components describe a reference:

1. symbol name
2. symbol version binding
3. Dwfl_Module making the reference
4. purpose of the reference

To take each of these in detail:

1. This is the name string used in the ELF symbol table, obviously.
   Resolving what a name used in a particular context in the source
   would actually yield as an ELF name is in fact quite difficult for
   all the complex cases, though 90% of cases are trivial.  I won't go
   into all the gory details of those problems now.  It suffices to
   observe the context necessary to do the best possible job: DWARF
   scope DIE of the desired context, if available (either CU or inner);
   language mode if not implicit from CU; module the reference is being
   made from.

2. The symbol version is approximately a second and third part to the
   symbol name.  It is usually determined (bound) only at link time,
   not by the compiler nor in assembly source code; DWARF is never
   much help figuring it out.  It's only an issue when there are two
   definitions with the same name and different symbol versions.  This
   is likely for e.g. printf and some libstdc++ name-mangled symbols,
   but not very common in Joe Blow's DSO.

   Given a module to consider as the context making the reference, when
   there is an existing external reference in that module to a given
   symbol name, that pretty much makes it easy.  (It's possible to refer
   to two different symbols with the same name and different versions
   inside one module.  But it's so inconvenient that even DSOs like libc
   that define multiple symbols by the same name don't use the versioned
   mechanism to refer to their own symbols between CUs, they just use
   private aliases with different names.)  If there was no reference to
   this symbol linked into the context module, then you can't in all
   cases get an unambiguously right answer.  But there is no information
   helpful to that guessing more granular than just the module as
   context.

3. Every reference is in the context of some module or other, even if not
   in the context of a known CU/scope.  If the context of the user request
   seems to be "global, I don't care exactly what I mean", then either
   this means the main program module, or it means accepting the result is
   a map of different results given different contexts in cases of ambiguity.

4. The purposes for reference that we must distinguish are:
   a. like a PLT reloc, a jump target
   b. like a COPY reloc, an initializer value
   c. like all others, an object address
   
   For "func(args)", and probably for a breakpoint on func, it's (a).
   For "&func", it's (c).  In module A using PIC that calls func in module B,
   (a) means func's real definition in B; (c) means func's PLT symbol in A.

   For a non-PIC object (i.e. the main program) that does "extern int foo;"
   and links to a DSO that does "int foo = 1;", then (b) is foo's symbol in
   the main program; (c) is foo's definition in the DSO.  When the
   reference is to "the variable foo", to see its live value in the
   program, change it, place a watchpoint, it's (c).  When the reference is
   to print the static initializer value, offline or before the program has
   finished dynamic loading at startup/dlopen, then it's (b).

   The (a) vs (c) and (b) vs (c) distinctions often apply to a module's
   own references to its own symbols, though I used less confusing examples
   above.  So purpose is relevant to every lookup.

   At high level, we can describe the purpose distinctions as "for actual
   code address", "for static initializer data", and "for object address".

So, gleaned from that, the lookup function should have at hand:

* symbol name
* DWARF scope DIE of the desired context, if available
* language mode, if no scope/CU context
* referring module, if available
* purpose of reference

Furthermore, it should be able to return ambiguous results.  That is,
the result of the lookup is either "this one is it", or a list of
candidates each annotated with "this would be it if you were to give
foobar as the referring module" and/or "this would be it if this
reference by module foobar were resolved to symbol version V in module
M".  It's fine for now if the only plan for the ambiguous cases is an
exception "couldn't figure it out" or even "blindly pick the first one".
But one should contemplate how the description of the ambiguity and the
options for resolving it might percolate up to the user.


Thanks,
Roland

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-10-16  2:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-06  8:12 Corefile -arch 32 test failures with breakpoint and stacktrace tests Phil Muldoon
2007-10-08 10:46 ` Mark Wielaard
2007-10-09 17:08   ` Andrew Cagney
2007-10-09 17:30     ` dl symbol search path; Was: " Andrew Cagney
2007-10-16  2:39       ` Roland McGrath

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).