使用dlopen编译C程序和-fPIC对dlsym [英] Compile C program using dlopen and dlsym with -fPIC

查看:355
本文介绍了使用dlopen编译C程序和-fPIC对dlsym的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于一个错误的符号解析问题。我的主要程序加载使用dlopen的共享库,并从它的dlsym的象征。无论是程序和库是用C编写
库code

I am having a problem about a wrong symbol resolution. My main program loads a shared library with dlopen and a symbol from it with dlsym. Both the program and the library are written in C. Library code

int a(int b)
{
  return b+1;
}

int c(int d)
{
  return a(d)+1;
}

为了使其在64位机器上工作,-fPIC传递编译时与gcc。

In order to make it work on a 64-bit machine, -fPIC is passed to gcc when compiling.

该计划是:

#include <dlfcn.h>
#include <stdio.h>

int (*a)(int b);
int (*c)(int d);

int main()
{
  void* lib=dlopen("./libtest.so",RTLD_LAZY);
  a=dlsym(lib,"a");
  c=dlsym(lib,"c");
  int d = c(6);
  int b = a(5);
  printf("b is %d d is %d\n",b,d);
  return 0;
}

一切都正常运行,如果该程序不-fPIC编译,但是它与分段故障崩溃时,程序与-fPIC编译。经过调查,发现,坠机是由于符号的错误的决议。当被调用时,无论从库中或主程序(后者被注释掉调用C()在主程序行获得)发生崩溃。

Everything runs fine if the program is NOT compiled with -fPIC, but it crashes with a segmentation fault when the program is compiled with -fPIC. Investigation led to discover that the crash is due to the wrong resolution of symbol a. The crash occurs when a is called, no matter whether from the library or the main program (the latter is obtained by commenting out the line calling c() in the main program).

出现没有问题,可能是因为C()不是由库本身内部调用,而()既是由图书馆和图书馆的API函数内部使用的功能。

No problems occur when calling c() itself, probably because c() is not called internally by the library itself, while a() is both a function used internally by the library and an API function of the library.

编译程序时,一个简单的解决方法是不使用-fPIC。但是,这并不总是可能的,例如,当主程序的code的是在一个共享库本身。另一个解决方法是重命名函数指针一到别的东西。但是,我找不到任何真正的解决办法。

A simple workaround is not use -fPIC when compiling the program. But this is not always possible, for example when the code of the main program has to be in a shared library itself. Another workaround is to rename the pointer to function a to something else. But I cannot find any real solution.

与RTLD_NOW更换RTLD_LAZY于事无补。

Replacing RTLD_LAZY with RTLD_NOW does not help.

推荐答案

我的犯罪嫌疑人的有两个全局符号之间的冲突。一种解决方案是申报 A 在主程序为静态。另外,在Linux手册页中提到 RTLD_DEEPBIND 标记,只有Linux的扩展,它可以传递给的dlopen 键,这将导致库preFER在全局符号自己的符号。

I suspect that there is a clash between two global symbols. One solution is to declare a in the main program as static. Alternatively, the linux manpage mentions RTLD_DEEPBIND flag, a linux-only extension, which you can pass to dlopen and which will cause library to prefer its own symbols over global symbols.

这篇关于使用dlopen编译C程序和-fPIC对dlsym的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆