2012-12-18 126 views
4

在Linux中。每对dlsym(3)Linux手册页,为什么dlsym()返回的符号值为空?

*Since the value of the symbol could actually be NULL 
    (so that a NULL return from dlsym() need not indicate an error),* 

这是为什么,当可在符号(函数,特别是)是实际NULL?我正在审查代码,并找到一个使用dlerror首先清理,dlsym next和dlerror检查错误的作品。但在调用它之前,它不会检查由此产生的函数为空:

  • dlerror();
  • a_func_name = ... dlsym(...);
  • if(dlerror())goto end;
  • a_func_name(...); //从不检查a_func_name == NULL;

我只是一个评论者,所以没有选择只是添加支票。也许作者知道NULL永远不会被返回。我的工作是挑战,但不知道什么可以使这个返回一个有效的NULL,这样我就可以检查在这个代码的上下文中是否可以满足这样的条件。没有找到适合Google阅读的内容,除非您想明确说明哪个更好,否则指向好的文档就足够了。

+1

您可以在汇编程序中或使用GCC特定技巧定义给定的符号位于地址0,并且您可以“符合”该符号。 –

+0

明白了。谢谢。 – bokusama

回答

1

那么,如果它没有错误地返回,那么指针是有效的,并且NULL与来自共享对象的任何随机指针大约是非法的。像错误的功能,数据或其他。

+3

如果返回值是共享变量(或函数)的*值*,这将有意义。但它应该是地址,是不是(或者是否依赖于标志)?那么,大概它实际上是从一张地址表中读取一个值,并且该二进制文件可以被编辑为在该表中具有零(或者如你所说的任何无效指针)。 –

+0

嗯,我不确定,但不能输出符号有绝对地址? –

+0

确实。谢谢。 – bokusama

-1

dlerror()返回最后一个错误,而不是最后一次调用的状态。因此,如果没有其他代码,您显示的代码可能会从dlsym()得到有效的结果,并且自欺欺人地认为存在错误(因为队列中还有一个错误)。 dlerror背后的目的是提供人类可读的错误消息。如果您不打印结果,则说明您使用的是错误的。

+3

这就是在* dlsym之前立即调用dlerror()的目的 - 清除最近的错误变量。没有队列(如果可以相信手册页)。 –

+0

啊,错过了。是的,所以这是毫无意义但是正确的。 'dlsym'被记录为错误时返回NULL,但是'dlerror'的非NULL结果是等价的(禁止线程安全错误之类的事情 - 如果另一个线程做同样的废话,显然这里有一场竞赛)。这仍然是对API的滥用。 –

+0

当然,每个线程都有自己的错误变量副本。无论如何,这是调用API的正确方式,而不是滥用。比较:'errno = 0; int a = itoa(s);如果(errno)...'因为'如果(a)'不能区分s =“0”;'from's =“Garbage”;'。 –