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

dlclose() not guaranteed to unload the library #17159

Open
dlangBugzillaToGithub opened this issue Jul 26, 2017 · 2 comments
Open

dlclose() not guaranteed to unload the library #17159

dlangBugzillaToGithub opened this issue Jul 26, 2017 · 2 comments

Comments

@dlangBugzillaToGithub
Copy link

Iain Buclaw (@ibuclaw) reported this on 2017-07-26T22:15:42Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=17696

CC List

Description

There's a broken test in druntime. Discovered after making a change in gdc to put ClassInfo symbols in the comdat (yeah I know, but I am yet to receive any duplicate symbol bug reports).

https://github.com/dlang/druntime/blob/master/test/shared/src/load.d#L136-L139


Old gdc behaviour:
---
$ readelf -Ws lib.o  | grep MyFinal
   113: 000000000000078a    38 FUNC    GLOBAL DEFAULT   16 _D3lib11MyFinalizer6__dtorMFZv
   117: 0000000000000000    16 OBJECT  GLOBAL DEFAULT   28 _D3lib11MyFinalizer6__initZ
   118: 0000000000000010    40 OBJECT  GLOBAL DEFAULT   28 _D3lib11MyFinalizer6__vtblZ
   119: 0000000000000000   152 OBJECT  GLOBAL DEFAULT   30 _D3lib11MyFinalizer7__ClassZ
   125: 0000000000000040  4112 OBJECT  GLOBAL DEFAULT   28 _D3lib14MyFinalizerBig6__initZ
   126: 0000000000001050    40 OBJECT  GLOBAL DEFAULT   28 _D3lib14MyFinalizerBig6__vtblZ
   127: 00000000000000a0   152 OBJECT  GLOBAL DEFAULT   30 _D3lib14MyFinalizerBig7__ClassZ
---

New gdc behaviour:
---
$ readelf -Ws lib.o  | grep MyFinal
   124: 000000000000078a    38 FUNC    GLOBAL DEFAULT   22 _D3lib11MyFinalizer6__dtorMFZv
   128: 0000000000000000    16 OBJECT  WEAK   DEFAULT   34 _D3lib11MyFinalizer6__initZ
   129: 0000000000000000    40 OBJECT  WEAK   DEFAULT   38 _D3lib11MyFinalizer6__vtblZ
   130: 0000000000000000   152 OBJECT  UNIQUE DEFAULT   36 _D3lib11MyFinalizer7__ClassZ
   136: 0000000000000000  4112 OBJECT  WEAK   DEFAULT   40 _D3lib14MyFinalizerBig6__initZ
   137: 0000000000000000    40 OBJECT  WEAK   DEFAULT   44 _D3lib14MyFinalizerBig6__vtblZ
   138: 0000000000000000   152 OBJECT  UNIQUE DEFAULT   42 _D3lib14MyFinalizerBig7__ClassZ
---

Current dmd behaviour:
---
$ readelf -Ws lib.o  | grep MyFinal
   105: 0000000000000000    34 FUNC    GLOBAL DEFAULT   70 _D3lib11MyFinalizer6__dtorMFZv
   106: 0000000000000000    16 OBJECT  WEAK   DEFAULT   72 _D3lib11MyFinalizer6__initZ
   107: 0000000000000000   168 OBJECT  WEAK   DEFAULT   73 _D3lib11MyFinalizer7__ClassZ
   108: 0000000000000000    40 OBJECT  WEAK   DEFAULT   75 _D3lib11MyFinalizer6__vtblZ
   109: 0000000000000000  4112 OBJECT  WEAK   DEFAULT   78 _D3lib14MyFinalizerBig6__initZ
   110: 0000000000000000   176 OBJECT  WEAK   DEFAULT   79 _D3lib14MyFinalizerBig7__ClassZ
   111: 0000000000000000    40 OBJECT  WEAK   DEFAULT   81 _D3lib14MyFinalizerBig6__vtblZ
---

Notice that dmd marks the __Class symbol as a weak @object, but gdc marks it as a weak @gnu_unique_object.

This subtle difference means that when calling dlopen() on lib.so, it is marked as DF_1_NODELETE - meaning "not unloadable", and will never be unloaded no matter how many times you call dlclose().


Looking at the documentation:

http://pubs.opengroup.org/onlinepubs/007904975/functions/dlclose.html

===
Although a dlclose() operation is not required to remove structures from an address space, neither is an implementation prohibited from doing so.
===

The druntime test should probably be fixed up, as it may not necessary always be true.

In the meantime, I'll have a look at possibly a fix on my side, something that errs towards --no-gnu-unique, however if its not an agnostic fix, then there's no point in trying to do that.

https://cygwin.com/ml/binutils/2011-10/msg00276.html
@dlangBugzillaToGithub
Copy link
Author

ibuclaw (@ibuclaw) commented on 2017-07-26T22:18:57Z

GCC internals note, there's flag_gnu_unique.  But actually it seems pretty silly turning it off explicitly.

@dlangBugzillaToGithub
Copy link
Author

ibuclaw (@ibuclaw) commented on 2017-07-27T07:05:32Z

And on a D language implementation note, if you didn't use ClassInfo for setting the monitor in synchronized() statements, then I could have just marked the data as read-only.

@thewilsonator thewilsonator added the Druntime Specific to druntime label Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants