dlopen和弱符号的问题

时间:2014-05-07 21:02:23

标签: shared-libraries dlopen

  

我有以下顺序

     

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

     

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

     

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

     

PS:不要让我解释特定执行顺序的原因,但我愿意接受> workarounds。

     

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);
}

1 个答案:

答案 0 :(得分:2)

  

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

您的期望不正确,一切都按设计运作。

链接单个ELF二进制文件时,弱符号会丢失为强符号。如果您要将普通(强)函数foo和弱foo链接到libfoo.so,那么强定义就会胜出。

如果您有多个 ELF图片,其中一些图片内容为foo,另一些图片内容较弱foo首先 { {1}}图片定义ELF(无论是弱者还是强者)获胜。一旦找到第一个为foo提供定义的图像,加载程序就不会在其搜索范围内查找任何其他ELF图像。

  

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

这是一个令人讨厌的事情。

我猜测你的理由是什么,以及解决方案,但你必须先提供理由。