Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

segfault when mounting plugins #3881

Closed
markus2330 opened this issue Jun 7, 2021 · 17 comments
Closed

segfault when mounting plugins #3881

markus2330 opened this issue Jun 7, 2021 · 17 comments
Assignees

Comments

@markus2330
Copy link
Contributor

markus2330 commented Jun 7, 2021

Steps to Reproduce the Problem

I tried to do what is described in the README.md of the JNI plugin, e.g.:

kdb mount -c classname=org/libelektra/plugin/Echo,classpath=.:/usr/share/java/jna.jar:/usr/share/java/libelektra.jar config.jni /tests/jni jni

Expected Result

That I can mount JNI plugins and use them.

Actual Result

Segfaults without usable backtrace.

System Information

  • Elektra Version: master
  • Debian Buster
@markus2330 markus2330 mentioned this issue Jun 7, 2021
20 tasks
@markus2330
Copy link
Contributor Author

@tucek How were you able to mount plugins? Did the commands in the README.md work for you?

@markus2330 markus2330 mentioned this issue Jun 7, 2021
14 tasks
@kodebach
Copy link
Member

kodebach commented Jun 7, 2021

I get this too. According to the backtrace from gdb it happens in the call1Arg call of elektraJniClose. Specifically right at the start here:

jobject jerrorKey = (*data->env)->NewObject (data->env, data->clsKey, data->midKeyConstr, errorKey, true);

I have no idea how this could cause a segfault and the more I have to deal with the jni plugin, the more I think we should just abandon it in favour of a processplugin solution like in Python.

@tucek
Copy link
Contributor

tucek commented Jun 7, 2021

@tucek How were you able to mount plugins? Did the commands in the README.md work for you?

Unfortunately I haven't been able yet. Updating the JNI tutorial, which includes mounting the JNI plugins has been moved to #3876.

@markus2330
Copy link
Contributor Author

Ok, then we should write in the release notes that it is currently not possible to actually mount plugins written in Java, pointing to this issue. (@mpranj, can you add this please?)

Unfortunately I haven't been able yet.

This would have been an important information when I asked about testing JNI 14 days ago. (#3825 (review))

According to the backtrace from gdb

Can you post the backtrace here please?

I think we should just abandon it in favour of a processplugin solution like in Python.

We don't know what the cause is yet but yes, it could be that the segfaults stem from several initialization of the jni plugin (and as such also the JVM) during mounting.

@tucek
Copy link
Contributor

tucek commented Jun 7, 2021

Ok, then we should write in the release notes that it is currently not possible to actually mount plugins written in Java, pointing to this issue. (@mpranj, can you add this please?)

Unfortunately I haven't been able yet.

This would have been an important information when I asked about testing JNI 14 days ago. (#3825 (review))

@markus2330
I'm sorry for the misunderstanding. My focus was on getting JNI plugin to work (as tested via the test). To that end, i had to build more knowledge about the workings of Elektra and the JNA bindings, improving them on the way. I thought it was clear, that i am not yet completed the process of fully testing and updating the documentation for mounting and using JNA plugins via DB. (#3863 (comment))

@markus2330
Copy link
Contributor Author

markus2330 commented Jun 7, 2021

The unit tests and plugin-check work now, which is already a big step. But we need to clearly communicate limitations via docu&release notes. People expect that everything works in the README.md as described. I already started fixing the README.md in #3882. Help appreciated.

@kodebach
Copy link
Member

kodebach commented Jun 7, 2021

Can you post the backtrace here please?

I look at it again, and it seems I had an error in my command line. The open call of jni failed with an error about the classpath and then the close call within open segfaulted.

Here is the backtrace:

#0  0x00007ffff734963b in call1Arg (data=0x555555773900, errorKey=0x5555557782a0, method=0x7ffff734a455 "close") at /home/klemens/coding/bsc/libelektra/src/plugins/jni/jni.c:79
#1  0x00007ffff73495ae in elektraJniClose (handle=0x555555773c00, errorKey=0x5555557782a0) at /home/klemens/coding/bsc/libelektra/src/plugins/jni/jni.c:338
#2  0x00007ffff7e9b53d in elektraPluginClose (handle=0x555555773c00, errorKey=0x5555557782a0) at /home/klemens/coding/bsc/libelektra/src/libs/elektra/plugin.c:330
#3  0x00007ffff7e9b42e in elektraPluginOpen (name=0x7fffffffc7b8 "jni", modules=0x555555778960, config=0x0, errorKey=0x5555557782a0) at /home/klemens/coding/bsc/libelektra/src/libs/elektra/plugin.c:303
#4  0x00007ffff7f5fef0 in kdb::tools::Plugin::Plugin (this=0x55555575a050, spec_=..., modules=...) at /home/klemens/coding/bsc/libelektra/src/libs/tools/src/plugin.cpp:39
#5  0x00007ffff7f5f9c9 in kdb::tools::Modules::load (this=0x55555576c8f0, spec=...) at /home/klemens/coding/bsc/libelektra/src/libs/tools/src/modules.cpp:49
#6  0x00007ffff7f5f8c8 in kdb::tools::Modules::load (this=0x55555576c8f0, pluginName="jni", config=...) at /home/klemens/coding/bsc/libelektra/src/libs/tools/src/modules.cpp:44
#7  0x00007ffff7f6fe57 in kdb::tools::ModulesPluginDatabase::getSymbol (this=0x555555779c90, spec=..., which="checkconf") at /home/klemens/coding/bsc/libelektra/src/libs/tools/src/plugindatabase.cpp:242
#8  0x00007ffff7f44bad in kdb::tools::BackendBuilder::addPlugin (this=0x7fffffffd1e0, plugin=...) at /home/klemens/coding/bsc/libelektra/src/libs/tools/src/backendbuilder.cpp:449
#9  0x0000555555676366 in kdb::tools::MountBackendBuilder::addPlugin (this=0x7fffffffd1d0, spec=...) at /home/klemens/coding/bsc/libelektra/src/libs/tools/include/backendbuilder.hpp:190
#10 0x000055555562f5ee in kdb::tools::BackendBuilder::addPlugins (this=0x7fffffffd1e0, plugins=std::vector of length 1, capacity 1 = {...}) at /home/klemens/coding/bsc/libelektra/src/libs/tools/include/backendbuilder.hpp:140
#11 0x00005555556751fb in MountCommand::buildBackend (this=0x55555574b3c0, cl=...) at /home/klemens/coding/bsc/libelektra/src/tools/kdb/mount.cpp:169
#12 0x0000555555676067 in MountCommand::execute (this=0x55555574b3c0, cl=...) at /home/klemens/coding/bsc/libelektra/src/tools/kdb/mount.cpp:286
#13 0x0000555555666925 in main (argc=7, argv=0x7fffffffdd88) at /home/klemens/coding/bsc/libelektra/src/tools/kdb/main.cpp:202

If I use this command line instead:

kdb mount config.jni /testsjni jni classname=org/libelektra/plugin/Echo classpath=$PWD/share/java/libelektra.jar

($PWD since, I used a local install; replace $PWD with /usr or /usr/local if installed system-wide)

I get a different segfault (not immediately, the process runs for about 1 sec before the segfault). But the backtrace for this segfault is somewhere within libjvm.so and only contains ??(). At least according to gdb there is also only one thread, so in this case there really is zero information.

The only other noteworthy detail is that constructing plugin is printed, so the Echo() constructor has been executed. But I don't see open plugin, so the segfault happens somewhere in this region:

data->plugin = (*data->env)->NewObject (data->env, data->clsPlugin, midPluginConstructor);
checkException (data, "creating plugin", errorKey);
if (data->plugin == 0)
{
ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (errorKey, "Cannot create Java plugin %s", classname);
return -1;
}
return call2Arg (data, config, errorKey, "open");

People expect that everything works in the README.md as described.

This is true in general, but the JNI plugin seems so broken I honestly doubt anybody is actually using it.

@markus2330
Copy link
Contributor Author

This is true in general, but the JNI plugin seems so broken I honestly doubt anybody is actually using it.

The JNI plugin currently has "discouraged" but my idea was to improve the status quo and to get it to a working status again. Seems like the expectations were not communicated clearly.

@mpranj
Copy link
Member

mpranj commented Jun 7, 2021

Is something like this fine for the release notes:


Note that it is currently not possible to mount plugins written in Java (see #3881).

@tucek
Copy link
Contributor

tucek commented Jun 7, 2021

It might have to do something with the JNA dependencies. For testing the jni plugin, we are using a fat jar including all required dependencies (like JNA).

while kdb mount config.jni /testsjni jni classname=org/libelektra/plugin/Echo classpath=${ELEKTRA_BUILD_DIR}/src/bindings/jna/libelektra/build/libs/libelektra-0.9.6.jar yields:

construct plugin

Sorry, I crashed by the signal SIGSEGV
This should not have happened!

Please report the issue at https://issues.libelektra.org/
Aborted

using the fat jar including all dependencies (which is currently not installed, but build only for us in the testmod_jni) kdb mount config.jni /testsjni jni classname=org/libelektra/plugin/Echo classpath=${ELEKTRA_BUILD_DIR}/src/bindings/jna/libelektra/build/libs/libelektra-0.9.6-all.jar yields:

construct plugin
kdb: symbol lookup error: /home/tucek/.cache/JNA/temp/jna3742494249016765927.tmp: undefined symbol: pthread_once

@kodebach do you have any clue about the undefined symbol: pthread_once error?

@markus2330
Copy link
Contributor Author

Note that it is currently not possible to mount plugins written in Java (see #3881).

Yes, it is fine! I can also adapt the release notes later (when forwarded to CM students). I'll do it in #3882 after the release.

@markus2330
Copy link
Contributor Author

undefined symbol: pthread_once

Probably JNI needs to be linked with ${CMAKE_THREAD_LIBS_INIT}. You can try only linking the jni plugin but this might not be enough (usually executables need to be linked with it).

tucek pushed a commit to tucek/libelektra that referenced this issue Jun 7, 2021
@tucek
Copy link
Contributor

tucek commented Jun 7, 2021

undefined symbol: pthread_once

Probably JNI needs to be linked with ${CMAKE_THREAD_LIBS_INIT}. You can try only linking the jni plugin but this might not be enough (usually executables need to be linked with it).

please have a quick look at the changes in #3884 - did I fail to link JNI with ${CMAKE_THREAD_LIBS_INIT} or is it just not solving the problem?

@markus2330
Copy link
Contributor Author

usually executables need to be linked with it

So something similar (target_link_libraries ${CMAKE_THREAD_LIBS_INIT}) also needs to be done in src/tools/kdb/CMakeLists.txt

tucek pushed a commit to tucek/libelektra that referenced this issue Jun 7, 2021
- if jni plugin is included, kdb is built with ${CMAKE_THREAD_LIBS_INIT} (for shared builds)
- libelektra-${KDB_VERSION}-all.jar fat jar is now installed when jna bindings are included
@tucek
Copy link
Contributor

tucek commented Jun 7, 2021

please see changes in #3884

tucek pushed a commit to tucek/libelektra that referenced this issue Jun 7, 2021
tucek pushed a commit to tucek/libelektra that referenced this issue Jun 7, 2021
tucek pushed a commit to tucek/libelektra that referenced this issue Jun 7, 2021
- if jni plugin is included, kdb is built with ${CMAKE_THREAD_LIBS_INIT} (for shared builds)
- libelektra-${KDB_VERSION}-all.jar fat jar is now installed when jna bindings are included
tucek pushed a commit to tucek/libelektra that referenced this issue Jun 7, 2021
tucek pushed a commit to tucek/libelektra that referenced this issue Jun 9, 2021
tucek pushed a commit to tucek/libelektra that referenced this issue Jun 9, 2021
- if jni plugin is included, kdb is built with ${CMAKE_THREAD_LIBS_INIT} (for shared builds)
- libelektra-${KDB_VERSION}-all.jar fat jar is now installed when jna bindings are included
tucek pushed a commit to tucek/libelektra that referenced this issue Jun 9, 2021
@tucek tucek added this to Stage in Java bindings overhaul via automation Jul 5, 2021
@tucek tucek moved this from Stage to Blocked because of JNI integration in Java bindings overhaul Jul 6, 2021
tucek pushed a commit to tucek/libelektra that referenced this issue Aug 12, 2021
tucek pushed a commit to tucek/libelektra that referenced this issue Aug 12, 2021
- if jni plugin is included, kdb is built with ${CMAKE_THREAD_LIBS_INIT} (for shared builds)
- libelektra-${KDB_VERSION}-all.jar fat jar is now installed when jna bindings are included
tucek pushed a commit to tucek/libelektra that referenced this issue Aug 12, 2021
@tucek
Copy link
Contributor

tucek commented May 11, 2022

Is this still an issue? I think this issue can be closed due to mounting java plugins via the process plugin.

@markus2330
Copy link
Contributor Author

Thank you, yes this is fixed now! 🎆

Java bindings overhaul automation moved this from blocked / waiting on to Done May 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants