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

[WIP]Fix double dlclose when uninstalling bundle without activator #301

Closed
wants to merge 1 commit into from
Closed

[WIP]Fix double dlclose when uninstalling bundle without activator #301

wants to merge 1 commit into from

Conversation

PengZheng
Copy link
Contributor

I kept playing with the export_import example, and found that the handle to libhello_test2libd.so.3 has been closed twice, but opened only once.

  248 Thread 3 "helloworld_with" hit Breakpoint 2, framework_loadLibrary (framework=0x55555558a1e0, library=0x7ffff62a42a0 "libhello_test2libd.so.3", archive=0x55555558e950, handle=0x7ffff62a4270) at /home/peng/D      ownloads/git/celix/libs/framework/src/framework.c:2307
    1 2307▸           if (*handle == NULL) {
    2 $23 = ".cache/bundle1/version0.5/libhello_test2libd.so.3", '\000' <repeats 206 times>
    3 $24 = (void *) 0x7fffe8011750
    4 #0  framework_loadLibrary (framework=0x55555558a1e0, library=0x7ffff62a42a0 "libhello_test2libd.so.3", archive=0x55555558e950, handle=0x7ffff62a4270) at /home/peng/Downloads/git/celix/libs/framework/src/fra      mework.c:2307
    5 #1  0x00007ffff7f9c065 in framework_loadLibraries (framework=0x55555558a1e0, librariesIn=0x7fffe800f1d0 "libhello_test2libd.so.3", activator=0x7fffe800e3d0 "1", archive=0x55555558e950, activatorHandle=0x7ff      ff62a4360) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:2252
    6 #2  0x00007ffff7f9be1e in framework_loadBundleLibraries (framework=0x55555558a1e0, bundle=0x55555558bfc0) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:2200                                   7 #3  0x00007ffff7f9aa2e in framework_markBundleResolved (framework=0x55555558a1e0, module=0x7fffe8010b00) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:1761
    8 #4  0x00007ffff7f9a8d5 in framework_markResolvedModules (framework=0x55555558a1e0, resolvedModuleWireMap=0x7fffe8010c80) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:1727
    9 #5  0x00007ffff7f9830d in fw_startBundle (framework=0x55555558a1e0, bndId=1, options=1) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:862
   10 #6  0x00007ffff7f98ba0 in framework_updateBundle (framework=0x55555558a1e0, bundle=0x55555558bfc0, inputFile=0x7ffff62a4670 "update0pQNqz") at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:1      011
   11 #7  0x00007ffff7f8db0b in bundle_update (bundle=0x55555558bfc0, inputFile=0x7ffff62a4670 "update0pQNqz") at /home/peng/Downloads/git/celix/libs/framework/src/bundle.c:286
   12 #8  0x00007ffff7f23413 in updateCommand_execute (handle=0x5555555946d0, const_line=0x7ffff62a4950 "update 1 file:/home/peng/Downloads/git/celix/build/examples/export_import/hello_export-Debug.zip", outStrea      m=0x7ffff7e096a0 <_IO_2_1_stdout_>, errStream=0x7ffff7e095c0 <_IO_2_1_stderr_>) at /home/peng/Downloads/git/celix/bundles/shell/shell/src/update_command.c:60
   13 #9  0x00007ffff7f21c20 in shell_executeCommand (shell=0x555555595940, commandLine=0x7ffff62a4950 "update 1 file:/home/peng/Downloads/git/celix/build/examples/export_import/hello_export-Debug.zip", out=0x7ff      ff7e096a0 <_IO_2_1_stdout_>, err=0x7ffff7e095c0 <_IO_2_1_stderr_>) at /home/peng/Downloads/git/celix/bundles/shell/shell/src/shell.c:277
   14 #10 0x00007ffff7f153c0 in shellTui_parseInput (shellTui=0x55555559d7f0, ctx=0x7ffff62a4950) at /home/peng/Downloads/git/celix/bundles/shell/shell_tui/private/src/shell_tui.c:259                                15 #11 0x00007ffff7f151fe in shellTui_runnable (data=0x55555559d7f0) at /home/peng/Downloads/git/celix/bundles/shell/shell_tui/private/src/shell_tui.c:220
   16 #12 0x00007ffff7e18609 in start_thread (arg=<optimized out>) at pthread_create.c:477
   17 #13 0x00007ffff7d3f293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
   18
   19 Thread 3 "helloworld_with" hit Breakpoint 1, celix_libloader_close (handle=0x7fffe8011750) at /home/peng/Downloads/git/celix/libs/framework/src/celix_library_loader.c:40                                        20 40▸         dlclose(handle);
   21 $25 = (celix_library_handle_t *) 0x7fffe8011750
   22 #0  celix_libloader_close (handle=0x7fffe8011750) at /home/peng/Downloads/git/celix/libs/framework/src/celix_library_loader.c:40
   23 #1  0x00007ffff7f9c0c9 in framework_loadLibraries (framework=0x55555558a1e0, librariesIn=0x7fffe800f1d0 "libhello_test2libd.so.3", activator=0x7fffe800e3d0 "1", archive=0x55555558e950, activatorHandle=0x7ff      ff62a4360) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:2258                                                                                                                                 24 #2  0x00007ffff7f9be1e in framework_loadBundleLibraries (framework=0x55555558a1e0, bundle=0x55555558bfc0) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:2200
   25 #3  0x00007ffff7f9aa2e in framework_markBundleResolved (framework=0x55555558a1e0, module=0x7fffe8010b00) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:1761                                   26 #4  0x00007ffff7f9a8d5 in framework_markResolvedModules (framework=0x55555558a1e0, resolvedModuleWireMap=0x7fffe8010c80) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:1727
   27 #5  0x00007ffff7f9830d in fw_startBundle (framework=0x55555558a1e0, bndId=1, options=1) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:862
   28 #6  0x00007ffff7f98ba0 in framework_updateBundle (framework=0x55555558a1e0, bundle=0x55555558bfc0, inputFile=0x7ffff62a4670 "update0pQNqz") at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:1      011
   29 #7  0x00007ffff7f8db0b in bundle_update (bundle=0x55555558bfc0, inputFile=0x7ffff62a4670 "update0pQNqz") at /home/peng/Downloads/git/celix/libs/framework/src/bundle.c:286
   30 #8  0x00007ffff7f23413 in updateCommand_execute (handle=0x5555555946d0, const_line=0x7ffff62a4950 "update 1 file:/home/peng/Downloads/git/celix/build/examples/export_import/hello_export-Debug.zip", outStrea      m=0x7ffff7e096a0 <_IO_2_1_stdout_>, errStream=0x7ffff7e095c0 <_IO_2_1_stderr_>) at /home/peng/Downloads/git/celix/bundles/shell/shell/src/update_command.c:60
   31 #9  0x00007ffff7f21c20 in shell_executeCommand (shell=0x555555595940, commandLine=0x7ffff62a4950 "update 1 file:/home/peng/Downloads/git/celix/build/examples/export_import/hello_export-Debug.zip", out=0x7ff      ff7e096a0 <_IO_2_1_stdout_>, err=0x7ffff7e095c0 <_IO_2_1_stderr_>) at /home/peng/Downloads/git/celix/bundles/shell/shell/src/shell.c:277
   32 #10 0x00007ffff7f153c0 in shellTui_parseInput (shellTui=0x55555559d7f0, ctx=0x7ffff62a4950) at /home/peng/Downloads/git/celix/bundles/shell/shell_tui/private/src/shell_tui.c:259
   33 #11 0x00007ffff7f151fe in shellTui_runnable (data=0x55555559d7f0) at /home/peng/Downloads/git/celix/bundles/shell/shell_tui/private/src/shell_tui.c:220                                                          34 #12 0x00007ffff7e18609 in start_thread (arg=<optimized out>) at pthread_create.c:477
   35 #13 0x00007ffff7d3f293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
   36
   37 Thread 3 "helloworld_with" hit Breakpoint 1, celix_libloader_close (handle=0x7fffe8011750) at /home/peng/Downloads/git/celix/libs/framework/src/celix_library_loader.c:40
   38 40▸         dlclose(handle);
   39 $26 = (celix_library_handle_t *) 0x7fffe8011750
   40 #0  celix_libloader_close (handle=0x7fffe8011750) at /home/peng/Downloads/git/celix/libs/framework/src/celix_library_loader.c:40
   41 #1  0x00007ffff7f993a3 in fw_uninstallBundleEntry (framework=0x55555558a1e0, entry=0x55555558df10) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:1183
   42 #2  0x00007ffff7f9cc50 in celix_framework_uninstallBundle (fw=0x55555558a1e0, bndId=1) at /home/peng/Downloads/git/celix/libs/framework/src/framework.c:2494
   43 #3  0x00007ffff7f93e75 in celix_bundleContext_uninstallBundle (ctx=0x5555555946d0, bundleId=1) at /home/peng/Downloads/git/celix/libs/framework/src/bundle_context.c:713
   44 #4  0x00007ffff7f237a6 in uninstallCommand_execute (handle=0x5555555946d0, const_command=0x7ffff62a4950 "uninstall 1", outStream=0x7ffff7e096a0 <_IO_2_1_stdout_>, errStream=0x7ffff7e095c0 <_IO_2_1_stderr_>)       at /home/peng/Downloads/git/celix/bundles/shell/shell/src/uninstall_command.c:52
   45 #5  0x00007ffff7f21c20 in shell_executeCommand (shell=0x555555595940, commandLine=0x7ffff62a4950 "uninstall 1", out=0x7ffff7e096a0 <_IO_2_1_stdout_>, err=0x7ffff7e095c0 <_IO_2_1_stderr_>) at /home/peng/Down      loads/git/celix/bundles/shell/shell/src/shell.c:277
   46 #6  0x00007ffff7f153c0 in shellTui_parseInput (shellTui=0x55555559d7f0, ctx=0x7ffff62a4950) at /home/peng/Downloads/git/celix/bundles/shell/shell_tui/private/src/shell_tui.c:259
   47 #7  0x00007ffff7f151fe in shellTui_runnable (data=0x55555559d7f0) at /home/peng/Downloads/git/celix/bundles/shell/shell_tui/private/src/shell_tui.c:220
   48 #8  0x00007ffff7e18609 in start_thread (arg=<optimized out>) at pthread_create.c:477
   49 #9  0x00007ffff7d3f293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

For bundle without activator, all handles of its shared objects are
immediately closed after dlopen. Thus they should NOT be added to a
revision's handle-list.
@codecov-io
Copy link

Codecov Report

Merging #301 (2142389) into master (2546c64) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #301   +/-   ##
=======================================
  Coverage   66.74%   66.74%           
=======================================
  Files         147      147           
  Lines       29947    29947           
=======================================
  Hits        19987    19987           
  Misses       9960     9960           
Impacted Files Coverage Δ
libs/framework/src/framework.c 75.53% <100.00%> (ø)
.../pubsub_admin_zmq/v2/src/pubsub_zmq_topic_sender.c 73.46% <0.00%> (-0.59%) ⬇️
libs/utils/src/hash_map.c 93.08% <0.00%> (-0.58%) ⬇️
libs/framework/src/service_tracker.c 77.13% <0.00%> (-0.19%) ⬇️
.../pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_admin.c 56.35% <0.00%> (+0.37%) ⬆️
...dmin_websocket/src/pubsub_websocket_topic_sender.c 83.24% <0.00%> (+1.11%) ⬆️
bundles/pubsub/pubsub_utils/src/pubsub_utils.c 69.31% <0.00%> (+1.13%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2546c64...2142389. Read the comment docs.

@PengZheng
Copy link
Contributor Author

@pnoltes @Oipo
Could you have a look at this? It seems like a bug.

Copy link
Contributor

@pnoltes pnoltes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First off, I am not very familiar with this part of Celix (so loading/closing libraries).
I did some improvement for this, but this was very "just fix it" oriented.

I also think that loadLibraries/closeLibraries handling could use a refactoring to make this more cleaner, less code copies and in a separate source / header file from the framework.c.
Note that framework.c is more that 2500 lines of code and that makes it very hard to maintain.

Looking a the stacktrace I see that it tries to close the library at

celix_libloader_close(handle);

I think the bug is in the else if condition.

The if will set the activatorHandle to the current handle if that is the activator library and if this was loaded successful. Ok nothing wrong there.
The else if will just close the library if the handle is not null, meaning all libraries loaded that are not the activator will be closed here. This is not what I expected.

I expect the whole handeling of a loadLibrary result to be something like:

if (status == CELIX_SUCCESS) {
  //ok, library loaded successful
 if (activator != NULL && strcmp(trimmedLib, activator) == 0) {
  //the activator library was loaded, setting activatorHandle
  *activatorHandle = handle;
 }
} else {
  //TODO log error
  assert(handle == NULL); //framework_loadLibrary should not return a handle if it is not successful
}

@@ -2307,16 +2317,6 @@ static celix_status_t framework_loadLibrary(framework_pt framework, const char *
if (*handle == NULL) {
error = celix_libloader_getLastError();
status = CELIX_BUNDLE_EXCEPTION;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this and moving this to loadLibraries (and only for the activator libraries) means that not all libraries mentioned in Private-Library and Import-Library are added to the handles list.
I think this is not the desired result.

I expected this issues to be solved during the stopping if a bundle (i.e. during the closing of a library).

Could you first add an unit test to reproduce this issue. We already have some test for starting/stopping bundles. See

const char * const TEST_BND1_LOC = "" SIMPLE_TEST_BUNDLE1_LOCATION "";

add_celix_bundle(simple_test_bundle4 NO_ACTIVATOR VERSION 1.0.0)

add_celix_bundle(simple_test_bundle1 NO_ACTIVATOR VERSION 1.0.0)

@PengZheng PengZheng changed the title Fix double dlclose when uninstalling bundle without activator [WIP]Fix double dlclose when uninstalling bundle without activator Dec 7, 2020
@PengZheng PengZheng marked this pull request as draft March 4, 2022 08:41
@PengZheng
Copy link
Contributor Author

It should have been fixed by #476

@PengZheng PengZheng closed this May 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants