【问题标题】:Issue with dlopen and weak symbolsdlopen 和弱符号的问题
【发布时间】:2014-06-25 01:19:06
【问题描述】:

我有以下顺序

executable (main) ---- (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);
}

【问题讨论】:

    标签: shared-libraries dlopen


    【解决方案1】:

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

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

    当您链接单个 ELF 二进制文件时,弱符号会输给强符号。如果您要将普通(强)函数foo 和弱foo 链接到libfoo.so,则强定义会胜出。

    如果您有多个 ELF 图像,一些具有强foo,一些具有弱foo第一个 ELF 图像定义@ 987654329@(无论弱或强)获胜。一旦找到第一个为foo 提供定义的图像,加载程序就不会在其搜索范围内查找任何其他ELF 图像。

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

    这样说是很讨厌的事情。

    我猜测你的原因可能是什么,并有一个解决方案,但你必须先提供你的理由。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 2021-01-04
      • 2018-07-05
      • 1970-01-01
      • 2014-10-20
      • 1970-01-01
      • 2012-10-10
      相关资源
      最近更新 更多