【问题标题】:dlerror: Undefined symbol "_nss_cache_cycle_prevention_function" on FreeBSD 7.2dlerror:FreeBSD 7.2 上的未定义符号“_nss_cache_cycle_prevention_function”
【发布时间】:2025-11-28 00:50:02
【问题描述】:

我有一个 ANSI C 程序,它使用传递 RTLD_LAZY 的 dlopen() 动态加载 .so 文件。我收到了

Undefined symbol "_nss_cache_cycle_prevention_function"

在 FreeBSD 7.2 中访问 .so 文件时发出警告。 nss_cache_cycle_prevention_function() 不是我程序的功能之一,我想一定来自 FreeBSD。这在 Linux 上也可能是一个问题,尽管我在那里没有遇到这个问题。我不希望将 FreeBSD 特定的头文件加载到我的程序中。我想以可移植的方式包含此功能或禁止显示这些警告。

【问题讨论】:

    标签: c freebsd linker-warning


    【解决方案1】:

    “我收到警告”是什么意思?你的程序是否 检查dlerror()返回的值,如果不为NULL则打印?

    _nss_cache_cycle_prevention_function 是一个标记符号,nsdispatch(3) 在 FreeBSD 上使用它来确定是否使用名称服务缓存守护进程 nscd(8) 的服务。它不存在于一个环境中是完全正常的 可执行文件或共享库。

    但是当nsdispatch(3)执行dlsym(3),并且找不到符号时,就会设置错误。而dlerror(3) 返回的是last 错误的描述,而不是最后一个call 的错误描述。我怀疑这就是你要打的。

    解决方案(相当便携)是:

    • 对于dlopen(3),在使用dlerror()之前检查它的返回值,看看是否有错误;
    • 对于dlsym(3),因为NULL 是一个有效的返回值, 在调用dlsym(3) 之前 在无效上下文中调用dlerror();这将清除之前的任何错误,以便以后对 dlerror(3) 的第二次调用返回的任何内容都可以信任。

    一般来说,在任何其他 dl* 调用之前调用空的 dlerror() 不会有任何损害。

    【讨论】:

    • 是的,我的程序在调用 dlsym() 后将任何非 NULL dlerror() 返回值吐出到日志中。在调用 dlsym() 之前,我按照您所说的进行了调用并调用了 dlerror() 并且未定义的符号警告消失了!谢谢。