On Mar 24, 2009, at 2:59 AM, Terry Lambert wrote:
This assumes your scope, which is hierarchical, is rooted at the top, rather than in some subelement. As in the expectation is that you call it from the root scope.
The dyld interfaces, on the other hand use a scope parameter which lets you explicitly set the scope.
My guess is that you are calling this from within a library routine and only seeing the library and the things it us linked against, and big anything above it, or in a non-flat symbol space.
Thanks, but I think this scope stuff is a red herring. I am calling from the executable (root scope). If someday I write a library and can't lookup symbols in the root executable from there, then that's good to know but not the case here.
All symbols in question are in the executable (and thus in the same scope as the caller). I'm not doing any fancy dlopen() stuff, this is all based on a "Debug" style link from Xcode. Prebinding is off, fix and continue is on, debug symbols is obviously on, position-dependent is off...
Personally, I'd popen atos.
Yeah, for my own code that's what I'm going to wind up doing. For reference, I've realized that atos's ~10 second CPU burn only occurs for the first lookup (must be doing some kind of preprocessing of the entire symbol table). So if I keep the atos process running, then subsequent lookups are quite fast...
Regardless, calling out to atos seems like a hack (and is non-portable), I'd rather dladdr worked reliably. I'm still trying to determine whether this dladdr behavior warrants a bug report. I've done some further investigation and narrowed this down:
For reference, the incorrect symbol lookups from backtrace_symbols are:
0x00085273 _ZSt4acosf + 7437
0x000707da _ZSt8_Destroy[snip] + 17510
0x0001a90b _ZN7debuget15extractFilenameEPKc + 1093
If I look up the target addresses using nm, I find the correct symbols at the preceding address as expected:
00085216 t __ZN9TraceTest7DoStartEv
000705cc t __ZN21BehaviorSwitchControlI9TraceTestN11Factory0ArgIS0_E7FactoryIS0_EEE9startmineEv
0001a8bc t __ZN25BehaviorSwitchControlBase5startEv
And the incorrect symbols are indeed found at the offsets given in the symbol lookup, but they are not the nearest symbol with value less than or equal to addr. Here is the complete symbol list between the returned __ZSt4acosf, and one-past the intended __ZN9TraceTest7DoStartEv:
00083566 T __ZSt4acosf [returned symbol]
00083580 t __ZThn12_N13ArmGrabTarget12processEventERK9EventBase
0008358a t __ZN13ArmGrabTarget12processEventERK9EventBase
00084196 t __ZN19GroundPlaneBehavior7DoStartEv
0008424e t __ZN11EventRouter11removeTimerEPK13EventListenerR9EventBase
000842a4 t __ZThn12_N19GroundPlaneBehavior12processEventERK9EventBase
000842ae t __ZN19GroundPlaneBehavior12processEventERK9EventBase
00085216 t __ZN9TraceTest7DoStartEv [correct symbol]
[00085273 target address here]
It's clear what is happening is dladdr is skipping all of the 't' (local text section?) symbols, and only returning the 'T' (external text section?) symbols. Spot checking the correctly returned symbols suggests they are all 'T' symbols. I'm guessing the 't' symbols are static-linked in the executable, and 'T' symbols are dynamically loaded from a build directory somewhere, and thus dladdr is only reporting the 'T' symbols as it ignores static linkage.
Does that sound right?
If so, how can I force all my symbols to be external/dynamic? I suppose I could link everything into a .dylib and then have just main() be in the actual executable, but perhaps there's an easier way if I only care about development builds. Smells like ZeroLink.
Alternatively, I suppose I could figure out what nm is using and emulate that in my code... sounds even more hairy than popen atos though, probably a bunch of manual mach-o parsing...?
Finally, it's fair that dladdr only handles dynamic symbols, but perhaps the root issue to take up with Apple is that backtrace_symbols should be based on something more generic that handles static symbols as well, instead of basing it on dladdr. They should be able to make backtrace_symbols interface with atos's codebase instead.
Thanks,
-Ethan