New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/mobile: accessing field on nil on iOS raises exception instead of panicking (gomobile) #23511

Open
cvermilion opened this Issue Jan 22, 2018 · 2 comments

Comments

Projects
None yet
4 participants
@cvermilion

cvermilion commented Jan 22, 2018

The spec says accessing a field (x.foo) should panic if x is nil, but it seems that in an iOS library built with gomobile, the result is an EXC_BAD_ACCESS exception being raised.

Please answer these questions before submitting your issue. Thanks!

What did you do?

If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.

Here's an example that works fine in a regular Go program but the equivalent compiled into an iOS app crashes: https://play.golang.org/p/KsIyVll7NE0.

What did you expect to see?

Accessing a field on nil panics, and is handled by a surrounding defer/recover block.

What did you see instead?

Accessing a field on nil raises a native exception, crashing the program unrecoverably.

System details

go version go1.9.2 darwin/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/verm/remix/amp"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.9.2/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.9.2/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/36/92jbhtpj41s6q3w4fcq2v01w0000gn/T/go-build431793073=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOROOT/bin/go version: go version go1.9.2 darwin/amd64
GOROOT/bin/go tool compile -V: compile version go1.9.2
uname -v: Darwin Kernel Version 16.7.0: Mon Nov 13 21:56:25 PST 2017; root:xnu-3789.72.11~1/RELEASE_X86_64
ProductName:	Mac OS X
ProductVersion:	10.12.6
BuildVersion:	16G1114
lldb --version: lldb-900.0.64
  Swift-4.0

@ianlancetaylor ianlancetaylor changed the title from Accessing field on nil on iOS raises exception instead of panicking (gomobile) to x/mobile: accessing field on nil on iOS raises exception instead of panicking (gomobile) Jan 23, 2018

@gopherbot gopherbot added this to the Unreleased milestone Jan 23, 2018

@gopherbot gopherbot added the mobile label Jan 23, 2018

@eliasnaur

This comment has been minimized.

Contributor

eliasnaur commented Mar 15, 2018

Have you tried to run your program outside the (Xcode) debugger or simply continuing execution after the exception is raised? I believe that the Go runtime will catch the exception and enable your recover to catch the panic.

@cvermilion

This comment has been minimized.

cvermilion commented Apr 1, 2018

Ah, interesting! I hadn't tried running it outside of Xcode. Continuing execution in Xcode doesn't work (just stays at the same exception), but if I run outside of Xcode, catching the panic works and the program functions normally.

So it seems like the issue is that Xcode's debugger is probably installing a signal handler that conflicts with how panics get caught.

OK, so to summarize then, there are two distinct ways this is a (minor) problem:

  1. Debugging a program in Xcode that links a Go library, an uncaught nil de-ref that would normally be trivial to debug can be a bit trickier to figure out, since you don't get the expected Go error response and stack trace. Xcode does show you the correct code location, though, so once you've run into this before it's not very hard to figure out what's going on. But if you don't spend a ton of time in Xcode on non-Go stuff it might be confusing.

  2. Running a program in Xcode, if you're relying on panic/defer/recover for normal execution flow, you may be out of luck if a panic you expect to happen occurs because of a nil deref. This seems like bad practice generally but I can't speak to how often this comes up in the wild.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment