how do I get assertion messages into crash logs in Swift - swift

so - I use guards and assertions all over the place - I just added a check for something like this:
if start == end
{
fatalError( "can't initialise a date range of zero size but start and end are both \(start)")
}
and it dies correctly - but in my crash report I just see:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libswiftCore.dylib 0x10a61483b _assertionFailure(_:_:file:line:flags:) + 427
1 Weight Waist and Fat 0x102669179 Date_range.init(start:end:) + 1321 (Date_range.swift:42)
...
the word "initialise" doesn't appear anywhere in the entire crash report. How do I put in assertions where I actually get the information I need - do I have to set something? Is fatalError the wrong thing to be using?

The information you want is being pruned for privacy reasons.
https://forums.swift.org/t/intercept-fatalerror-or-other-termination-messages-from-swift/6190
You might be better off throwing an NSException via Objective-C if you insist on having this in the crash log. Personally I just write into the log file with OSLog and pick up the info with the sudo log tool later.

Related

bypassing exc_breakpoint crash to continue program execution

During testing my iOS app, (it's a workout app), the app crashed (EXC_BREAKPOINT) as it was trying to save the workout data.
The crash was an index out of range issue whereby the array count is 1 lesser than the workout seconds. (I should have started the seconds counter from 1 instead of 0)
for i in 0...seconds {
let data = "\(i),\(dataArray.powerGenY[i-1]),\(dataArray.powerGenYAlt[i-1])\n"
do {
try data.appendToURL(fileURL: fileURL)
}
catch {
print("Could not write data to file")
}
}
anyways, the error dropped me to LLDB. Is there any way I an Use LLDB to bypass this error and continue execution?
Having worked out for a hour, I wasn't prepared to have this crash take my data along with it. Since the crashed dropped me into LLDB, I wanted to see if there's any way to salvage the data by stepping over / bypassing / changing the value of i so that the program execution can continue.
Initially I tried
(lldb) po i = 3327
error: <EXPR>:3:1: error: cannot assign to value: 'i' is immutable
i = 3327
^
but it won't let me change the value (I is immutable)
Then I tried thread jump -l 1 but it spewed some error about not the code execution outside of current function.
(lldb) th j -l 29
error: CSVExport.swift:29 is outside the current function.
Finally, going thru this site https://www.inovex.de/blog/lldb-patch-your-code-with-breakpoints/ and trying a few things. The one that helped was thread jump
thread return
The mentioned disadvantage of thread jump can be avoided by using a
different technique to change control flow behaviour. Instead of
manipulating the affected lines of code directly the idea is to
manipulate other parts of the program which in turn results in the
desired behaviour. For the given example this means changing the
return value of can_pass() from 0 to 1. Which, of course, can be done
through LLDB. The command to use is thread just like before, but this
time with the subcommand return to prematurely return from a stack
frame, thereby short-circuiting its execution.
Executing thread return 1 did the trick. This returned true (1) to the index out of range issue and then continued the execution to the next line of code.

Application crashes when showing another window, but only when not debugging

I'm an iOS-developer trying to make a small macOS-application.
I have the storyboard, and have two NSWindowController's with their viewController.
When clicking a button in the first (initial) controller, I want the other window (with its viewController).
I have tried two things:
Create a segue between VC1 and Window2, naming it and invoking it.
Instantiate with self.storyboard?.instantiate(..).
Both of these work - when I run this through Xcode. But if I close Xcode and just run the resulting product, it crashes as soon as I try to open the next viewController, saying:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [32282]
Application Specific Information:
Performing #selector(ok:) from sender _NSPaddedButton 0x600003d0ac40
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 com.my.app 0x000000010d3e998e FirstViewController.openFile(at:) + 734 (SecondViewController.swift:44)
1 com.my.app 0x000000010d3e95e9 closure #1 in FirstViewController.openFile(_:) + 249
I'm now using this to instantiate it:
if let w = storyboard?.instantiateController(withIdentifier: "secondWindowIdentifier") as? NSWindowController{
if let d = w.contentViewController as? SecondViewController{
d.doSomething(someData: myData)
self.presentAsModalWindow(d)
}
}
I figured it out. It wasn't clear in the provided error, but after testing a few more times, I noticed it was sometimes showing a different error. I found one mentioning a WebView I had placed in the next view.
I had simply written import WebKit in the file I needed it, and hadn't added it to linked frameworks in the project's general tab. Not sure why this 100% didn't crash in the debugger, and 100% crashed on product, but oh well.

What can cause this SIGSEGV error?

I received a crash log that I cannot explain. I have searched around and it appears that the SIGSEGV has something to do with memory. But in my case there is nothing of my own code except for the main.m in the stacktrace. Also it doesn't seem to symbolicate any of the system libraries.
The crash so far only happened on one iPhone. On other phones I haven't been able to reproduce it. Right now I'm completely stuck and don't know where to continue so if anyone has seen something like this before it would be good to hear their problem and resolution.
The crash log:
Incident Identifier: TODO
CrashReporter Key: TODO
Hardware Model: iPhone4,1
OS Version: iPhone OS 6.1.3 (10B329)
Report Version: 104
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x41fd5903
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x3b0b9564 0x3b0b6000 + 13668
1 libobjc.A.dylib 0x3b0bb1d7 0x3b0b6000 + 20951
2 CoreFoundation 0x33396605 0x332d4000 + 796165
3 CoreFoundation 0x3339635d 0x332d4000 + 795485
4 libobjc.A.dylib 0x3b0bea65 0x3b0b6000 + 35429
5 libc++abi.dylib 0x3ab0b07b 0x3ab0a000 + 4219
6 libc++abi.dylib 0x3ab0b114 0x3ab0a000 + 4372
7 libc++abi.dylib 0x3ab0c599 0x3ab0a000 + 9625
8 libobjc.A.dylib 0x3b0be9d1 0x3b0b6000 + 35281
9 CoreFoundation 0x332dcf21 0x332d4000 + 36641
10 CoreFoundation 0x332dcd49 0x332d4000 + 36169
11 GraphicsServices 0x36eb52eb 0x36eb0000 + 21227
12 UIKit 0x351f2301 0x3519b000 + 357121
13 Stylbar 0x0007109f main (main.m:21)
Edit 3th of May:
The crash log is sent by a user. I haven't been able to reproduce the issue myself unfortunately, which is why it's so difficult for me to figure out what went wrong with just this crash log.
It appeared to have happened about 15 times in a row for the same user when opening a certain view controller. The view controller does several calls to a server to load a post, comments and images and profile pictures. All the code that's executed when this view controller is opened is probably over 2000 lines of code (excluding the RestKit and SBWebImage libraries that are used within this code). Posting that code here wouldn't help anyone I'm afraid.
The most simple and useful way to spend your time hunting for the cause of the crash is to look at your code and focus on places where UIKit has a delegate that points back into your code. For example, I found that the most common place this sort of thing would show up was in UITableView. The reason these problems are so hard to track down is that they might only happen in a low memory situation or in some uncommon UI condition that is very hard to reproduce. It is better to just do a code review and make sure that delegate that are set to point to your classes are set back to nil in your own object destructors. If you have many developers, it is often better to work on some higher level abstractions like a generic table and cell class that is used throughout the project than to have every developer coding up a UITableView and making mistakes like forgetting to nil out the delegate that are very difficult to find.
SIGSEGV is a problem the occurs when your application tries to access an address of memory that doesn't exists or some address where is already reserved to another program. I have the same issue with an application right now but I have to review my code to figure it out better. One clue for this kind of problem could be something equivalent to this (found in wikipedia):
#include <stdlib.h>
int main(void)
{
char p = NULL; / p is a pointer to char that initializes poiting to "nowhere"*/
* p = 'x'; /* Tries to save the char 'x' in 'no address'*/
return 0;
}
I hope this can help someone.

Strange Core Data crash with _Unwind_SjLj_Resume after migrating

I am getting a strange crash from some of my beta testers that I am having trouble with. The symbolicated crash reports indicate that the crash is occurring in the simple allocation of a controller as a singleton, at the init call, but according to the stack trace, it appears that the code I have in init is not actually where the crash is. Here is the relevant code:
1534| + (UA[REDACTED]PlayerController*)sharedInstance
1535| {
1536| #synchronized(self)
1537| {
1538| if (sharedInstance == nil)
1539| sharedInstance = [[UA[REDACTED]PlayerController alloc] init];
1540| }
1541| return sharedInstance;
1542| }
This has never crashed before, and the code has not changed anytime recently. Here is the raised stack trace:
Thread 5:
0 libSystem.B.dylib 0x33bd52d4 __kill + 8
1 libSystem.B.dylib 0x33bd52c4 kill + 4
2 libSystem.B.dylib 0x33bd52b6 raise + 10
3 libSystem.B.dylib 0x33be9d26 __abort + 62
4 libSystem.B.dylib 0x33be9d7e abort + 62
5 libSystem.B.dylib 0x33bd7980 __assert_rtn + 152
6 libgcc_s.1.dylib 0x32acab4e _Unwind_SjLj_Resume + 26
7 [REDACTED] 0x00060b64 +[UA[REDACTED]PlayerController sharedInstance] (UA[REDACTED]PlayerController.m:1540)
8 [REDACTED] 0x00063e6c -[UA[REDACTED]PlayerViewController setupControlViews] (UA[REDACTED]PlayerViewController.m:224)
9 [REDACTED] 0x00062ce0 -[UA[REDACTED]PlayerViewController viewDidLoad] (UA[REDACTED]PlayerViewController.m:268)
10 UIKit 0x320a0270 -[UIViewController view] + 104
…
Any ideas as to what this cryptic crash is and where it might be coming from?
UPDATE 1
It appears it has to do with core data and migrations. I was able to duplicate it, but the root cause is still unknown. I have some automatic migrations that are in this version, and it appears that while some of the NSManagedObjects can be read, others are throwing this exception, particularly on a NSManagedObjects relationship. It might not be related to the PlayerController at all. Any Core-Data experts have some insight?
UPDATE 2
Here is the call stack of the crash after I have found a way to reproduce it
and the relevant code:
if (resultArray && [resultArray count]) {
for (MixAudio *ma in resultArray) {
Audio *audio = [ma valueForKey:LOCAL_MIX_AUDIO_AUDIO_KEY];
if (audio) {
[returnArray addObject:audio];
}
}
To help explain what I did to reproduce it, I have to explain the data structure a little. I have Mix and Audio items. Mixes have many Audio, Audio belongs to many Mixes. This is a simple relationship call on the MixAudio objects to get the Audio. Now, this has only been crashing here after I do a database restore to the new version.
Database backups in my setup means zipping up the database to save the data, then unzipping on restore. This crash only happens after the restore process. To make things more complicated, there are 3 database versions with mapping models. Because this process worked for me before the versioning, I feel that something in my versions is causing this crash.
All other data is fine and can be accessed, even saved. Somehow, this single fetch is causing issues. There are no errors or warnings when setting up the persistent store or managed object model. Furthermore, new Mix objects can be created and accessed fine, only older fetches (that were in the DB before the restore) are failing.
If I don't catch the error, the console prints:
Assertion failed: (_Unwind_SjLj_Resume() can't return), function _Unwind_SjLj_Resume, file /SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c, line 326.
Putting a try/catch around the crashing line allows me to inspect the root crash cause:
Error: NSRangeException: *** -[NSMutableArray objectAtIndex:]: index 4294967295 beyond bounds [0 .. 16]
but this makes no sense (to me at least) for a simple valueForKey call. 4294967295 = 2^32-1 which means the index var was probably set to −1 if that helps. I am lost here.
[SOLVED] UPDATE 3
I was right about it being in the versioning :) I reread the section on versioning in Zarra's book and had a major DOH moment. This is the first time I have ever had an app with 3 database versions. I am using Mapping Models in my app and I naively assumed that core data would be able to map from 1-2 using one model, then 2-3 using the next. I literally hit my head when I realized I did not have a 1-3 mapping model. to test it out, I added one quickly and everything is as smooth as butter. Now I just have to go back and use his Progressive Data Migration samples to make my life easier as I go on with more version of this DB.
I am hoping Zarra drives by here and answers something… anything… so I can give him the points for this :)
While the OP was able to solve his own question, it is helpful to have a clear understanding of migrations.
When you create a second version of your data model, you need a mapping model from version one to version two.
When you create a third model you need a mapping model from one to two AND a map from one to three.
When you add a fourth model you need the following models:
1-2
1-3
1-4
2-3
2-4
And it gets more progress from there.

iTunesConnect crashlog is partially symbolicated; does not show line numbers

The crashlog on iTunesConnect for my XCode 3.2.5-built application shows method names, but not line numbers. For example, in the abridged crash report I've pasted in below, it shows this:
0x000f5ef8 -[MyTableViewController dealloc] + 120
There are two things here that are puzzling me, upon which I'd appreciate some insight. The first is why the raw .crash file coming from iTunesConnect is already partially symbolized: it shows the class and method name, but not the source code file and line number. I would expect the raw iTunesConnect crashlog to show just the hexidecimal addresses. As I understand it, only once I download the crash log onto my local system and explicitly bind it using the appropriate tool (XCode Organizer, symbolicatecrash, atos, gdb x/i command, etc) and to the exact application binary and dSYM files (those having the matching UUID), will I see the full symbols of class, method, source code file, and line number. Even when I download and view the crashlog on a Windows box, it appears partially symbolized. I am concerned that my distribution binary must be including some debug symbols in order for this information to show up in the raw crashlog, despite having "Strip Linked Project" set in its Distribution target settings. Any insight here would be great.
The second thing that is perplexing me, and is of more immediate concern to me in fixing this high-profile crash, is this business of the offset. I've very carefully located the dSYM and application binary with the matching UUID, put them in my home directory so they can be found by Spotlight et al, and no matter what I do, I am unable to convert that offset [MyTableViewController dealloc] + 120 to a source code file (which is known to me to be MyTableViewController.m) and a line number. I have tried the following tricks with the raw iTunesConnect .crash file:
XCode Organizer: its "symbolication" affects no changes to the crashlog -- it's the same.
symbolicatecrash: It doesn't really complain about anything in verbose mode, and the output crashlog is the same
gdb: Using the same gdb and -arch setting that XCode 3.2.5 uses for producing the distribution build, and loading in the matching application binary and dSYM symbols per this post, gdb 'x/i' and 'info line *' commands tells me that [MyTableViewController dealloc] + 120 corresponds to a totally unrelated piece of our codebase in a completely different file -- a .h file, even! Wild goose chase.
Something is not right here. Even despite ensuring the exact same UUID across the crash report, the application binary, and the dSYM file ... none of these tools can yield an actual line number, and doing it the low-level way sends me on a wild goose chase. Knowing the exact line number is critical to fixing this, because we are unable to reproduce this crash in-house so we're flying blind here. This looks to be a simple over-released object, but it's not clear which exact object it is, and we're unable to tell from context. I'm wondering if there is some misappropriated XCode build setting that is somehow breaking the symbolication process.
Thanks for your time!
What follows is the abridged raw .crash log from iTunesConnect.
Incident Identifier: 09EAE058-7D55-4AE5-947A-17280FB0211A
Hardware Model: iPhone3,1
Process: MyApp [1895]
Path: /var/mobile/Applications/B4B872EF-CB0D-41D7-A7B5-435ADE479D0A/MyApp.app/MyApp
Identifier: MyApp
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2011-01-24 14:06:32.941 -0500
OS Version: iPhone OS 4.2.1 (8C148)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0xd0000000
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x33479466 objc_msgSend + 18
1 MyApp 0x000f5ef8 -[MyTableViewController dealloc] + 120
2 CoreFoundation 0x33a26f74 -[NSObject(NSObject) release]
3 libobjc.A.dylib 0x3347a812 objc_setProperty
4 UIKit 0x320bb4a0 -[UINavigationController setDisappearingViewController:]
5 UIKit 0x320bb478 -[UINavigationController _clearLastOperation]
xx SNIP xx
23 MyApp 0x00014eac main + 36
24 MyApp 0x0000b324 start + 44
XX SNIP xx
Binary Images:
0x1000 - 0x1e3fff +MyApp armv7 <5570f8eee3bc11647732c12f96fe9553> /var/mobile/Applications/B4B872EF-CB0D-41D7-A7B5-435ADE479D0A/MyApp.app/MyApp
I've experienced similar issues with releasing object that weren't retained or that were in an autorelease pool thereby getting released twice. More often than not I'll get a crash for a location that is inside the framework/iOS but was caused from my lack of proper memory management. I'm not saying this IS happening here, but just is something I've experienced when a similar error has presented itself.