Skip to content

ddprof_lib_state undefined symbol when loader is dlopen'd with RTLD_GLOBAL #520

@xroche

Description

@xroche

Loading libdd_profiling.so at runtime via dlopen("libdd_profiling.so", RTLD_LAZY | RTLD_GLOBAL) fails:

undefined symbol: ddprof_lib_state

This breaks profiling for applications that dlopen the library instead of linking it at build time (e.g., toggling profiling via a config flag).

Root cause

ddprof_lib_state (a TLS variable added in #490 for fork safety) is defined in the loader and referenced as extern in the embedded .so.

The loader's constructor (loader.c:251) calls my_dlopen(embedded.so, RTLD_LOCAL | RTLD_NOW) during its own initialization. On glibc, RTLD_GLOBAL takes effect after dlopen returns, not while the loaded library's constructors run. The loader's symbols are not yet in global scope when the embedded library tries to resolve ddprof_lib_state.

v0.23.0 worked because the embedded .so had no undefined symbols referencing the loader.

Reproduction

void *h = dlopen("libdd_profiling.so", RTLD_LAZY | RTLD_GLOBAL);
// Constructor fails: embedded .so can't resolve ddprof_lib_state
int rc = ddprof_start_profiling(); // returns -1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions