Skip to content

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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions