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