plasma-umass / doppio

Breaks the browser language barrier (includes a plugin-free JVM).
http://plasma-umass.github.io/doppio-demo
MIT License
2.16k stars 175 forks source link

[natives_refactor] Error: Assertion failed: Invalid thread transition: RUNNABLE => ASYNC_WAITING #314

Closed deathcap closed 10 years ago

deathcap commented 10 years ago

src/threading.ts can attempt to transition from RUNNABLE to ASYNC_WAITING, in scheduleException():

            // ASYNC PATH: We'll need to asynchronously resolve these handlers.
            debug(method.full_signature() + " needs to resolve some exception types...");
            var handlerClasses: string[] = [];
            exceptionHandlers.forEach((handler: attributes.ExceptionHandler) => {
              if (handler.catch_type !== "<any>") {
                handlerClasses.push(handler.catch_type);
              }
            });
            thread.setStatus(enums.ThreadStatus.ASYNC_WAITING); // ***

Reproduction case (unfortunately haven't been able to reduce further — but the problem appears to be triggered by throwing a NoSuchMethodError from another thread(?)):

jar: https://dl.dropboxusercontent.com/u/258156216/java/junket-0.0.1-314-849b703.jar (source: https://github.com/deathcap/Junket/commit/4f3873de1fc0dc39563140aa98c081ba1e72c312)

copy to 'plugins' directory: https://dl.dropboxusercontent.com/u/258156216/java/bukkit-sample-plugin-0.5-05.jar (source: https://github.com/deathcap/SamplePlugin/commit/24580cd03cd76ba818260fb3cd1631dd2d1c76ce)

using doppio natives_refactor as of https://github.com/plasma-umass/doppio/commit/9601860443a48f37db16750bf73983e5bbc39dd6

Junket $  ../doppio/doppio-dev -jar /tmp/junket-0.0.1-314-849b703.jar 
Hello
May 18, 2014 3:37:01 AM deathcap.junket.ServerImpl <init>
INFO: ServerImpl starting...
May 18, 2014 3:37:08 AM org.bukkit.Bukkit setServer
INFO: This server is running null version null (Implementing API version null)
May 18, 2014 3:37:09 AM deathcap.junket.ServerImpl loadPlugins
INFO: Loading plugins...
Error: Assertion failed: Invalid thread transition: RUNNABLE => ASYNC_WAITING
    at assert (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/assert.ts:6:11)
    at JVMThread.setStatus (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:630:7)
    at BytecodeStackFrame.scheduleException (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:154:20)
    at JVMThread.throwException (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:829:46)
    at InternalStackFrame.cb (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:858:18)
    at InternalStackFrame.run (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:306:12)
    at JVMThread.run (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:568:31)
    at JVMThread.setStatus (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:652:16)
    at Object._onImmediate (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:393:24)
    at processImmediate [as _immediateCallback] (timers.js:330:15)

vs with a native JVM:

Junket $ java -jar /tmp/junket-0.0.1-314-849b703.jar 
Hello
May 17, 2014 8:37:17 PM deathcap.junket.ServerImpl <init>
INFO: ServerImpl starting...
May 17, 2014 8:37:17 PM org.bukkit.Bukkit setServer
INFO: This server is running null version null (Implementing API version null)
May 17, 2014 8:37:17 PM deathcap.junket.ServerImpl loadPlugins
INFO: Loading plugins...
May 17, 2014 8:37:17 PM deathcap.junket.ServerImpl loadPlugins
INFO: Loaded 1 plugins
May 17, 2014 8:37:17 PM deathcap.junket.ServerImpl loadPlugins
INFO: Enabling plugin SamplePlugin v0.5
May 17, 2014 8:37:17 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] Enabling SamplePlugin v0.5
May 17, 2014 8:37:17 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] SamplePlugin version 0.5 is enabled!
May 17, 2014 8:37:17 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] dirt = DIRT, name = DIRT, ordinal=3
May 17, 2014 8:37:17 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got stone
May 17, 2014 8:37:17 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got dirt
May 17, 2014 8:37:17 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got else
May 17, 2014 8:37:17 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got null

According to validTransitions, RUNNABLE can currently only transition to RUNNING. Should it transition RUNNABLE => RUNNING => ASYNC_WAITING, or should RUNNABLE => ASYNC_WAITING be added as valid?

deathcap commented 10 years ago

Transitioning through RUNNING first causes an invalid array length error, but allowing the transition directly to ASYNC_WAITING seems to work, although I don't know if there are other unintended consequences of allowing this.

jvilk commented 10 years ago

@deathcap: Yeah, only the thread scheduler should ever setState(RUNNING), since only one thread should be running at once.

Thanks for catching this.