-
Notifications
You must be signed in to change notification settings - Fork 215
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
failed startVat won't fire criticalVat panic #9157
Comments
Ah, I think I can avoid the unnecessary DB call. Most This means that |
Previously, vat state initialization (e.g. setting counters to zero) happened lazily, the first time that `provideVatKeeper()` was called. When creating a new vat, the pattern was: vk = kernelKeeper.provideVatKeeper(); vk.setSourceAndOptions(source, options); Now, we initialize both counters and source/options explicitly, in `recordVatOptions`, when the static/dynamic vat is first defined: kernelKeeper.createVatState(vatID, source, options); In the future, this will make it easier for `provideVatKeeper` to rely upon the presence of all vat state keys, especially `options`. Previously, vatKeeper.getOptions() would tolerate a missing key by returning empty options. The one place where this was needed (terminating a barely-created vat because startVat() failed, using getOptions().critical) was changed, so this tolerance is no longer needed, and was removed. The tolerance caused bug #9157 (kernel doesn't panic when it should), which continues to be present, but at least won't cause a crash. refs #8980
Previously, vat state initialization (e.g. setting counters to zero) happened lazily, the first time that `provideVatKeeper()` was called. When creating a new vat, the pattern was: vk = kernelKeeper.provideVatKeeper(); vk.setSourceAndOptions(source, options); Now, we initialize both counters and source/options explicitly, in `recordVatOptions`, when the static/dynamic vat is first defined: kernelKeeper.createVatState(vatID, source, options); In the future, this will make it easier for `provideVatKeeper` to rely upon the presence of all vat state keys, especially `options`. Previously, vatKeeper.getOptions() would tolerate a missing key by returning empty options. The one place where this was needed (terminating a barely-created vat because startVat() failed, using getOptions().critical) was changed, so this tolerance is no longer needed, and was removed. The tolerance caused bug #9157 (kernel doesn't panic when it should), which continues to be present, but at least won't cause a crash. refs #8980
Previously, vat state initialization (e.g. setting counters to zero) happened lazily, the first time that `provideVatKeeper()` was called. When creating a new vat, the pattern was: vk = kernelKeeper.provideVatKeeper(); vk.setSourceAndOptions(source, options); Now, we initialize both counters and source/options explicitly, in `recordVatOptions`, when the static/dynamic vat is first defined: kernelKeeper.createVatState(vatID, source, options); In the future, this will make it easier for `provideVatKeeper` to rely upon the presence of all vat state keys, especially `options`. Previously, vatKeeper.getOptions() would tolerate a missing key by returning empty options. The one place where this was needed (terminating a barely-created vat because startVat() failed, using getOptions().critical) was changed, so this tolerance is no longer needed, and was removed. The tolerance caused bug #9157 (kernel doesn't panic when it should), which continues to be present, but at least won't cause a crash. refs #8980
Previously, vat state initialization (e.g. setting counters to zero) happened lazily, the first time that `provideVatKeeper()` was called. When creating a new vat, the pattern was: vk = kernelKeeper.provideVatKeeper(); vk.setSourceAndOptions(source, options); Now, we initialize both counters and source/options explicitly, in `recordVatOptions`, when the static/dynamic vat is first defined: kernelKeeper.createVatState(vatID, source, options); In the future, this will make it easier for `provideVatKeeper` to rely upon the presence of all vat state keys, especially `options`. Previously, vatKeeper.getOptions() would tolerate a missing key by returning empty options. The one place where this was needed (terminating a barely-created vat because startVat() failed, using getOptions().critical) was changed, so this tolerance is no longer needed, and was removed. The tolerance caused bug #9157 (kernel doesn't panic when it should), which continues to be present, but at least won't cause a crash. refs #8980
While working on #8980, I noticed a problem in the code which is supposed to panic the kernel if a "critical" vat gets terminated. If such a vat gets terminated super-early, during
buildRootObject()
, then it won't trigger the panic.This can only happen when a dynamic vat is marked as critical (requiring
criticalVatKey
) and fails its initial launch, perhaps because itsbuildRootObject()
throws an Error.The problem is in how we manage state. When a vat triggers a fatal termination-worthy error, it sets both
crankResults.abort
andcrankResults.terminate
. The.abort
causes us to unwind the state changes back to the point where we've popped the message off the run-queue (in this case acreate-vat
message):agoric-sdk/packages/SwingSet/src/kernel/kernel.js
Lines 1265 to 1275 in 8e87d58
then a moment later, the
.terminate
invokesterminateVat
:agoric-sdk/packages/SwingSet/src/kernel/kernel.js
Lines 1265 to 1275 in 8e87d58
which needs to retrieve the
critical
flag:agoric-sdk/packages/SwingSet/src/kernel/kernel.js
Lines 256 to 258 in 8e87d58
then deletes state (which only matter for later deliveries, after the vat has had a chance to create any promises or state):
agoric-sdk/packages/SwingSet/src/kernel/kernel.js
Lines 268 to 276 in 8e87d58
then uses
critical
to decide whether to panic the kernel or not :agoric-sdk/packages/SwingSet/src/kernel/kernel.js
Lines 277 to 288 in 8e87d58
The problem is that the
critical
flag is stored invNN.options
, which is part of the state that got unwound by the.abort
flag. So whenterminateVat
callsvatKeeper.getOptions()
to read out the.critical
flag, we end up relying upon a fallback insidevatKeeper.getOptions
that returns an emptyoptions
if the key was missing:agoric-sdk/packages/SwingSet/src/kernel/state/vatKeeper.js
Lines 126 to 130 in 8e87d58
So, in this case, we always get an empty options, which means
.critical
isundefined
, which is falsy, which inhibits the panic.Fixes
My vague plan is to add
.criticalVat
to thecrankResults
. At the beginning ofcreateVat
, we can populate this from theoptions
that are getting stored byoptionRecorder.recordDynamic()
. At the beginning of other deliveries, we can populated it from avatKeeper.getOptions().critical
. Then the post-delivery code can refer tocrankResults.criticalVat
instead of querying the vatKeeper (whose backing state might no longer be present).I'm not entirely happy with this approach, though, because it means an extra DB call for every delivery. We don't usually need to know whether a vat is critical or not, and the critical status doesn't change for the lifetime of the vat. So either a lazy lookup or something that gets cached (maybe in the vatKeeper, maybe in vat-warehouse) would be more satisfying.
The text was updated successfully, but these errors were encountered: