MyApplication creates a personalized crash report using the NSException instance. The app retrieves the callStackSymbols array and adds them to a text file.
If you notice on the crash report, instead of getting a line like this:
libsqlite3.dylib 0x30531ce4 0x30506000 + 179428
I'm getting a line like this one
29 MyApplication 0x00059260 MyApplication + 4704
Looks like instead of getting 2 addresses, I get "MyApplication" in the middle.
Atos is not working with the first address.
You get the symbolicated results, since your app binary contains the debug symbols, so calling callStackSymbols can resolve the addresses right away. The only missing part is the line numbers, which isn't possible to get automatically with the symbols being part of the app.
The three number values are: Address = Base Address + Offset. This means the first address is enough to get the symbol. The Base address is the start address of the binary/framework. Mostly when symbolication is done, the first address is also changed to be relative to the framework address instead of being absolute. The app binary memory area usually starts at 0x1000. This can be viewed in a crash reports binary images section, and it can be different to 0x1000 due to new memory features in newer iOS versions.
So for now simply use the give address in the 3rd column and add 0x1000 to the value when invoking atos.
In general I suggest using a framework based on PLCrashReporter, which will give you all information for a crash report. Including all threads and binary images in a standard crash report format and also works in the App Store.
Related
I am looking for a way to symbolicate external app symbols (iOS) inside my own application (macOS), assuming I have the DSYM and system symbols.
Xcode symbolicates both app addresses as well as system framework addresses (UIKit, Foundation, etc.)
atos requires an image file and can symbolicate addresses from that image.
I am looking to symbolicate a large number of addresses in my own app. The addresses represent stack traces at various points in time. I would like to symbolicate the system framework addresses as well.
I found atosl, which uses dwarf.h and libdwarf.h to reimplement atos to varying degrees of success—however this seems like a very low–level approach.
Are there any other ways to symbolicate a large number of addresses at once?
Here is symbolication I use in tests (requires XCTest): https://github.com/avito-tech/Mixbox/blob/db3206c95b71f35ae6032ff9b0baff13026608f4/Frameworks/TestsFoundation/Reporting/FileLineForFailureProvider/StackTrace/ExtendedStackTraceEntryFromStackTraceEntryConverterImpl.swift
I use the code to highlight failures in tests in Xcode without requiring testers to pass file: StaticString = #file, line: UInt = #line everywhere. The code is less readable with this boilerplate, and also there is not much reason for such boilerplate, because ideally Xcode should be able to highlight stacktrace of test failure...
Note that there is an issue. If you do not have sources on the machine that executes the code, it doesn't symbolicate. Maybe it can be fixed quickly, I didn't even tried.
Also there are comments in the code about other options: atos, lldb, CoreSymbolication. I think CoreSymbolication is what you want to use. The solution I gave you is simple, more dependent on XCTest, less configurable, has some other flaws.
I am trying to debug some concurrency code and when I log [NSThread callStackSymbols]; the console shows most of the symbols I am interested in as <redacted>.
Is there a way to get around this during runtime? I have deleted the device symbols folder but Xcode re-symbolication didn't seem to fix the issue.
There are a few other questions on here but they all seem to be trying to solve this on crash files.
How can I see the method names for framework symbols in the debug console?
I am running Xcode 5.
You get all symbols showing up only:
while debugging
when generating a full crash report and symbolicate that.
symbolicating the addresses manually using atos with the corresponding dSYM or system symbols on disk (you need to load address for each framework and binary to do that, also due to Address space layout randomization. Only having callStackSymbols doesn't reveal those). See iOS crash reports: atos not working as expected
The <redacted> symbols are a
Memory optimization. The <redacted> symbol names are stored on disk only, which saves some physical memory and lots of virtual address space in every process.
See https://devforums.apple.com/thread/171264
To sum up: you can NOT get all system symbols showing up using any calls during runtime. Instead you need to create a full crash report by letting the app crash and analyse the stack traces from those.
I have an app on the App Store that is crashing. I have tried several of the solutions on SO to symbolicate my app, using at different times the Organizer, the Terminal, and Instruments. Nothing has worked so far - the lines in the reports from the methods in my app are never symbolicated, even when the lines for Apple methods are. After looking around for a while, it seems as though this might have something to do with the app name, which is along the lines of "Angie's List" - with both an apostrophe and a space. It is too late to change the app name now as it is live on the store. I haven't seen a solution to this anywhere and would appreciate a shove in the right direction.
Usually the app name doesn't matter, unless there is a bug in the symbolication script which I doubt. Did you check if you have the correct dSYM available?
If you scroll down your latest crash log, check the 1st line below Binary Images, it will look like this
0x1000 - 0x24cfff +YourApp armv7 <f6012c517d783486ab53e45d948b92a2> /var/mobile/Applications/A8EC3C1F-44AF-169A-BC0E-FBBC0F04CDF5/YourApp.app/YourApp
f6012c517d783486ab53e45d948b92a2 is the UUID of the executable the caused the crash.
You can find the correct dSYM using the terminal as follows:
mdfind "com_apple_xcode_dsym_uuids == F6012C51-7D78-3486-AB53-E45D948B92A2"
The string F6012C51-7D78-3486-AB53-E45D948B92A2 is the above string reformatted to uppercase and 8-4-4-4-12 groups. I guess this command will not return anything.
If you have a dSYM (e.g. in an .xcarchive), you can check its UUID in the terminal as follows:
dwarfdump --uuid YourApp.app.dSYM
If symbolication doesn't work automatically, you can try to do it manually by following the instructions posted here: iOS crash reports: atos not working as expected
If the application has special characters like spaces or apostrophe's in it, the default Apple toolchain will not be able to symbolicate it. The reason is that the tool otool, which being used in the toolchain, can't handle that. No matter how you pass the filename. So to fix this, you have to do the following:
Rename the dSYM package and remove all special chars, e.g. from My App's.app.dSYM to MyApps.app.dSYM
Open the content inside the package and navigate down to Contents/Resources/DWARF
Rename the file in there as you did above
Now try again. Best way to avoid all this: NEVER use special chars in your apps name. If you want the adjust the name that appears on the screen, use CFBundleDisplayName or the corresponding plist entries.
Up until very recently (around november 4th, 2012) the crash dumps from our ios app always had a load address of 0x1000. We never used the -l option in atos and we still got good results so I assume it defaults to 0x1000. Over the last week we were having difficulties tracing crashes and it turned out the load addresses have been different in every crash log since november 4th.
Does anyone know what determines the load address?
Is it something that Apple has done recently or possibly something that our app has done to cause this?
You can retrieve the base address from a crash report by looking at the 'Binary Images' section at the bottom of the report. The first entry is your binary image with a range of addresses, take the first one and pass it to atos as load address.
An example of crash report:
[...]
Binary Images:
0x1000 - 0xfcfff +YOUR_BINARY_NAME armv7 <9b381f1828fa3a888d4fbc4175f9a16d> /var/mobile/Applications/FD624263-D877-4F07-BC1F-5E6703A78D07/YOUR_APP.app/YOUR_BINARY_NAME
0x7ba000 - 0x7befff AccessibilitySettingsLoader armv7 /System/Library/AccessibilityBundles/AccessibilitySettingsLoader.bundle/AccessibilitySettingsLoader
[...]
0x1000 is the loading address you are looking for.
What is the easiest way to produce a Mach-O object file that does not have the SUBSECTIONS_VIA_SYMBOLS flag set, such that the linker (with -dead_strip) will not later try to cut the text section into pieces and guess which pieces are used?
I can use either a command-line option to llvm/gcc (4.2.1) that will prevent it from emitting .subsections_via_symbols in the first place, or a command-line tool that will remove the flag from an existing object file.
(Writing such a tool myself based on the Mach-O spec is an option, but if possible I'd rather not reinvent the wheel that hard).
Platform: iOS, cross-compiling from OSX with XCode 4.5.
Background: We're supplying a static library that other companies build into apps. When our library encounters a problem it produces a crash report with a stack trace and certain other key information that (if we're lucky) we get to analyze later. Typically the apps as deployed have been stripped of debug information so interpreting stack traces is a problem. If we were making the app ourselves we would just save the DWARF debug data from before stripping and use that to decode the addresses in the incoming crash reports. But we can't depend on the app makers supplying us with such data from their linking steps.
What we're doing instead is to let the crash report include the run-time address of selected function; from that we can deduce the offset between addresses in our linker map and addresses in the crash report. We're linking our entire library incrementally into a single .o before we stuff it into an .a; since it does only one big thing there wouldn't be much to save from removing unused functionality from it when the app is eventually linked. Unfortunately there's a few small pieces of code in the library that are sometimes not used (alternative API entry points for the main functionality, small helper functions for interpreting our error codes and the like), and if the app developer links with -dead_strip, it disturbs the address reconstruction of crash reports that the relative offsets in the final app differ from the linker map from our incremental link operation.
We can't realistically ask all app developers to disable dead-code stripping in their build process, so it seems a better way forward if we could mark our .o as "not dead-strippable" and have the eventual app linking respect that.
I solved it.
The output of an incremental link operation only has MH_SUBSECTIONS_VIA_SYMBOLS set if all the input objects have it set. And an object file produced from assembler input only has it set if there's an explicit directive set. So one can remove the flag by linking with an empty assembler input:
echo > empty.s
$(CC) $(CFLAGS) input.o empty.s -nostdlib -Wl,r -o output.o