Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
2.7.5
-
None
-
Java 11 / Linux / JavaMelody (but should not be related)
Description
When cancelling an other query from an other thread, you might get an NPE in rare cases:
java.lang.NullPointerException
|
at org.mariadb.jdbc.MariaDbStatement.skipMoreResults(MariaDbStatement.java:1187)
|
at org.mariadb.jdbc.MariaDbStatement.cancel(MariaDbStatement.java:981)
|
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
|
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
|
at net.bull.javamelody.JdbcWrapper$StatementInvocationHandler.invoke(JdbcWrapper.java:163)
|
at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:306)
|
at com.sun.proxy.$Proxy345.cancel(Unknown Source)
|
at io.ebean.util.JdbcClose.cancel(JdbcClose.java:76)
|
As you see, 'protocol' is null in https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L1187
I investigate a bit and have the following explanation for the bug:
Thread #1 starts a query
Thread #2 tries to cancel the query.
It invokes L980 protocol.cancelCurrentQuery() successfully
Thread #1 now closes the query and sets protocol = null
When Thread #2 tries to execute L981, which calls L1187 protocol.skip() - you get an NPE.
There is no kind of locking the access of protocol and this can be modified in a concurrent thread.
Unfortunately, I cannot provide a test. The bug is very hard to reproduce and happens only in production...
Side note: I think the bug may not happen with 3.x, because the code is totally different (but we did not update to 3.x, yet)
Attachments
Activity
Field | Original Value | New Value |
---|---|---|
Description |
When cancelling an other query from an other thread, you might get an NPE in rare cases:
{code} java.lang.NullPointerException at org.mariadb.jdbc.MariaDbStatement.skipMoreResults(MariaDbStatement.java:1187) at org.mariadb.jdbc.MariaDbStatement.cancel(MariaDbStatement.java:981) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at net.bull.javamelody.JdbcWrapper$StatementInvocationHandler.invoke(JdbcWrapper.java:163) at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:306) at com.sun.proxy.$Proxy345.cancel(Unknown Source) at io.ebean.util.JdbcClose.cancel(JdbcClose.java:76) {code} As you see, 'protocol' is null in https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L1187 I investigate a bit and have the following explanation for the bug: Thread #1 starts a query Thread #2 tries to cancel the query. It invokes [protocol.cancelCurrentQuery()|https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L980] successfully Thread #1 now closes the query and sets [protocol = null|https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L805] When Thread #2 tries to execute [protocol.skip()|https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L1187] - you get an NPE. There is no kind of locking the access of protocol and this can be modified in a concurrent thread. Unfortunately, I cannot provide a test. The bug is very hard to reproduce and happens only in production... Side note: I think the bug may not happen with 3.x, because the code is totally different (but we did not update to 3.x, yet) |
When cancelling an other query from an other thread, you might get an NPE in rare cases:
{code} java.lang.NullPointerException at org.mariadb.jdbc.MariaDbStatement.skipMoreResults(MariaDbStatement.java:1187) at org.mariadb.jdbc.MariaDbStatement.cancel(MariaDbStatement.java:981) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at net.bull.javamelody.JdbcWrapper$StatementInvocationHandler.invoke(JdbcWrapper.java:163) at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:306) at com.sun.proxy.$Proxy345.cancel(Unknown Source) at io.ebean.util.JdbcClose.cancel(JdbcClose.java:76) {code} As you see, 'protocol' is null in https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L1187 I investigate a bit and have the following explanation for the bug: Thread #1 starts a query Thread #2 tries to cancel the query. It invokes L980 [protocol.cancelCurrentQuery()|https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L980] successfully Thread #1 now closes the query and sets [protocol = null|https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L805] When Thread #2 tries to execute L981, which calls L1187 [protocol.skip()|https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L1187] - you get an NPE. There is no kind of locking the access of protocol and this can be modified in a concurrent thread. Unfortunately, I cannot provide a test. The bug is very hard to reproduce and happens only in production... Side note: I think the bug may not happen with 3.x, because the code is totally different (but we did not update to 3.x, yet) |
Fix Version/s | 2.7.7 [ 28325 ] |
Status | Open [ 1 ] | In Progress [ 3 ] |
issue.field.resolutiondate | 2022-09-30 12:33:15.0 | 2022-09-30 12:33:15.584 |
Component/s | Other [ 12201 ] | |
Resolution | Fixed [ 1 ] | |
Status | In Progress [ 3 ] | Closed [ 6 ] |
Thanks for detailed explaination.
This will be corrected in next version.