
Xcode 9.1 Improves Display of Fatal Errors - Nuance
https://swift.org/blog/xcode-9-1-improves-display-of-fatal-errors/
======
M4v3R
This is one of those "how the hell Xcode didn't have this already?" type of
things. A very welcome change, I personally don't do much iOS development but
got those EXC_BAD_INSTRUCTION errors in past and they were always very
misleading to me.

~~~
bernadus_edwin
Rename refactoring swift also finally came after 2 years. Maybe xcode product
manager is replaced by someone who more understand developer. Every release on
xcode 9 has big impact. Gladly apple now hear developer. Before this, xcode 8
is the worst IDE

~~~
flipgimble
Or more realistically and less dramatically, some these big features took a
lot of effort and engineering investment before they were ready for
production.

Apple tends to re-think the current technology and implements their ideal
solution. This takes longer but avoids the duck tape approach I've seen in
various iterations of Visual Studio. As a concrete example the refactoring
tools in Xcode9 work for both C++ (for the first time!), Objective-C and Swift
using the same framework.

Best of all the API to write your own refactoring tools has been carefully
designed, and there have been some high quality external contributions already
to the refactoring tools.

~~~
binthere
I actually think Visual Studio does refactoring pretty well. It is not a new
innovation from Apple. Xcode, in this case, is just catching up with a much
needed feature and I still think it's not quite there.

~~~
favorited
It looks the implementation was a significant investment. They built a
language-agnostic refactoring engine into Clang and open-sourced it
[http://lists.llvm.org/pipermail/cfe-
dev/2017-June/054286.htm...](http://lists.llvm.org/pipermail/cfe-
dev/2017-June/054286.html)

------
matwood
One thing I've never understood is why break on all exceptions is not the
default in Xcode. It'll happy crash the app with an assembly stack trace with
no way to see the offending code unless break on all exceptions is setup.

~~~
eridius
Because there's no way for the debugger to only break on uncaught exceptions,
and you don't usually want to break on caught exceptions. Various frameworks
(most infamously CoreData) use caught exceptions internally as a control flow
tool.

~~~
pavlov
There are a few places in AppKit where you need to determine an object's state
by catching an exception because there's no method available. (Checking
whether an NSColor is a pattern comes to mind -- only way is to try getting
the pattern image and it will throw if it's not a pattern color.)

The really frustrating thing is that Obj-C didn't even have exceptions
originally, so someone basically looked at exceptions when they were added and
thought: "I know, I'll use them as part of the API"...

~~~
mnem
Can't you check if the NSColor.type == NSColorTypePattern?

~~~
pavlov
I might be misremembering that one! Will have to check. Thanks!

~~~
eridius
NSColor.type is new in macOS 10.13.

------
0x0
Is this the first time a feature is exclusive to swift, and not available for
Objective-C? I wish they would offer this for regular Objective-C apps as
well. UIApplication is an objc class after all!

~~~
Someone
Objective-C is C; it doesn’t do the various range and nil checks that Swift
does to exit properly.

Because of that, it cannot do that.

~~~
nielsbot
not entirely true. if you use Obj-C data types (NSArray etc) you get an
exception for out-of-range accesses.

~~~
0x0
Right, I feel like I've seen exceptions for a lot of errors ending up with
xcode hanging on an exc_bad_whatever disassembly of some sort of main()
routine, things like putting nil values in arrays, inconsistent uitableview
datasource implementations, etc. Usually shows an alright stack trace logged
to the console but the main xcode editor still opens a useless disassembler in
system code?

~~~
eridius
Stick `po $arg1` in your exception breakpoint and it will print the exception
(well, for Obj-C exceptions; I don't remember offhand how to look at C++
exceptions since I so rarely deal with them).

~~~
0x0
Thanks for the tip. It's usually not a problem to figure out what's wrong (the
exception is dumped to the debugger), but it's a bit useless that the main
editor in xcode switches to an irrelevant disassembly view at the same time :)

~~~
eridius
It shouldn't. Xcode usually switches to the shallowest stack frame that has
source code available when hitting a breakpoint.

~~~
0x0
Oh, I was talking about uncaught exceptions where no breakpoint has been set.

~~~
eridius
Uncaught exceptions don't enter the debugger until it bubbles back up to
main(), so the stack in the debugger is useless there.

~~~
0x0
Right, I was hoping this new Xcode 9.1 feature could improve upon that for
Objective-C as well. Perhaps capturing a copy of the stack when the exception
is raised, so it open the main editor window on the appropriate source line
where that exception was raised.

------
jarjoura
> Note that this improved experience is only available when the app’s entry
> point is written in Swift (i.e. your app delegate with the
> @UIApplicationMain/@NSApplicationMain attribute).

Interesting requirement, is this because it requires a predictable entry
codepath in order to work?

~~~
eridius
I'm guessing because it has to insert code into main() to set up the
coordination with Xcode.

EDIT:

Ok, I looked into it. There's no code inserted into main(). The way this works
is Xcode sets up an internal breakpoint on _swift_runtime_on_report, which is
an empty function that is called during fatal errors specifically to allow
Xcode to break on it.

I don't know why this requires main() to be written in Swift.

~~~
nielsbot
and/or some type of custom exception/signal handler?

------
applecorruption
Xcode have soo so many places where it need to be fixed. No wonder why people
rather use android studio. And swift version is changing every 6 momths to
ruin everything.. good luck

------
woolvalley
So if we use swift to write our main function and call UIApplicationMain, then
this wouldn't apply?

~~~
eridius
Yeah it does. I tested a CLI app in Xcode 9.1 which was just a single
main.swift file and it showed my fatalError() nicely.

