WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 213160
Signal handlers should have a two phase installation.
https://bugs.webkit.org/show_bug.cgi?id=213160
Summary
Signal handlers should have a two phase installation.
Keith Miller
Reported
2020-06-12 18:28:54 PDT
Signal handlers should have a two phase installation.
Attachments
Patch
(14.19 KB, patch)
2020-06-12 18:34 PDT
,
Keith Miller
no flags
Details
Formatted Diff
Diff
Patch
(15.95 KB, patch)
2020-06-12 18:54 PDT
,
Keith Miller
no flags
Details
Formatted Diff
Diff
Patch
(17.07 KB, patch)
2020-06-12 19:43 PDT
,
Keith Miller
no flags
Details
Formatted Diff
Diff
Patch
(17.07 KB, patch)
2020-06-12 19:45 PDT
,
Keith Miller
no flags
Details
Formatted Diff
Diff
Patch
(17.00 KB, patch)
2020-06-13 11:17 PDT
,
Keith Miller
no flags
Details
Formatted Diff
Diff
Patch for landing
(17.21 KB, patch)
2020-06-15 10:53 PDT
,
Keith Miller
no flags
Details
Formatted Diff
Diff
Show Obsolete
(5)
View All
Add attachment
proposed patch, testcase, etc.
Keith Miller
Comment 1
2020-06-12 18:34:48 PDT
Created
attachment 401817
[details]
Patch
Keith Miller
Comment 2
2020-06-12 18:54:58 PDT
Created
attachment 401818
[details]
Patch
Mark Lam
Comment 3
2020-06-12 19:14:45 PDT
Comment on
attachment 401818
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=401818&action=review
Some comments for now. I'll do a proper review later.
> Source/WTF/ChangeLog:10 > + With Mach exception handlers installed the OS will send a mach message
comma after "installed" please.
> Source/WTF/ChangeLog:12 > + When this happens the combination of LLDB and the process JSC is in effectively
comma after "happens" please.
> Source/WTF/ChangeLog:15 > + Under our new approach we go back to only telling the OS we care about
comma after "approach" please.
> Source/JavaScriptCore/jsc.cpp:3243 > + Wasm::enableFastMemory();
Please fix the indentation.
Keith Miller
Comment 4
2020-06-12 19:43:27 PDT
Created
attachment 401821
[details]
Patch
Keith Miller
Comment 5
2020-06-12 19:45:56 PDT
Created
attachment 401822
[details]
Patch
Mark Lam
Comment 6
2020-06-12 21:20:22 PDT
Comment on
attachment 401822
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=401822&action=review
> Source/WTF/ChangeLog:17 > + Under our new approach, we go back to only telling the OS we care about > + these exceptions late but lock down the function pointers early. This way > + processes that benefit from our exception handler code are easier to debug.
Given my comment below about what should be done in activateSignalHandlersFor(), I would change this to say: Under our new approach, we go back to registering threads to listen for exceptions late, but lock down all other details about mach exceptions early (including the function pointers, the exception mask, and the exception port). ...
> Source/WTF/wtf/threads/Signals.cpp:243 > + kern_return_t result = thread_set_exception_ports(thread.machThread(), activeExceptions, handlers.exceptionPort, EXCEPTION_STATE | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE);
Let's undo this and keep activeExceptions in the Config (see details below).
> Source/WTF/wtf/threads/Signals.cpp:279 > +static std::once_flag initializeOnceFlags[static_cast<size_t>(Signal::NumberOfSignals)];
Why move this outside of addSignalHandler? No one else needs it.
> Source/WTF/wtf/threads/Signals.cpp:-295 > - Config::AssertNotFrozenScope assertScope;
Please keep this. It defends against bugs where we end up jumping into this lambda function. We want to make sure that this lambda function is never called once we freeze the Config.
> Source/WTF/wtf/threads/Signals.cpp:317 > + ASSERT(signal < Signal::Unknown); > + ASSERT(!handlers.useMach || signal != Signal::Usr);
Make these ASSERT_UNUSED so that !HAVE(MACH_EXCEPTIONS) builds won't complain about an unused arguments and variables.
> Source/WTF/wtf/threads/Signals.cpp:319 > + > +
Remove excess empty lines.
> Source/WTF/wtf/threads/Signals.cpp:324 > + activeExceptions |= toMachMask(signal);
Why can't you set activeExceptions in addSignalHandler()? If a bug overwrites this and removes a Signal type, we may inadvertently disable signal handling that we're depending on. Let's do this: 1. keep the activeExceptions mask in the Config's handlers record. 2. In addSignalHandler(), set `handlers.activeExceptions |= toMachMask(signal);` 3. In activateSignalHandlersFor(), do this instead: `RELEASE_ASSERT(handlers.activeExceptions & toMachMask(signal));`. This is ensure that addSignalHandler() was called for this Signal type as expected. After reading thru this patch, I'm convinced that the only real work that activateSignalHandlersFor() needs to do is simply to register the threads by calling setExceptionPorts() on them.
Mark Lam
Comment 7
2020-06-12 21:20:55 PDT
Comment on
attachment 401822
[details]
Patch r- for now since EWS bots are red anyway. Please revise the patch.
Keith Miller
Comment 8
2020-06-13 11:02:56 PDT
Comment on
attachment 401822
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=401822&action=review
>> Source/WTF/wtf/threads/Signals.cpp:279 >> +static std::once_flag initializeOnceFlags[static_cast<size_t>(Signal::NumberOfSignals)]; > > Why move this outside of addSignalHandler? No one else needs it.
sure.
>> Source/WTF/wtf/threads/Signals.cpp:-295 >> - Config::AssertNotFrozenScope assertScope; > > Please keep this. It defends against bugs where we end up jumping into this lambda function. We want to make sure that this lambda function is never called once we freeze the Config.
Ah yeah, that got incidentally deleted while moving code around. I'll put it back.
>> Source/WTF/wtf/threads/Signals.cpp:317 >> + ASSERT(!handlers.useMach || signal != Signal::Usr); > > Make these ASSERT_UNUSED so that !HAVE(MACH_EXCEPTIONS) builds won't complain about an unused arguments and variables.
sure.
>> Source/WTF/wtf/threads/Signals.cpp:324 >> + activeExceptions |= toMachMask(signal); > > Why can't you set activeExceptions in addSignalHandler()? If a bug overwrites this and removes a Signal type, we may inadvertently disable signal handling that we're depending on. > > Let's do this: > 1. keep the activeExceptions mask in the Config's handlers record. > 2. In addSignalHandler(), set `handlers.activeExceptions |= toMachMask(signal);` > 3. In activateSignalHandlersFor(), do this instead: `RELEASE_ASSERT(handlers.activeExceptions & toMachMask(signal));`. This is ensure that addSignalHandler() was called for this Signal type as expected. > > After reading thru this patch, I'm convinced that the only real work that activateSignalHandlersFor() needs to do is simply to register the threads by calling setExceptionPorts() on them.
I think that's a riskier change because then all signals get turned on at once. Until we have a real fix for LLDB I want to make sure we only have the handlers installed when we actually need them. I don't think the badness from accidentally clearing the bits is that bad since, IIRC, the API will just leave the old handler in place. But even calling setExceptionPorts disables the other handler it's just gonna be a crash because no there's no handler.
Keith Miller
Comment 9
2020-06-13 11:17:48 PDT
Created
attachment 401844
[details]
Patch
Mark Lam
Comment 10
2020-06-13 12:32:20 PDT
(In reply to Keith Miller from
comment #8
)
> > After reading thru this patch, I'm convinced that the only real work that activateSignalHandlersFor() needs to do is simply to register the threads by calling setExceptionPorts() on them. > > I think that's a riskier change because then all signals get turned on at > once. Until we have a real fix for LLDB I want to make sure we only have the > handlers installed when we actually need them. > > I don't think the badness from accidentally clearing the bits is that bad > since, IIRC, the API will just leave the old handler in place. But even > calling setExceptionPorts disables the other handler it's just gonna be a > crash because no there's no handler.
After thinking about this more, I agree that subtracting masks is not an issue because it means we will just crash. However, I think adding masks can still be an issue. I'll propose a change in your patch.
Mark Lam
Comment 11
2020-06-13 13:02:06 PDT
Comment on
attachment 401844
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=401844&action=review
r=me with fixes for limiting what signals can be activated.
> Source/WTF/ChangeLog:13 > + LLDB does not like it when we single step while there are mach exception > + handlers installed because LLDB suspends all the non-active threads. > + With Mach exception handlers installed, the OS will send a mach message > + to our exception handler port, which is different than the active thread. > + When this happens, the combination of LLDB and the process JSC is in effectively > + deadlock.
It's not clear to me how this patch fixes the LLDB deadlock? At some point, we will call setExceptionPort() for the signals we wish to handle. How does having delayed the call to setExceptionPort() help after that it does get called? Wouldn't LLDB also still deadlock then? Or are you saying that you're only reducing the probability of deadlock here and not actually fixing it completely? Can you comment and clarify this point in the ChangeLog. Anyway, I think this patch is an improvement.
> Source/WTF/wtf/threads/Signals.cpp:243 > + kern_return_t result = thread_set_exception_ports(thread.machThread(), activeExceptions, handlers.exceptionPort, EXCEPTION_STATE | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE);
Replace "activeExceptions" with "activeExceptions & handlers.addedExceptions" here.
> Source/WTF/wtf/threads/Signals.cpp:-295 > - Config::AssertNotFrozenScope assertScope;
Please restore this Config::AssertNotFrozenScope.
> Source/WTF/wtf/threads/Signals.cpp:323 > - handlers.activeExceptions |= toMachMask(signal); > + activeExceptions |= toMachMask(signal);
To ensure that we don't allow activating any handlers for signals that we didn't explicitly call addSignalHandler() for, let's do the following: 1. In SignalHandlers::add(), please add the following: addedExceptions |= toMachMask(signal); 2. Here in activateSignalHandlersFor(), change this line to: activeExceptions |= (toMachMask(signal) & handlers.addedExceptions);
> Source/WTF/wtf/threads/Signals.h:112 > exception_mask_t activeExceptions;
Rename this "activeExceptions" field to to "addedExceptions".
Keith Miller
Comment 12
2020-06-15 10:52:17 PDT
Comment on
attachment 401844
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=401844&action=review
>> Source/WTF/ChangeLog:13 >> + deadlock. > > It's not clear to me how this patch fixes the LLDB deadlock? At some point, we will call setExceptionPort() for the signals we wish to handle. How does having delayed the call to setExceptionPort() help after that it does get called? Wouldn't LLDB also still deadlock then? Or are you saying that you're only reducing the probability of deadlock here and not actually fixing it completely? Can you comment and clarify this point in the ChangeLog. > > Anyway, I think this patch is an improvement.
It doesn't fix the LLDB issue, I'll clarify that in the changelog. This patch is just to reduce the prevalence of the bug back to were it was. In a follow up patch I plan on only turning on the WASM memory when we lazily allocate the WebAssembly object.
>> Source/WTF/wtf/threads/Signals.cpp:243 >> + kern_return_t result = thread_set_exception_ports(thread.machThread(), activeExceptions, handlers.exceptionPort, EXCEPTION_STATE | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE); > > Replace "activeExceptions" with "activeExceptions & handlers.addedExceptions" here.
That's a good idea. I'll rename it to `handlers.registeredExecptions` though.
>> Source/WTF/wtf/threads/Signals.cpp:-295 >> - Config::AssertNotFrozenScope assertScope; > > Please restore this Config::AssertNotFrozenScope.
Done. I didn't mean for this version of the patch to be marked r? >.>
>> Source/WTF/wtf/threads/Signals.cpp:323 >> + activeExceptions |= toMachMask(signal); > > To ensure that we don't allow activating any handlers for signals that we didn't explicitly call addSignalHandler() for, let's do the following: > 1. In SignalHandlers::add(), please add the following: > addedExceptions |= toMachMask(signal); > 2. Here in activateSignalHandlersFor(), change this line to: > activeExceptions |= (toMachMask(signal) & handlers.addedExceptions);
I don't think we need to change this line because we will & with registeredExceptions.
>> Source/WTF/wtf/threads/Signals.h:112 >> exception_mask_t activeExceptions; > > Rename this "activeExceptions" field to to "addedExceptions".
Ditto on renaming.
Keith Miller
Comment 13
2020-06-15 10:53:19 PDT
Ehhh, I decided against registeredExecptions in favor of addedExcepions.
Keith Miller
Comment 14
2020-06-15 10:53:50 PDT
Created
attachment 401910
[details]
Patch for landing
EWS
Comment 15
2020-06-15 11:30:03 PDT
Committed
r263045
: <
https://trac.webkit.org/changeset/263045
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 401910
[details]
.
Radar WebKit Bug Importer
Comment 16
2020-06-15 11:31:25 PDT
<
rdar://problem/64372103
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug