I have parsed out the addresses, file names and line numbers from a dSYM file for an iOS app. I basically have a table that maps an address to a file name and line number, which is very helpful for debugging.
To get the actual lookup address
, I use the stack trace address from the crash report and use the formula specified in this answer: https://stackoverflow.com/a/13576028/2758234. So something like this.
(actual lookup address)
= (stack trace address) + (virtual memory slide) - (image load address)
I use that address and look it up on my table. The file name I get is correct, but the line number always points to the end of the function or method that was called, not the actual line that called the following function on the stack trace.
I read somewhere, can't remember where, that frame addresses have to be de-tagged, because they are aligned to double the system pointer size. So for 32-bit systems, the pointer size is 4 bytes, so we de-tag using 8-bytes, using a formula like this:
(de-tagged address) = (tagged address) & ~(sizeof(uintptr_t)*2 - 1)
where uintptr_t
is the data type used for pointers in Objective-C.
After doing this, the lookup sort of works, but I have to do something like find the closest address that is less than or equal to the de-tagged address.
Question #1:
Why do I have to de-tag a stack frame address? Why in the stack trace aren't the addresses already pointing to the right place?
Question #2:
Sometimes in the crash report there seems to be a missing frame. For example, if function1()
calls function2()
which calls function3()
which calls function4()
, in my stack trace I will see something like:
0 Exception
1 function4()
2 function3()
4 function1()
And the stack trace address for function3()
(frame 2, above) doesn't even point to the right line number (but it is the right file, though), even after de-tagging. I see this even when I let Xcode symbolicate a crash report.
Why does this happen?