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

Avoiding unique global symbols #549

Closed
GiovanniBussi opened this issue Feb 3, 2020 · 3 comments
Closed

Avoiding unique global symbols #549

GiovanniBussi opened this issue Feb 3, 2020 · 3 comments

Comments

@GiovanniBussi
Copy link
Member

I noticed that when using plumed from python the libplumedKernel.so library is not unloaded correctly on Linux. To see the bug use export PLUMED_LOAD_DEBUG=1 and then:

>>> import plumed
>>> p=plumed.Plumed("/path/to/libplumedKernel.so")
[ ... some output ... ]
>>> del p
[ ... some output ...] 
+++ Unloading library
# the following line will NOT show up on Linux
# it will instead show up on MacOS
+++ Finalizing PLUMED with plumed_symbol_table at [ ... etc ...]

This seems to be a consequence of the presence of some "unique global symbols" in the library (show with nm -C libplumedKernel.so | grep " u "). I already have some fixes ready to be merged, but I open an issue here so I can refer to the issue in the commits (and in case people might comment).

@GiovanniBussi
Copy link
Member Author

GiovanniBussi commented Feb 7, 2020

These symbols appear when you have an inline function containing a static variable.

Case 1: function that is inline by chance. If the function is defined and used only in a single cpp file you can make it explicitly non-inline.

Case 2: function that is inline but not critical for performance. If the function is not critical for performance then it can be made non-inline moving it to a cpp file (see 476ee27).

Case 3: function that is inline but critical for performance. This is more complicated. If the static variable is just caching an environment variable then the function can be made static inline at namespace level. Notice that in this way there will be a separate copy of the static variable in each of the cpp files including the header file with the function definition. This is fine for the specific case of retrieving an environment variable (27616d1 and 775694c; the latter actually is only appearing in a single cpp file) but might not be correct in general. It is also ok if you have to store a constant static variable (0a2f726 and 1d7d730). Notice that in the last case (asmjit/func.h) an anonymous namespace was used, with a result similar to that of a static inline function.

@GiovanniBussi
Copy link
Member Author

I close the issue since this is basically fixed. I added a check on our CI so as to detect future appearances of the issue. The only remaining unique global symbols are:

  • Boost symbols. This implies that linking boost the problem will appear again (this is a known issue). Those hits are ignored with grep.
  • Symbols when configuring with --enable-debug-glibcxx. The check is skipped in this case.

GiovanniBussi added a commit that referenced this issue Apr 27, 2023
This option should solve once for all the problem with gnu unique symbols.
I am not 100% this option will not introduce troubles linking other C++
libraries, and thus I leave the possibility to remove it with
./configure --disable-no-gnu-unique

However, problems are very unlikely considering that this is the
same behavior of icpc and clang.

See #549
@GiovanniBussi
Copy link
Member Author

This closed now but I add a comment for future reference.

With current flags (-fno-gnu-unique) the shared library should be always unloadable and gcc will behave as intel and clang. However, I would still recommend avoiding inline functions containing static variables, since intel and clang (and, with this flag, also gcc) actually violate the c++ standard and create a separate copy of the inline variable in each library.

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

No branches or pull requests

1 participant