AddressSanitizer: odr-violation

Hi,

I got this error:

==10015==ERROR: AddressSanitizer: odr-violation (0x558f0a2712a0):
  [1] size=24 'Steinberg::FUnknown::iid' ../../libs/vstsdk3/base/source/baseiids.cpp:47:1
  [2] size=24 'Steinberg::FUnknown::iid' ../../libs/vstsdk3/base/source/baseiids.cpp:47:1

Because baseiids.cpp were compiled in both the plugin and the host.
Should I ignore this error? Should those symbols be compiled in the plugin or in the host or in both?

Many thanks,
Alex.

PS:

https://github.com/google/sanitizers/wiki/AddressSanitizerOneDefinitionRuleViolation

can you try to link the plugin with option: -Bsymbolic ?
"When creating a shared library, bind references to global symbols to the definition within the shared library, if any. Normally, it is possible for a program linked against a shared library to override the definition within the shared library. This option is only meaningful on ELF platforms which support shared libraries. "

This informs the dlopen (at loading time) function to use at first the local symbol for resolving map before using the ones already defined in the app or previous loaded libraries,.

Not sure that it will avoid the ODR violation…

What we need is something like on Mac the option -r :
" Save the relocation information in the output file so that it can be the subject of another ld run. The resulting file type is a Mach-O relocatable file (MH_OBJECT) if not otherwise specified. This flag also prevents final definitions from being given to common symbols, and suppresses the `undefined symbol’ diagnostics. "

need more investigation…

as workaround for now if we are sure that we have the same definition for the duplicate, we could skip this error…

That reminds me of the WEAK symbols for the templates.

Hi,
I think loading the plug-in needs to be done with dlmopen and LM_ID_NEWLM flag instead of dlopen.
I think this is equivalent to the way how dll’s are loaded on Windows and dylibs are loaded on MacOS ?
Otherwise a plug-in share all symbols with the host and all other loaded plug-ins, which will fail in many ways.

Arne

I’ve tried it, but it led to gtk crashing in my tests.
Did you try it?

No, did not try, just heard about it and searched the web for info. And now I read more about it and it is not the same as on macOS or Windows.
I think the only solution seems to be to remove all symbols but GetPluginFactory from the plug-in as this is the only symbol the host needs to know about.

But then if a plugin host which does not support vst3, but vst2 opens the plugin some symbols will be missing right?

I’m not sure I get you here, but vst2 plug-ins need to export VSTPluginMain. So if you implement a vst2 and a vst3 plug-in in the same executable than you have to export two symbols instead of only one.

I mean if I build a single plugin which contains many different plugin interface in one .so: vst2, vst3, lv2, …

If I don’t include …/…/libs/vstsdk3/base/source/baseiids.cpp in the plugin then I’ll rely on the host to provide the symbol. But if one host only implements lv2, then it will not provide baseiids.cpp symbols and my plugin will have undefined references right?

Ah OK. When I say remove all symbols except GetPluginFactory, then I meant to remove the symbol names, not the actual symbol from the executable.
The Plug-in and the host both need those COM iids. No way to leave them out. The dynamic loader on linux should just not map those two identical DATA sections to the same address, they should be private.

So maybe there is a gcc/clang attribute we could add to those fields so they are private?

Did you get a working solution for this ODR violation ?
Thanks

Hi,
No I did not.
Alex.

Hi Alex,
I think I found the solution!
Just add
-fvisibility=hidden
as compile flag.
Can you confirm ?

Cheers
Arne