[Bug] random warnings/exceptions on reachableBy operation over C source code
Describe the bug
I have Ghidra decompiled C source code where running a reachableBy operation and getting random exceptions. Sometimes there are no warnings and everything works fine, sometimes I got different exceptions, like these:
[WARN ] SolveTask failed with exception
java.util.concurrent.ExecutionException: java.util.NoSuchElementException: java.util.NoSuchElementException
at java.util.concurrent.ForkJoinTask.reportExecutionException(ForkJoinTask.java:605) ~[?:?]
at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:981) ~[?:?]
at io.joern.dataflowengineoss.queryengine.Engine.runUntilAllTasksAreSolved$1$$anonfun$1(Engine.scala:99) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
[WARN ] SolveTask failed with exception
java.util.concurrent.ExecutionException: overflowdb.SchemaViolationException: IN edge with label AST to an adjacent METHOD is mandatory, but not defined for this METHOD_PARAMETER_IN node with id=75199
at java.util.concurrent.ForkJoinTask.reportExecutionException(ForkJoinTask.java:605) ~[?:?]
at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:981) ~[?:?]
at io.joern.dataflowengineoss.queryengine.Engine.runUntilAllTasksAreSolved$1$$anonfun$1(Engine.scala:99) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
I am running it from a script, but when trying to manually reproduce it in joern console, this never happens and everything works well.
Sometimes I also get other errors:
[ERROR] Unable to complete 'SourceToStartingPoints' task
java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException
at java.util.concurrent.ForkJoinTask.reportExecutionException(ForkJoinTask.java:605) ~[?:?]
at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:981) ~[?:?]
at io.joern.dataflowengineoss.queryengine.SourceTravsToStartingPointsTask.compute$$anonfun$1$$anonfun$1(SourcesToStartingPoints.scala:49) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
at scala.util.Try$.apply(Try.scala:210) ~[org.scala-lang.scala-library-2.13.10.jar:?]
at io.joern.dataflowengineoss.queryengine.SourceTravsToStartingPointsTask.compute$$anonfun$1(SourcesToStartingPoints.scala:49) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
at scala.collection.immutable.List.flatMap(List.scala:293) ~[org.scala-lang.scala-library-2.13.10.jar:?]
at io.joern.dataflowengineoss.queryengine.SourceTravsToStartingPointsTask.compute(SourcesToStartingPoints.scala:53) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
at io.joern.dataflowengineoss.queryengine.SourceTravsToStartingPointsTask.compute(SourcesToStartingPoints.scala:40) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:100) ~[?:?]
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[?:?]
at java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:436) ~[?:?]
at java.util.concurrent.ForkJoinTask.joinForPoolInvoke(ForkJoinTask.java:1040) ~[?:?]
at java.util.concurrent.ForkJoinPool.invoke(ForkJoinPool.java:2639) ~[?:?]
at io.joern.dataflowengineoss.queryengine.SourcesToStartingPoints$.sourceTravsToStartingPoints(SourcesToStartingPoints.scala:24) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
at io.joern.dataflowengineoss.language.ExtendedCfgNode$.reachableBy$extension(ExtendedCfgNode.scala:34) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
at io.joern.dataflowengineoss.language.nodemethods.ExtendedCfgNodeMethods$.reachableBy$extension(ExtendedCfgNodeMethods.scala:22) ~[io.joern.dataflowengineoss-2.0.172.jar:2.0.172]
Tried to increase -Xms -Xmx parameters, but does not seems to solve it as I still see errors with relative high numbers like 20G and still working cases with 2G cases as well.
Versions:
val cpgVersion = "1.6.10"
val joernVersion = "2.0.327"
Java:
openjdk 19.0.2 2023-01-17
OpenJDK Runtime Environment (build 19.0.2+7-Ubuntu-0ubuntu322.04)
OpenJDK 64-Bit Server VM (build 19.0.2+7-Ubuntu-0ubuntu322.04, mixed mode, sharing)
Any idea, what could cause this random behavior?
This looks like another concurrency related bug similar to: https://github.com/joernio/joern/issues/4568. I am not sure whats going on there but we had quite some rework releated to concurrency in the recent past. Maybe @DavidBakerEffendi, @johannescoetzee or @bbrehm can help.
The latest concurrency optimization on SourcesToStartingPoints was done here https://github.com/joernio/joern/pull/4429
What is funny is that the Joern version used in the above issue is the version release just before that optimisation was done. So v2.0.328 could possibly work differently.
Tried it on the latest nighly docker image (sha256:8533dfaf2755844f1a5b11862a3fb01d45039f1c19cf8f69895e6ebd2d4b75c9) with same results.
Interestingly it only has joern version 2.0.357 despite 2.0.383 is already available, but maybe it is a different docker build layer caching bug.
Tried to collect more information, maybe it helps:
I built the CPG file using the following command line: joern-parse --language c -o /tmp/new.cpg . --log-problems --no-image-locations
Run the following script, it is stripped down for reproduction:
import io.shiftleft.codepropertygraph.generated.nodes.{
AstNode,
Call,
Expression,
Identifier,
Literal,
Method
}
@main def main(
cpgFile: String = null
): Unit = {
val cpg = importCpg(cpgFile).get
var sink = cpg.call
.nameExact("strcpy", "strcat", "stpcpy", "wcscpy", "wcscat", "wcpcpy")
val source_id = 2
val dest_id = 1
for (obj: Call <- sink) {
// if (obj.location.filename == "00267412.c") {
if (obj.location.filename != "00267412.c") {
// if (obj.location.filename == "00227324.c") {
println(s"${obj.code} -> ${obj.location.filename}:${obj.lineNumber}")
println(s"obj=$obj")
val arguments: List[Expression] = obj.argument.toList
println(s"arguments: $arguments")
val source = arguments(source_id - 1)
val destination = arguments(dest_id - 1)
var source_size_is_checked = false
var allocation_size_is_source_dependent = false
println(s"source: '$source' ${source.code}")
val strlen = obj.method.call.nameExact("strlen", "strnlen").argument(1).l
for (s <- strlen) {
println(s"strlen: ${s.code} ${s.lineNumber} ${s}")
}
if (!strlen.isEmpty) {
println(s"source.code=${source.code}")
val reachable_by_strlen = source.reachableBy(strlen.iterator).l
if (reachable_by_strlen.isEmpty) {
println("No reachable strlen")
} else {
print(reachable_by_strlen)
}
} else {
println("No strlen")
}
println("\n")
}
}
}
With the following command line: joern --script repo.sc --param cpgFile=new.cpg
Attached the source code as well repo.zip
To exclude multithreading issues (as we have seen on other recent bugreports) could you run it with -J-XX:ActiveProcessorCount=1?
Could you also try it with the latest version on your machine without docker?
Tried it with the latest version installed on my ubuntu 22.04.04 (not in doker): Version: 2.0.391 openjdk 19.0.2 2023-01-17 OpenJDK Runtime Environment (build 19.0.2+7-Ubuntu-0ubuntu322.04) OpenJDK 64-Bit Server VM (build 19.0.2+7-Ubuntu-0ubuntu322.04, mixed mode, sharing)
I still get the errors.
Also tried with the multithreading excluded: joern --script repo.sc --param cpgFile=cpg J-XX:ActiveProcessorCount=1 and same errors appeared:
[WARN ] SolveTask failed with exception:
java.util.concurrent.ExecutionException: overflowdb.SchemaViolationException: IN edge with label AST to an adjacent METHOD is mandatory, but not defined for this METHOD_PARAMETER_OUT node with id=111826
at java.util.concurrent.ForkJoinTask.reportExecutionException(ForkJoinTask.java:581) ~[?:?]
at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:993) ~[?:?]
at io.joern.dataflowengineoss.queryengine.Engine.runUntilAllTasksAreSolved$1$$anonfun$1(Engine.scala:99) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at scala.util.Try$.apply(Try.scala:210) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.joern.dataflowengineoss.queryengine.Engine.runUntilAllTasksAreSolved$1(Engine.scala:100) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.Engine.solveTasks(Engine.scala:114) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.Engine.backwards(Engine.scala:53) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.language.ExtendedCfgNode$.io$joern$dataflowengineoss$language$ExtendedCfgNode$$$reachableByInternal$extension(ExtendedCfgNode.scala:81) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.language.ExtendedCfgNode$.reachableBy$extension(ExtendedCfgNode.scala:36) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.language.nodemethods.ExtendedCfgNodeMethods$.reachableBy$extension(ExtendedCfgNodeMethods.scala:22) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at ScalaReplPP$.main$$anonfun$1(scala-repl-pp-script-with-predef15288036767704769727.sc:291) ~[?:?]
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15) ~[org.scala-lang.scala3-library_3-3.4.2.jar:3.4.2]
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10) ~[org.scala-lang.scala3-library_3-3.4.2.jar:3.4.2]
at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.AbstractIterator.foreach(Iterator.scala:1300) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at ScalaReplPP$.main(scala-repl-pp-script-with-predef15288036767704769727.sc:305) ~[?:?]
at ScalaReplPP$.$anonfun$2(scala-repl-pp-script-with-predef15288036767704769727.sc:310) ~[?:?]
at replpp.shaded.mainargs.Invoker$.$anonfun$2(Invoker.scala:68) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Result.flatMap(Result.scala:13) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Result.flatMap$(Result.scala:7) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Result$Success.flatMap(Result.scala:23) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Invoker$.invoke0(Invoker.scala:68) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Invoker$.invoke(Invoker.scala:77) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Invoker$.invokeLocal$1(Invoker.scala:89) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Invoker$.groupArgs$1$$anonfun$2(Invoker.scala:103) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Result.flatMap(Result.scala:13) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Result.flatMap$(Result.scala:7) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Result$Success.flatMap(Result.scala:23) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Invoker$.groupArgs$1(Invoker.scala:103) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.Invoker$.runMains(Invoker.scala:108) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.ParserForMethods.runRaw0(Parser.scala:170) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.ParserForMethods.runEither(Parser.scala:108) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.ParserForMethods.runEither(Parser.scala:151) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at replpp.shaded.mainargs.ParserForMethods.runOrExit(Parser.scala:56) ~[com.michaelpollmeier.scala-repl-pp-shaded-libs_3-0.1.87.jar:0.1.87]
at ScalaReplPP$.main(scala-repl-pp-script-with-predef15288036767704769727.sc:310) ~[?:?]
at ScalaReplPP.main(scala-repl-pp-script-with-predef15288036767704769727.sc) ~[?:?]
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:578) ~[?:?]
at replpp.scripting.ScriptingDriver.compileAndRun$$anonfun$1(ScriptingDriver.scala:55) ~[com.michaelpollmeier.scala-repl-pp_3-0.1.87.jar:0.1.87]
at scala.Option.flatMap(Option.scala:283) [org.scala-lang.scala-library-2.13.12.jar:?]
at replpp.scripting.ScriptingDriver.compileAndRun(ScriptingDriver.scala:61) [com.michaelpollmeier.scala-repl-pp_3-0.1.87.jar:0.1.87]
at replpp.scripting.NonForkingScriptRunner$.exec(NonForkingScriptRunner.scala:58) [com.michaelpollmeier.scala-repl-pp_3-0.1.87.jar:0.1.87]
at replpp.scripting.NonForkingScriptRunner$.main(NonForkingScriptRunner.scala:23) [com.michaelpollmeier.scala-repl-pp_3-0.1.87.jar:0.1.87]
at replpp.scripting.NonForkingScriptRunner.main(NonForkingScriptRunner.scala) [com.michaelpollmeier.scala-repl-pp_3-0.1.87.jar:0.1.87]
Caused by: overflowdb.SchemaViolationException: IN edge with label AST to an adjacent METHOD is mandatory, but not defined for this METHOD_PARAMETER_OUT node with id=111826
at io.shiftleft.codepropertygraph.generated.nodes.MethodParameterOutDb.method(MethodParameterOut.scala:367) ~[io.shiftleft.codepropertygraph-domain-classes_3-1.6.13.jar:1.6.13]
at io.shiftleft.codepropertygraph.generated.nodes.MethodParameterOut.method(MethodParameterOut.scala:172) ~[io.shiftleft.codepropertygraph-domain-classes_3-1.6.13.jar:1.6.13]
at io.joern.dataflowengineoss.queryengine.TaskCreator.$anonfun$5$$anonfun$1$$anonfun$1(TaskCreator.scala:152) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at scala.collection.immutable.List.filterNot(List.scala:515) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.joern.dataflowengineoss.queryengine.TaskCreator.$anonfun$5$$anonfun$1(TaskCreator.scala:152) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at scala.collection.immutable.List.flatMap(List.scala:293) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.joern.dataflowengineoss.queryengine.TaskCreator.$anonfun$5(TaskCreator.scala:159) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at scala.collection.StrictOptimizedIterableOps.flatMap(StrictOptimizedIterableOps.scala:118) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.StrictOptimizedIterableOps.flatMap$(StrictOptimizedIterableOps.scala:105) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.immutable.Vector.flatMap(Vector.scala:115) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.joern.dataflowengineoss.queryengine.TaskCreator.tasksForUnresolvedOutArgs(TaskCreator.scala:160) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.TaskCreator.createFromResults(TaskCreator.scala:27) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.TaskSolver.call(TaskSolver.scala:43) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.TaskSolver.call(TaskSolver.scala:30) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1456) ~[?:?]
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387) ~[?:?]
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:667) ~[?:?]
at java.util.concurrent.ForkJoinTask$AdaptedCallable.run(ForkJoinTask.java:1464) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577) ~[?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423) ~[?:?]
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387) ~[?:?]
at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1311) ~[?:?]
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1841) ~[?:?]
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806) ~[?:?]
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177) ~[?:?]
Caused by: java.util.NoSuchElementException: next on empty iterator
at scala.collection.Iterator$$anon$19.next(Iterator.scala:973) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.Iterator$$anon$19.next(Iterator.scala:971) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.Iterator$$anon$6.next(Iterator.scala:492) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.shiftleft.codepropertygraph.generated.nodes.MethodParameterOutDb.method(MethodParameterOut.scala:362) ~[io.shiftleft.codepropertygraph-domain-classes_3-1.6.13.jar:1.6.13]
at io.shiftleft.codepropertygraph.generated.nodes.MethodParameterOut.method(MethodParameterOut.scala:172) ~[io.shiftleft.codepropertygraph-domain-classes_3-1.6.13.jar:1.6.13]
at io.joern.dataflowengineoss.queryengine.TaskCreator.$anonfun$5$$anonfun$1$$anonfun$1(TaskCreator.scala:152) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at scala.collection.immutable.List.filterNot(List.scala:515) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.joern.dataflowengineoss.queryengine.TaskCreator.$anonfun$5$$anonfun$1(TaskCreator.scala:152) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at scala.collection.immutable.List.flatMap(List.scala:293) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.joern.dataflowengineoss.queryengine.TaskCreator.$anonfun$5(TaskCreator.scala:159) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at scala.collection.StrictOptimizedIterableOps.flatMap(StrictOptimizedIterableOps.scala:118) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.StrictOptimizedIterableOps.flatMap$(StrictOptimizedIterableOps.scala:105) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at scala.collection.immutable.Vector.flatMap(Vector.scala:115) ~[org.scala-lang.scala-library-2.13.12.jar:?]
at io.joern.dataflowengineoss.queryengine.TaskCreator.tasksForUnresolvedOutArgs(TaskCreator.scala:160) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.TaskCreator.createFromResults(TaskCreator.scala:27) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.TaskSolver.call(TaskSolver.scala:43) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at io.joern.dataflowengineoss.queryengine.TaskSolver.call(TaskSolver.scala:30) ~[io.joern.dataflowengineoss-2.0.391.jar:2.0.391]
at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1456) ~[?:?]
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387) ~[?:?]
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:667) ~[?:?]
at java.util.concurrent.ForkJoinTask$AdaptedCallable.run(ForkJoinTask.java:1464) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577) ~[?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423) ~[?:?]
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387) ~[?:?]
at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1311) ~[?:?]
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1841) ~[?:?]
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806) ~[?:?]
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177) ~[?:?]