-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Catch writes to protected memory in mmapped arrays (fix #3434)
- Loading branch information
Showing
2 changed files
with
73 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really cool if you can make it work nicely!
a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I think it already works nicely 😄.
I should point out that I went to more effort than is perhaps necessary in a perverse attempt to allow segfaults to happen in certain situations. For example,
unsafe_store!(convert(Ptr{Int}, 0), 3, 1)
still segfaults after this patch, because0
is not going to be within a span of memory addresses corresponding to ammap
ped file. Likewise, if you do this:then when
A
is a read-only block of 10 elements,g
will result in aMemoryError
butf
will segfault. This happens becauseA[11]
is not within the "trapped" block of memory (because it is not within the bounds of the array), and using@inbounds
circumvents theBoundsError
that would normally result, so you end up getting a segfault. It would of course be a slightly shorter patch if we just threw aMemoryError
for anything that would have resulted in a segfault---I had to go to extra effort to allow the segfault to happen---but for better or for worse I decided to make this minimalistic in terms of the way in which it changes julia's behavior. If you prefer the bigger change of trappingSIGSEGV
under all circumstances, do let me know.a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually considered making all Segfaults throw back when I implemented proper stack overflow support for Mac, but it was considered to easy to catch, so we took it out again.
a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, would it make more sense to just look for
SEGV_ACCERR
rather than dealing with protected regions?a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have looked more closely at what goodies
siginfo_t
provides. I like it.a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If segfaults where uncatchable errors (see #6845) and used a signal handling interface instead, then it would be much more reasonable for segfaults to produce errors rather than terminating the process.
a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always find myself writing type assertions when catching exceptions.
If that syntax was allowed, we could have
catch
without assertion only catch subtypes ofabstract Exception
.InterruptException
andSegmentationFault
would not inherit fromabstract Exception
, and thus you would need to specify them explicitly if you wanted to catch them.a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have realized that SIGINT and SIGSEGV are fundamentally different – SIGSEGV indicates that the code that's running made an error and cannot continue correctly. SIGINT has no such implication – it's a purely external signal.
a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the error is uncatchable, wouldn't that cover the fact that the code simply can't complete?
Of course, the more serious concern is that your generic SIGSEGV might indicate that julia is in a corrupted state, and under those circumstances you probably wouldn't want to try to continue. We seem to have at least some protections against this; for example, using this branch let's try to trash the method table for
sum
:So we weren't able to trash that memory location, and since it didn't succeed we don't actually have to worry about julia being corrupt.
However, the compiler (among others) surely could corrupt a method; if that happened for a method needed by the REPL, trying to cope with that error without crashing julia sounds like a dicey proposition. I fear we could pretty quickly get into forced termination/ctrl-alt-delete territory. I'm a little worried that this less "picky" version of this patch (which does away with the explicit check that this is just issue #3434) might already move us in that direction.
a339592
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, since this is a branch comment thread and isn't linked with the original PR, I should have clarified what I meant by the "less picky" version of this patch.