You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
It is possible to find some bad interleaving where one thread is writing from a synchronized block and another thread is reading the same variable from another method which is not synchronized. Here, flushandclosestate is a shared variable which is updated from a synchronized block at Line 596, but another thread uses flushandclosestate at Line 615 which is not synchronized. I can observe such an execution results in the assertion fail from running an existing test org.java_websocket.issues.Issue256Test with some added delay just before Line 596 of WebSocketImpl, resulting in the following stack trace.
Debug log
Tests run: 20, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.823 sec <<< FAILURE!
runReconnectSocketClose6 Time elapsed: 1.013 sec <<< FAILURE!
java.lang.AssertionError: Found 1 zombie thread(s)
at org.junit.Assert.fail(Assert.java:88)
at org.java_websocket.util.ThreadCheck.checkZombies(ThreadCheck.java:74)
at org.java_websocket.util.ThreadCheck.after(ThreadCheck.java:53)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:50)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Results :
Tests run: 20, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.823 sec <<< FAILURE!
runReconnectSocketClose6 Time elapsed: 1.013 sec <<< FAILURE!
java.lang.AssertionError: Found 1 zombie thread(s)
Tests in error:
Failed tests: runReconnectSocketClose6: Found 1 zombie thread(s)
Tests run: 20, Failures: 1, Errors: 0, Skipped: 0
To Reproduce
Steps to reproduce the behavior:
Add Thread.sleep(100) before Line 596
Run mvn test -Dtest=org.java_websocket.issues.Issue256Test -Dcheckstyle.skip
Expected behavior
Test failure should not occur
Additional context
When I investigated the WebSocketImpl class, I find flushandclosestate is a shared variable that is used on Line 615 and Line 596. By injecting a delay before Line 596 of WebSocketImpl.java, I could get a different thread interleaving where the variable flushandclosestate was not set to true when other threads were trying to close connection at Line 615. As a result, the assertion fails.
Environment(please complete the following information):
I ran the test on an Ubuntu 20.04 LTS machine using OpenJDK 1.8.0_312.
The text was updated successfully, but these errors were encountered:
Commit version- aad6654
Describe the bug
It is possible to find some bad interleaving where one thread is writing from a synchronized block and another thread is reading the same variable from another method which is not synchronized. Here, flushandclosestate is a shared variable which is updated from a synchronized block at Line 596, but another thread uses flushandclosestate at Line 615 which is not synchronized. I can observe such an execution results in the assertion fail from running an existing test org.java_websocket.issues.Issue256Test with some added delay just before Line 596 of WebSocketImpl, resulting in the following stack trace.
Debug log
Tests run: 20, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.823 sec <<< FAILURE!
runReconnectSocketClose6 Time elapsed: 1.013 sec <<< FAILURE!
java.lang.AssertionError: Found 1 zombie thread(s)
at org.junit.Assert.fail(Assert.java:88)
at org.java_websocket.util.ThreadCheck.checkZombies(ThreadCheck.java:74)
at org.java_websocket.util.ThreadCheck.after(ThreadCheck.java:53)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:50)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Results :
Tests run: 20, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.823 sec <<< FAILURE!
runReconnectSocketClose6 Time elapsed: 1.013 sec <<< FAILURE!
java.lang.AssertionError: Found 1 zombie thread(s)
Tests in error:
Failed tests: runReconnectSocketClose6: Found 1 zombie thread(s)
Tests run: 20, Failures: 1, Errors: 0, Skipped: 0
To Reproduce
Steps to reproduce the behavior:
Add Thread.sleep(100) before Line 596
Run mvn test -Dtest=org.java_websocket.issues.Issue256Test -Dcheckstyle.skip
Expected behavior
Test failure should not occur
Additional context
When I investigated the WebSocketImpl class, I find flushandclosestate is a shared variable that is used on Line 615 and Line 596. By injecting a delay before Line 596 of WebSocketImpl.java, I could get a different thread interleaving where the variable flushandclosestate was not set to true when other threads were trying to close connection at Line 615. As a result, the assertion fails.
Environment(please complete the following information):
I ran the test on an Ubuntu 20.04 LTS machine using OpenJDK 1.8.0_312.
The text was updated successfully, but these errors were encountered: