-[NSConcreteFileHandle writeData:] uses GCD to run a block but does not catch exceptions, leading to crash
| Originator: | davidz | ||
| Number: | rdar://19285139 | Date Originated: | 2014-12-17 |
| Status: | Fixed | Resolved: | iOS9.0b1 |
| Product: | iOS | Product Version: | 8.1 |
| Classification: | Reproducible: | Rarely |
Summary: When the filesystem is full, calling -[NSFileHandle writeData:] on a valid NSFileHandle sometimes (not always) calls dispatch_data_apply() with a block which internally throws an unhandled exception. GCD requires blocks to catch exceptions; this situation leads to an exception that cannot be caught by user code and leads to an unpreventable crash. Steps to Reproduce: 1. Create a new file (e.g. using NSFileManager) 2. Open an NSFileHandle using NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:filePath] 3. Completely fill up the disk, for example by creating lots of useless files on the filesystem 4. Call [fh writeData:data] to write some bytes Expected Results: writeData: throws an NSException that can be caught at the call site of [fh writeData:data]. In most cases (maybe 75%), this expected behavior is the actual behavior. Actual Results: In about 25% of cases, the app crashes and the catch block is not executed. In these cases, writeData: calls dispatch_data_apply, which calls a block that eventually throws an exception. Because GCD requires all blocks to catch exceptions, and this block does not catch its own exception, the app crashes. Furthermore, because this is entirely within the Foundation framework, user code cannot catch the exception and is forced to crash. Version: iOS 8.1 (12B411) Notes: Configuration: iPhone 5c Attachments: 'writedata.txt' was successfully uploaded.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!