Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

cannot pass SIGSEGV on darwin arm #22867

Open Quuxplusone opened 9 years ago

Quuxplusone commented 9 years ago
Bugzilla Link PR22868
Status NEW
Importance P normal
Reported by David Crawshaw (crawshaw@golang.org)
Reported on 2015-03-10 07:42:22 -0700
Last modified on 2020-09-01 11:40:44 -0700
Version unspecified
Hardware Other MacOS X
CC jingham@apple.com, keno@alumni.harvard.edu, lewurm@gmail.com, thelastmammoth@gmail.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
On darwin arm (iOS 8.1.3, XCode 6.1.1) lldb always stops on EXC_BAD_ACCESS and
will not continue. The result is SIGSEGV cannot be passed. That is, this does
not work:

    process handle SIGSEGV --stop false --pass true --notify false

Programs that expect to continue processing by turning SIGSEGV into an
exception cannot be run under lldb. In particular this affects the Go
programming language:

https://golang.org/issue/10043

For now we are working around it by registering a mach exception handler on the
thread port. But ideally lldb would be able to see the signal and choose what
to do with it.

This issue was also brought up on lldb-dev:

http://lists.cs.uiuc.edu/pipermail/lldb-dev/2013-July/002009.html
Quuxplusone commented 9 years ago

This is a longstanding bug on OS X. It doesn't have to do with catching the SIGSEGV, the problem is converting the EXC_BAD_ACCESS into a SIGSEGV. The straight-forward way to do this requires that the debugger run as root, which is not acceptable. The other way to do this - using PT_THUPDATE - has bugs on the kernel side that make it not work either.

The way we worked around this in gdb was to have a mode where the debugger didn't listen for EXC_BAD_ACCESS, so it got the SIGSEGV directly - in which case it could be passed on to the registered handler. But lldb's debugserver doesn't currently multiplex Mach exceptions & BSD signals, it only listens for Mach exceptions. So that would have to be added to debugserver, which given that this is really just a hack I'm not so willing to do.

The other alternative is to work around the kernel bug - which is that a PT_THUPDATE only works on a thread that is stopped with an EXC_SOFT_SIGNAL - by suspending all threads but the one that crashed, resuming the process with a SIGSTOP, then when you stop with the EXC_SOFT_SIGNAL, not the EXC_BAD_ACCESS again, then use PT_THUPDATE to generate the SIGSEGV by hand.

Anyway, given the problems resolving this, you're probably better off working around it in golang.

Quuxplusone commented 9 years ago

I'm very interested in getting this bug resolved. If there's a kernel bug, can't we get somebody at Apple to look at that? If that's not happening, I'd be happy to try to fix this myself if somebody can point me in the right direction.

Quuxplusone commented 9 years ago

Alternatively, could we just add a command that tells the debugger to temporarily ignore EXC_BAD_ACCESS?

Quuxplusone commented 5 years ago

_Bug 40669 has been marked as a duplicate of this bug._

Quuxplusone commented 4 years ago
The workaround by the Go runtime seems pretty complicated:
https://github.com/golang/go/commit/1b49a86ecece3978ceba60c372327b9cbcc68501

The Mono runtime uses a imho much simpler workaround (inspired by what
OpenJDK/HotSpot is doing):
https://github.com/mono/mono/pull/20321/files
Quuxplusone commented 4 years ago

When I tried just not watching for EXC_BAD_ACCESS and EXC_BAD_INSTRUCTION in the early days of lldb, we didn't get the resultant SIGSEGV, so this wasn't a viable option. But it looks like something in the system has changed and now we do get the signal stop if we just don't listen for the exception.

The information in the mach exceptions is more full than in the signals, so the exception version is preferable for most users. But it would be fine to add a mode that switches off the handling for these two two exceptions that the few people debugging programs that require SIGSEGV handlers to function.