dlopen 和弱符号问题

1 shared-libraries dlopen

我有以下顺序

可执行(主)----(dlopen)---> libapp.so ---(动态链接)--> libfoo.so

libfoo.so 反过来动态链接到 libfoo_strong.so。libfoo.so 从 libfoo_strong.so 调用一个函数,但也有一个弱定义(在编译成 libfoo.so 的 foo.c 中)。

现在,libapp.so 从 libfoo.so 调用一个函数(比如 invoke_foo_func_ptr() 并且这个函数>调用一个函数指针,它存储定义为弱的符号。我的期望是 >invokes_foo_func_ptr 调用强符号,但它总是到弱符号。请参阅下面的>代码了解详细信息。

PS:不要让我解释特定执行顺序的原因,但我对>变通办法持开放态度。

foo_strong.c --> gcc -g -fPIC -shared -rdynamic foo_strong.o -o libfoo_strong.so

foo.c: --> gcc -g -fPIC -shared -rdynamic -L/users/ardesiga/cprogs/ld_r foo.o -o libfoo.so

app.c: --> gcc -g -fPIC -shared -rdynamic -L/users/ardesiga/cprogs/ld_r -lfoo -lfoo_strong app.o -o > libapp.so

/* foo_strong.c */

int
foo_weak_func (char *msg)
{
    printf("[%s:%s] Reached strong, with msg: %s\n", __FILE__, __FUNCTION__, msg);
}

/* foo.c */

#include <stdio.h>
#include <stdlib.h>

#include "foo_ext.h"

#include "foo_weak.h"

int __attribute__ ((weak)) foo_weak_func (char *msg)
{
    printf("[%s:%s], Reached weak, with msg: %s\n", __FILE__, __FUNCTION__, msg);
}

typedef int (*func_ptr_t) (char *msg);
func_ptr_t foo_func_ptr = foo_weak_func;

void
invoke_foo_func_ptr (char *msg)
{
    printf("Inside %s\n", __FUNCTION__);

    if (foo_func_ptr) {
        (*foo_func_ptr)(msg);
    } else {
        printf("foo_func_ptr is NULL\n");
    }
}


/* app.c */

#include "foo.h"

int
app_init_func (char *msg)
{
    printf("Inside %s:%s\n", __FILE__, __FUNCTION__);

    invoke_foo_func_ptr(msg);

}

/* main.c */

int main (int argc, char *argv[])
{
    void *dl_handle;
    char *lib_name;
    app_init_func_t app_init_func;

    if (!(argc > 1)) {
        printf("Library is not supplied, loading libapp.so\n");
        lib_name = strdup("libapp.so");
    } else {
        lib_name = strdup(argv[2]);
    }

    printf("Loading library: %s\n", lib_name);

    dl_handle = dlopen(lib_name, RTLD_LAZY);
    if (!dl_handle) {
        printf("Failed to dlopen on %s, error: %s\n", lib_name, dlerror());
        exit(1);
    }

    app_init_func = dlsym(dl_handle, "app_init_func");
    if (app_init_func) {
        (*app_init_func)("Called via dlsym");
    } else {
        printf("dlsym did not file app_init_func");
    }

    return (0);
}
Run Code Online (Sandbox Code Playgroud)

Emp*_*ian 7

我的期望是 invokes_foo_func_ptr 调用强符号,但它总是转到弱符号。

您的期望是不正确的,一切都按设计进行。

链接单个ELF二进制文件时,弱符号会输给强符号。如果你将一个普通(强)函数foo和一个弱函数连接foolibfoo.so,强定义就会获胜。

当您有多个 ELF图像时,一些带有 strong foo,一些带有 weak foo,第一个 ELF定义的图像foo(无论是弱还是强)获胜。装载机根本不会寻找任何附加ELF在它的搜索范围内的图像,一旦发现确实提供了一个定义,第一个图像foo

不要让我解释特定执行顺序的原因

说这话真是令人讨厌。

我猜测您的原因可能是什么,以及解决方案,但您必须先提供您的原因。