graal icon indicating copy to clipboard operation
graal copied to clipboard

[LLVM] Sqlite3 library issues

Open roxanan-adyen opened this issue 3 years ago • 2 comments

Describe GraalVM and your environment :

  • GraalVM version: 22.1.0
  • EE
  • JDK version: JDK11
  • OS and OS Version: macOS Monterey
  • Architecture: amd64
  • The output of java -Xinternalversion:
 Java HotSpot(TM) 64-Bit Server VM (11.0.15+8-LTS-jvmci-22.1-b05) for bsd-amd64 JRE (11.0.15+8-LTS-jvmci-22.1-b05), built on Apr  4 2022 04:05:20 by "graal1" with gcc 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.17)

Have you verified this issue still happens when using the latest snapshot? Yes, I tried only the latest version

Describe the issue I have a small C/C++ program with some exposed functions that will perform some read operations on a sqlite3 database and a java app that will call that. I run into multiple issue, for all of them we have fixes. Please check this repo where I build the example. Here is the description. You can also find the description in the readme file.

Purpose

This is a very small setup where I reproduced some issue when using sqlite3 library with Graalvm.

Directory overview

  1. test.db --> sqlite database
  2. Test.java --> java app that will load a C/C++ lib test.so and will then call a function from the library, function that is received as command argument
  3. sqlite3 dir --> sqlite3 external library compile settings.
  4. test dir --> where the C/C++ library sources are. The library is linked to sqlite lib and will perform some database calls using the external lib.
  5. Cmakelists and graalvm.cmake --> build stuff

Build commands

Create a folder inside the root

mkdir build

cmake -DCMAKE_TOOLCHAIN_FILE=../graalvm.cmake -DPATCH_FILE=<no-follow.path/strlen.patch/allocator.patch> ../

We have 3 patches for sqlite, first one is to disable NO_FOLLOW flag which is not supported yet by GraalVm. strlen.patch and allocator.patch are our fixes for two issues I'll describe later

make cpp --> it will create test.so lib

make java --> it will compile java app

Run command

make <function> --> it will run the java app where we load the c/c++ lib and then call from c/c++ side. where function = {crash_create_random_statement/crash_5_consecutive_queries/crash_cache_entire_db}

Run scenatios

I recomend creating separate build directory for each patch

  1. make crash_create_random_statement

This will crash if you apply no-follow.patch or strlen.patch and it is solved with allocator.patch.

Reminder: this is the command to run to apply the proper patch before building:

cmake -DCMAKE_TOOLCHAIN_FILE=../graalvm.cmake -DPATCH_FILE=<no-follow.path/strlen.patch/allocator.patch> ../

1.1 Output when no-follow.patch is applied

[100%] Run java app
Opened db
Exception in thread "main" org.graalvm.polyglot.PolyglotException: java.lang.UnsupportedOperationException: A destroyed pointer is accessed: 8, 45224, com.oracle.truffle.llvm.a.a.j@11c6b739
	at com.oracle.truffle.llvm.a.a.c$b.a(stripped:708)
	at com.oracle.truffle.llvm.a.a.d$a.b(stripped:238)
	at com.oracle.truffle.llvm.a.a.d$a.a(stripped:213)
	at com.oracle.truffle.llvm.a.a.c$h.c(stripped:175)
	at com.oracle.truffle.llvm.a.a.e$d$a.p(stripped:413)
	at com.oracle.truffle.llvm.a.a.e$d$a.readGenericI64(stripped:393)
	at com.oracle.truffle.llvm.runtime.library.internal.LLVMManagedReadLibrary.readI64(LLVMManagedReadLibrary.java:84)
	at com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMI64LoadNode.doI64Managed(LLVMI64LoadNode.java:121)
	at com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMI64LoadNodeGen.executeAndSpecialize(LLVMI64LoadNodeGen.java:450)
	at com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMI64LoadNodeGen.executeI64(LLVMI64LoadNodeGen.java:368)
	at com.oracle.truffle.llvm.runtime.nodes.vars.LLVMWriteNodeFactory$LLVMWriteI64NodeGen.execute_long0(LLVMWriteNodeFactory.java:477)
	at com.oracle.truffle.llvm.runtime.nodes.vars.LLVMWriteNodeFactory$LLVMWriteI64NodeGen.execute(LLVMWriteNodeFactory.java:466)
	at com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode$InitializedBlockNode.execute(LLVMBasicBlockNode.java:172)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMLoopDispatchNode.executeRepeatingWithValue(LLVMLoopDispatchNode.java:102)
	at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedOSRLoopNode.profilingLoop(OptimizedOSRLoopNode.java:159)
	at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedOSRLoopNode.execute(OptimizedOSRLoopNode.java:110)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMLoopNode$LLVMLoopNodeImpl.loop(LLVMLoopNode.java:80)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMLoopNodeFactory$LLVMLoopNodeImplNodeGen.executeLoop(LLVMLoopNodeFactory.java:26)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.dispatchFromBasicBlock(LLVMDispatchBasicBlockNode.java:168)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.doDispatch(LLVMDispatchBasicBlockNode.java:84)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNodeGen.executeGeneric(LLVMDispatchBasicBlockNodeGen.java:23)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNode.doRun(LLVMFunctionRootNode.java:81)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNodeGen.executeGeneric(LLVMFunctionRootNodeGen.java:25)
	at com.oracle.truffle.llvm.runtime.nodes.func.LLVMFunctionStartNode.execute(LLVMFunctionStartNode.java:93)
	at <llvm> sqlite3VdbeMemSetStr(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:78098:2927780)
	at <llvm> sqlite3VdbeSetColName(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:81526:3037211)
	at <llvm> sqlite3GenerateColumnNames(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:134070:4859483)
	at <llvm> sqlite3Select(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:138379:5016107)
	at <llvm> yy_reduce(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:161826:5915832)
	at <llvm> sqlite3Parser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:163194:5975573)
	at <llvm> sqlite3RunParser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:164490:6022355)
	at <llvm> sqlite3Prepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131777:4776292)
	at <llvm> sqlite3LockAndPrepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131852:4778375)
	at <llvm> sqlite3_prepare_v2(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131937:4781394)
	at <llvm> sqlite3_exec(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:126176:4576045)
	at <llvm> sqlite3InitOne(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131416:4763716)
	at <llvm> sqlite3Init(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131491:4766128)
	at <llvm> sqlite3ReadSchema(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131517:4766909)
	at <llvm> sqlite3LocateTable(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:112853:4101375)
	at <llvm> sqlite3LocateTableItem(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:112916:4103228)
	at <llvm> selectExpander(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:137525:4985633)
	at <llvm> sqlite3WalkSelect(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:99157:3626355)
	at <llvm> sqlite3SelectExpand(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:137794:4995483)
	at <llvm> sqlite3SelectPrep(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:137879:4998234)
	at <llvm> sqlite3Select(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:138348:5015052)
	at <llvm> yy_reduce(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:161826:5915832)
	at <llvm> sqlite3Parser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:163194:5975573)
	at <llvm> sqlite3RunParser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:164490:6022355)
	at <llvm> sqlite3Prepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131770:4776093)
	at <llvm> sqlite3LockAndPrepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131852:4778375)
	at <llvm> sqlite3_prepare_v2(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131937:4781394)
	at <llvm> create_statement(../test/main.cpp:32:1003)
	at <llvm> crash_create_random_statement(../test/main.cpp:61:1732)
	at org.graalvm.sdk/org.graalvm.polyglot.Value.invokeMember(Value.java:932)
	at Test.main(Test.java:11)

1.2 Output when strlen.patch is applied

[100%] Run java app
Opened db
Exception in thread "main" org.graalvm.polyglot.PolyglotException: java.lang.UnsupportedOperationException: A destroyed pointer is accessed: 1, 47275, com.oracle.truffle.llvm.a.a.j@16631f69
	at com.oracle.truffle.llvm.a.a.c$b.a(stripped:708)
	at com.oracle.truffle.llvm.a.a.d$a.b(stripped:238)
	at com.oracle.truffle.llvm.a.a.d$a.a(stripped:213)
	at com.oracle.truffle.llvm.a.a.c$k.f(stripped:127)
	at com.oracle.truffle.llvm.a.a.e$d$a.m(stripped:253)
	at com.oracle.truffle.llvm.a.a.e$d$a.readI8(stripped:233)
	at com.oracle.truffle.llvm.runtime.library.internal.LLVMManagedReadLibraryGen$CachedDispatch.readI8(LLVMManagedReadLibraryGen.java:711)
	at com.oracle.truffle.llvm.a.a.c$e.a(stripped:876)
	at com.oracle.truffle.llvm.a.a.d$c.b(stripped:373)
	at com.oracle.truffle.llvm.a.a.d$c.a(stripped:349)
	at com.oracle.truffle.llvm.a.a.c$d.a(stripped:915)
	at com.oracle.truffle.llvm.a.a.e$c$a.a(stripped:1317)
	at com.oracle.truffle.llvm.a.a.e$c$a.a(stripped:1287)
	at com.oracle.truffle.llvm.a.a.fGen$a.a(stripped:853)
	at com.oracle.truffle.llvm.managed.nodes.memory.e.a(stripped:38)
	at com.oracle.truffle.llvm.managed.nodes.memory.f.a(stripped:97)
	at com.oracle.truffle.llvm.managed.nodes.memory.f.executeWithTarget(stripped:76)
	at com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMMemCopy.doVoid(LLVMMemCopy.java:64)
	at com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMMemCopyNodeGen.executeAndSpecialize(LLVMMemCopyNodeGen.java:158)
	at com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMMemCopyNodeGen.executeGeneric_generic2(LLVMMemCopyNodeGen.java:136)
	at com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMMemCopyNodeGen.executeGeneric(LLVMMemCopyNodeGen.java:48)
	at com.oracle.truffle.llvm.runtime.nodes.api.LLVMVoidStatementNodeGen.execute(LLVMVoidStatementNodeGen.java:22)
	at com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNuller.doExecute(LLVMFrameNuller.java:64)
	at com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNullerNodeGen.execute(LLVMFrameNullerNodeGen.java:20)
	at com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode$InitializedBlockNode.execute(LLVMBasicBlockNode.java:172)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.dispatchFromBasicBlock(LLVMDispatchBasicBlockNode.java:121)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.doDispatch(LLVMDispatchBasicBlockNode.java:84)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNodeGen.executeGeneric(LLVMDispatchBasicBlockNodeGen.java:23)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNode.doRun(LLVMFunctionRootNode.java:81)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNodeGen.executeGeneric(LLVMFunctionRootNodeGen.java:25)
	at com.oracle.truffle.llvm.runtime.nodes.func.LLVMFunctionStartNode.execute(LLVMFunctionStartNode.java:93)
	at <llvm> exprDup(Unknown)
	at <llvm> sqlite3ExprDup(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:102724:3751878)
	at <llvm> sqlite3WhereTabFuncArgs(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:149225:5424495)
	at <llvm> sqlite3WhereBegin(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:154171:5612127)
	at <llvm> sqlite3Select(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:138832:5033065)
	at <llvm> yy_reduce(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:161834:5916018)
	at <llvm> sqlite3Parser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:163202:5975759)
	at <llvm> sqlite3RunParser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:164498:6022541)
	at <llvm> sqlite3Prepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131778:4776279)
	at <llvm> sqlite3LockAndPrepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131860:4778561)
	at <llvm> sqlite3_prepare_v2(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131945:4781580)
	at <llvm> create_statement(../test/main.cpp:32:1003)
	at <llvm> crash_create_random_statement(../test/main.cpp:61:1732)
	at org.graalvm.sdk/org.graalvm.polyglot.Value.invokeMember(Value.java:932)
	at Test.main(Test.java:11)
  1. make crash_5_consecutive_queries

This is will crash when allocator.patch is applied

100%] Run java app
Opened db
SELECT case0 FROM TEST WHERE (KEY='agnauegl')
SELECT case0 FROM TEST WHERE (KEY='raekol.gen')
SELECT case0 FROM TEST WHERE (KEY='anerie.cgorlnfm')
SELECT case0 FROM TEST WHERE (KEY='ctrocnere.regal')
SELECT case0 FROM TEST WHERE (KEY='ac.agelecelrnn')
Exception in thread "main" org.graalvm.polyglot.PolyglotException: java.lang.UnsupportedOperationException: A destroyed pointer is accessed: 4, 46684, com.oracle.truffle.llvm.a.a.j@47433e5d
	at com.oracle.truffle.llvm.a.a.c$b.a(stripped:708)
	at com.oracle.truffle.llvm.a.a.d$a.b(stripped:238)
	at com.oracle.truffle.llvm.a.a.d$a.a(stripped:213)
	at com.oracle.truffle.llvm.a.a.c$j.e(stripped:159)
	at com.oracle.truffle.llvm.a.a.e$d$a.o(stripped:364)
	at com.oracle.truffle.llvm.a.a.e$d$a.readI32(stripped:344)
	at com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMI32LoadNode$LLVMI32OffsetLoadNode.doI32Managed(LLVMI32LoadNode.java:79)
	at com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMI32LoadNodeGen$LLVMI32OffsetLoadNodeGen.executeWithTarget(LLVMI32LoadNodeGen.java:514)
	at com.oracle.truffle.llvm.enterprise.nodes.memory.a$d.d(stripped:124)
	at com.oracle.truffle.llvm.enterprise.nodes.memory.b$d.m(stripped:715)
	at com.oracle.truffle.llvm.enterprise.nodes.memory.b$d.executeI32(stripped:693)
	at com.oracle.truffle.llvm.runtime.nodes.vars.LLVMWriteNodeFactory$LLVMWriteI32NodeGen.execute(LLVMWriteNodeFactory.java:364)
	at com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode$InitializedBlockNode.execute(LLVMBasicBlockNode.java:172)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.dispatchFromBasicBlock(LLVMDispatchBasicBlockNode.java:121)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.doDispatch(LLVMDispatchBasicBlockNode.java:84)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNodeGen.executeGeneric(LLVMDispatchBasicBlockNodeGen.java:23)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNode.doRun(LLVMFunctionRootNode.java:81)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNodeGen.executeGeneric(LLVMFunctionRootNodeGen.java:25)
	at com.oracle.truffle.llvm.runtime.nodes.func.LLVMFunctionStartNode.execute(LLVMFunctionStartNode.java:93)
	at <llvm> exprDup(Unknown)
	at <llvm> sqlite3ExprDup(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:102772:3753733)
	at <llvm> sqlite3ExprCodeRunJustOnce(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:105939:3869448)
	at <llvm> sqlite3ExprCodeTemp(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:105988:3871072)
	at <llvm> sqlite3ExprIfFalse(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:106465:3888078)
	at <llvm> sqlite3WhereCodeOneLoopStart(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:147569:5362395)
	at <llvm> sqlite3WhereBegin(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:154635:5629269)
	at <llvm> sqlite3Select(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:138880:5034920)
	at <llvm> yy_reduce(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:161882:5917873)
	at <llvm> sqlite3Parser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:163250:5977614)
	at <llvm> sqlite3RunParser(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:164546:6024396)
	at <llvm> sqlite3Prepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131826:4778134)
	at <llvm> sqlite3LockAndPrepare(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131908:4780416)
	at <llvm> sqlite3_prepare_v2(sqlite3/sqlite-prefix/src/sqlite/sqlite3.c:131993:4783435)
	at <llvm> create_statement(../test/main.cpp:32:1003)
	at <llvm> crash_5_consecutive_queries(../test/main.cpp:108:3218)
	at org.graalvm.sdk/org.graalvm.polyglot.Value.invokeMember(Value.java:932)
	at Test.main(Test.java:11)
  1. make crash_cache_entire_db

    This is will crash when allocator.patch is applied.

Exception in thread "main" org.graalvm.polyglot.PolyglotException: java.lang.UnsupportedOperationException: A destroyed pointer is accessed: 1, 19, com.oracle.truffle.llvm.a.a.j@6cb6d90
	at com.oracle.truffle.llvm.a.a.c$b.a(stripped:708)
	at com.oracle.truffle.llvm.a.a.d$a.b(stripped:238)
	at com.oracle.truffle.llvm.a.a.d$a.a(stripped:213)
	at com.oracle.truffle.llvm.a.a.c$k.f(stripped:127)
	at com.oracle.truffle.llvm.a.a.e$d$a.m(stripped:253)
	at com.oracle.truffle.llvm.a.a.e$d$a.readI8(stripped:233)
	at com.oracle.truffle.llvm.runtime.library.internal.LLVMManagedReadLibraryGen$CachedDispatch.readI8(LLVMManagedReadLibraryGen.java:711)
	at com.oracle.truffle.llvm.a.a.c$e.a(stripped:876)
	at com.oracle.truffle.llvm.a.a.d$c.b(stripped:373)
	at com.oracle.truffle.llvm.a.a.d$c.a(stripped:349)
	at com.oracle.truffle.llvm.a.a.c$d.a(stripped:915)
	at com.oracle.truffle.llvm.a.a.e$c$a.a(stripped:1317)
	at com.oracle.truffle.llvm.a.a.e$c$a.a(stripped:1287)
	at com.oracle.truffle.llvm.a.a.fGen$a.a(stripped:853)
	at com.oracle.truffle.llvm.managed.nodes.memory.e.a(stripped:38)
	at com.oracle.truffle.llvm.managed.nodes.memory.f.executeWithTarget(stripped:52)
	at com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMMemCopy.doVoid(LLVMMemCopy.java:64)
	at com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMMemCopyNodeGen.executeGeneric_long_boolean1(LLVMMemCopyNodeGen.java:103)
	at com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMMemCopyNodeGen.executeGeneric(LLVMMemCopyNodeGen.java:46)
	at com.oracle.truffle.llvm.runtime.nodes.api.LLVMVoidStatementNodeGen.execute(LLVMVoidStatementNodeGen.java:22)
	at com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode$InitializedBlockNode.execute(LLVMBasicBlockNode.java:172)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.dispatchFromBasicBlock(LLVMDispatchBasicBlockNode.java:121)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.doDispatch(LLVMDispatchBasicBlockNode.java:84)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNodeGen.executeGeneric(LLVMDispatchBasicBlockNodeGen.java:23)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNode.doRun(LLVMFunctionRootNode.java:81)
	at com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNodeGen.executeGeneric(LLVMFunctionRootNodeGen.java:25)
	at com.oracle.truffle.llvm.runtime.nodes.func.LLVMFunctionStartNode.execute(LLVMFunctionStartNode.java:93)
	at <llvm> pair<std::string &, std::string &, false>(../../../graalvm-ee-java11-22.1.0/Contents/Home/languages/llvm/managed/include/c++/v1/utility:447:14828)
	at <llvm> construct<std::pair<const std::string, std::string>, std::string &, std::string &>(../../../graalvm-ee-java11-22.1.0/Contents/Home/languages/llvm/managed/include/c++/v1/memory:911:33336)
	at <llvm> construct<std::pair<const std::string, std::string>, std::string &, std::string &, void>(../../../graalvm-ee-java11-22.1.0/Contents/Home/languages/llvm/managed/include/c++/v1/__memory/allocator_traits.h:288:11996)
	at <llvm> __construct_node_hash<std::string &, std::string &>(../../../graalvm-ee-java11-22.1.0/Contents/Home/languages/llvm/managed/include/c++/v1/__hash_table:2473:89228)
	at <llvm> __emplace_unique_key_args<std::string, std::string &, std::string &>(../../../graalvm-ee-java11-22.1.0/Contents/Home/languages/llvm/managed/include/c++/v1/__hash_table:2093:75727)
	at <llvm> __emplace_unique<std::string &, std::string &>(../../../graalvm-ee-java11-22.1.0/Contents/Home/languages/llvm/managed/include/c++/v1/__hash_table:1089:39597)
	at <llvm> emplace<std::string &, std::string &>(../../../graalvm-ee-java11-22.1.0/Contents/Home/languages/llvm/managed/include/c++/v1/unordered_map:1158:48249)
	at <llvm> crash_cache_entire_db(../test/main.cpp:172:5120)
	at org.graalvm.sdk/org.graalvm.polyglot.Value.invokeMember(Value.java:932)
	at Test.main(Test.java:11)

If you go to main.cpp in test/ and go to crash_cache_entire_db and decomment the FIXME lines, it won't crash. Maybe the GC intervenes here, it's just a theory.

roxanan-adyen avatar May 19 '22 08:05 roxanan-adyen

Hi, thank you for reporting this, we're going to take a look into this and get back to you

oubidar-Abderrahim avatar May 25 '22 14:05 oubidar-Abderrahim

We have a potential fix for this issue.

The problem is that sqlite seems to be using a custom memory allocator, and it looks like this allocator is reusing memory without properly clearing it. This leads to a situation where memory that used to be a pointer is partially overwritten with primitive values. The weird thing is that then later, the 64-bit value that used to be a pointer is actually read in full, despite being only written partially.

In general, this is not a safe thing to do. The read value will contain stale bits from the pointer. Their value is essentially random. This is why the LLVM runtime refuses to do this operation. But of course if the bits are only read but then not actually used, it might be fine.

We have introduced a new flag, --llvm.deadPointerProtection, to specify the behavior of the VM in that situation. The default is still ERROR, which is the old behavior. Other possible values are NONE for completely ignoring that problem, and MASK for replacing the effectively random bits with a fixed bit pattern (0xdeaddeaddeaddead). I tried your reproducer with --llvm.deadPointerProtection=MASK, and it doesn't crash anymore.

This option is included in GraalVM 22.2. It is marked as experimental for now. If this works for you, we might actually flip the default to MASK. I think it should be a safe default in all cases.

Note that either option is ok from a memory safety point of view. It is never possible to actually dereference one of these broken pointers, even with --llvm.deadPointerProtection=NONE.

Patch for your reproducer:

diff --git a/Test.java b/Test.java
index b225270..4d206bd 100644
--- a/Test.java
+++ b/Test.java
@@ -3,7 +3,7 @@ import org.graalvm.polyglot.*;
 
 class Test {
     public static void main(String[] args) throws Exception {
-        Context polyglot = Context.newBuilder().allowAllAccess(true).option("llvm.managed", "true").build();
+        Context polyglot = Context.newBuilder().allowAllAccess(true).option("llvm.managed", "true").option("llvm.deadPointerProtection", "MASK").build();
         File file = new File("libtest.so");
         Source source = Source.newBuilder("llvm", file).build();
         Value cpart = polyglot.eval(source);

rschatz avatar Jul 26 '22 13:07 rschatz