Re: Symbolizing Crash Dump with atos. How does it get the .dSYM?
Re: Symbolizing Crash Dump with atos. How does it get the .dSYM?
- Subject: Re: Symbolizing Crash Dump with atos. How does it get the .dSYM?
- From: Rick Altherr <email@hidden>
- Date: Tue, 26 Feb 2008 08:12:06 -0800
On Feb 25, 2008, at 5:44 PM, Jerry Krinock wrote:
On 2008 Feb, 25, at 15:27, Rick Altherr wrote:
Well, actually, it shouldn't be. The crash happened in frame 0.
Now objc_msgSend has a nasty habit of not setting up a stack frame,
so the actual originator appears to be missing. I expect that
frame 9 is actually something in your app that calls -[NSDocument
showWindows].
<snip>
The problem is a feature of gdb. When you tell it to look open a
file, it reads the symbol information for that file as well as the
symbol information for all the shared libraries that it directly
links against. On Leopard, nothing is prebound, so everything
starts at 0x1000. Thus, your program's symbol information is read,
and then replaced by each framework it directly links against.
Well, I believe you're telling me that there are two problems:
(1) My simulated crash is not a "good" crash for Objective-C
(2) Possible confusion between frameworks (I don't really
understand this.)
Let me clarify (2) for the edification of the list. Each binary on
the system (application, tool, framework, shared library) is comprised
of segments. Those segments group things into basic areas such as
text (the actual code), data (initialized variables, etc), and various
others. Each of those segments also has an address in the processes'
address space where it prefers to be loaded.
When your application is executed, the first thing that occurs is that
a program called dyld is run first. Its job is to load all the shared
libraries needed by your application. For each library it loads, it
first tries to simply load it into the addresses that are specified in
the library's segments, but since 2 libraries' segments could overlap,
dyld will load one of the segments to a different address to avoid
collisions. The difference between where the segment was actually
loaded and where the segment preferred to be loaded is commonly
referred to as the slide.
In Tiger, this was somewhat avoided by having the OS "prebound". That
basically meant that a framework could be set to a specific address
that was essentially reserved for that framework. This helped reduce
collisions, but they could still occur. One side-effect was that when
gdb loaded a prebound framework from disk, the preferred address
specified in the binary tended to be unique to that framework.
In Leopard, prebinding was made obsolete. dyld is much faster at
sliding libraries and can better utilize the process's address space
by repositioning everything that is actually loaded, rather than
relying on preset addresses for everything that _could_ be loaded.
The side-effect here is that every binary on disk says that the first
segment will start at 0x1000 (well, technically 64-bit processes
don't, but the same problem happens).
Now, when you tell gdb to read a file from disk with the 'file'
command, it read the file into memory and interprets the symbol
information as though the binary had loaded at its preferred address.
It doesn't really have any other option since it is considering the
file in isolation. If you pointed gdb at a process, it would ask dyld
where everything was actually loaded. gdb also has a feature that
tries to save the user a bit of time entering commands. When you load
a binary with the 'file' command, gdb also loads all of the frameworks
and libraries that that binary links against directly. On Tiger, you
have a good chance that those libraries are prebound, so they all get
interpreted as being at unique addresses and everything is fine. On
Leopard, everything has the same preferred address, so gdb does
exactly what it is asked to do and interprets the symbol information
as though they were all at the same preferred address. Each time a
symbol overlaps with a symbol that was already loaded, the old symbol
is replaced in gdb's knowledge base of symbols. Ultimately, you end
up with a mishmash of symbol information and asking for the symbol
information for an address yields strange results.
By specifying the 'set sharedlibrary preload-libraries no' command
before the 'file' command, you tell gdb to _not_ load all the
libraries the binary is directly linked against. This means that a
single binary is loaded into gdb's symbol knowledge base and no
symbols are overwritten.
So, I changed my crasher to this:
int* p = 1 ; *p = 5 ;
And then I did what you said:
1) Start gdb with no options. Make sure you use the correct -arch
flag if your crash report is from a different architecture.
2) Run 'set sharedlibrary preload-libraries no'. This disables the
behavior described above.
3) Load your binary with the 'file' command. In your case 'file
Bookdog.app/Contents/MacOS/Bookdog'
(You'll always want to specify the actual executable to gdb.)
4) now run the 'info' command.
And now it pinpoints the line number perfectly, as shown below.
So I'll do what you said, Rick, and hope that any crash reports I
get are "good" crashes, (although messages to invalid objects
upsetting objc_msgSend do happen!)
Thanks,
Jerry
Thread 0 Crashed:
0 com.sheepsystems.Bookdog 0x0006c433 0x1000 + 439347
1 com.apple.AppKit 0x937dcf12 -[NSIBObjectData
nibInstantiateWithOwner:topLevelObjects:] + 1613
2 com.apple.AppKit 0x937d30ec loadNib + 264
3 com.apple.AppKit 0x937d2a4d +
[NSBundle(NSNibLoading)
_loadNibFile:nameTable:withZone:ownerBundle:] + 946
Jerrys-Mac-Mini:Release jk$ gdb
GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct 2 04:07:49
UTC 2007)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i386-apple-darwin".No symbol table is
loaded. Use the "file" command.
Breakpoint 1 (-[NSException raise]) pending.
No symbol table is loaded. Use the "file" command.
Breakpoint 2 (objc_exception_throw()) pending.
No symbol table is loaded. Use the "file" command.
Breakpoint 3 (-[_NSZombie release]) pending.
No symbol table is loaded. Use the "file" command.
Breakpoint 4 (szone_error) pending.
(gdb) set sharedlibrary preload-libraries no
(gdb) file Bookdog.app/Contents/MacOS/Bookdog
Reading symbols from /Users/jk/Documents/Programming/Builds/Release/
Bookdog.app/Contents/MacOS/Bookdog...Reading symbols from /Users/jk/
Documents/Programming/Builds/Release/Bookdog.app.dSYM/Contents/
Resources/DWARF/Bookdog...done.
done.
(gdb) info line *0x6c433
Line 1014 of "/Users/jk/Documents/Programming/Projects/Bookdog/
Migration.m" starts at address 0x6c433 <-[Migration awakeFromNib]
+2741> and ends at 0x6c43d <-[Migration awakeFromNib]+2751>.
--
Rick Altherr
Architecture and Performance Group
email@hidden
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden