pothosware / SoapySDR

Vendor and platform neutral SDR support library.
https://github.com/pothosware/SoapySDR/wiki
Boost Software License 1.0
1.09k stars 176 forks source link

Module loading issue related to differences in dlopen default flags in macOS and linux #430

Closed npm-sdr closed 2 months ago

npm-sdr commented 4 months ago

Hi,

I'm seeing an issue in macOS where SoapySDR is calling driver the registration function of a driver from a wrong library. All libraries are loaded by automaticLoadModules() function call in SoapySDR::Device::enumerate. I have 2 libraries for 2 different types of hardware, library x for driver x and library y for driver y. On macOS driver y gets enumerated using library x. Having looked at what's causing the issue, it looks like it's caused by default flags of dlopen. On macOS dlopen, if neither RTLD_GLOBAL nor RTLD_LOCAL is specified, the default is RTLD_GLOBAL. On Linux dlopen, RTLD_LOCAL is the default if neither flag is specified.

https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlopen.3.html

https://man7.org/linux/man-pages/man3/dlopen.3.html

Can we explicitly add RTLD_LOCAL to SoapySDR::loadModule dlopen function call?

Regards, Niro.

zuckschwerdt commented 4 months ago

Out of curiosity, which driver modules did you encounter this problem with?

npm-sdr commented 4 months ago

It's a custom driver module I wrote for my own hardware - I started with rtlsdr Soapy driver module as a starting point. I have two different generations of H/W and for this I created two different Soapy driver modules so that I can link each Soapy driver module against a hardware specific low-level driver library. I've given these Soapy driver modules unique driver names as below and built 2 independent shared libraries:

static SoapySDR::Registry registerSDRFE("soapy_sdrfe_sc5", &findSDRFE, &makeSDRFE, SOAPY_SDR_ABI_VERSION);

and

static SoapySDR::Registry registerSDRFE("soapy_sdrfe_sc7", &findSDRFE, &makeSDRFE, SOAPY_SDR_ABI_VERSION);

zuckschwerdt commented 4 months ago

Effectively all your symbols are duplicated, and perhaps one of registerSDRFE, findSDRFE, makeSDRFE then creates this problem? You might be the first one to encounter this oddity then :) It should go away when stripping the symbols (nm -u) from the modules, right?

Nevertheless the suggestion to explicity choose RTLD_LOCAL seems a good idea.

npm-sdr commented 4 months ago

I tried renaming findSDRFE/makeSDRFE to findSDRFE_sc5/makeSDRFE_sc5 and findSDRFE_sc7/makeSDRFE_sc7 in the 2 Soapy driver modules and that didn't help. Also tried stripping the symbols and that didn't work either.

npm-sdr commented 2 months ago

@zuckschwerdt, is SoapySDR still being maintained? There hasn't been any commits or bug fixes since middle of last year.

zuckschwerdt commented 2 months ago

There are admins still around and active maintainers tending mostly to the modules. I guess development slowed down as things are working well and are somewhat feature-complete?

I'll PR this fix and merge it in ~2 weeks -- should give everyone a chance to chime in if needed.

npm-sdr commented 2 months ago

There are admins still around and active maintainers tending mostly to the modules. I guess development slowed down as things are working well and are somewhat feature-complete?

I'll PR this fix and merge it in ~2 weeks -- should give everyone a chance to chime in if needed.

Great - thank you.