首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果dlopen()失败,dlerror()如何返回NULL?

如果dlopen()失败,dlerror()如何返回NULL?
EN

Stack Overflow用户
提问于 2011-12-18 03:31:59
回答 5查看 11.6K关注 0票数 3

我正在工作的系统,通过调用脚本自动加载所有*.so模块库。

我尝试更新其中一个模块以支持XML-RPC。我在Ubuntu10.10上使用了ibxmlrpc-c3-dev库。在我的更改之后dlopen()失败并且dlerror()返回NULL的问题。编译不会返回任何错误。

如何调试和修复此问题?代码如下:

代码语言:javascript
复制
#include "stdlib.h"
#include "stdio.h"
#ifndef WIN32
#include "unistd.h"
#endif

#include "xmlrpc-c/base.h"
#include "xmlrpc-c/server.h"
#include "xmlrpc-c/server_abyss.h"

#include "config.h"  /* information about this build environment */

而且,我添加了这个函数,即使dlopen()失败了,大多数行也被注释掉了:

代码语言:javascript
复制
int RPC_Server(int           const port) {

   // xmlrpc_server_abyss_parms serverparm;
    //xmlrpc_registry * registryP;
    xmlrpc_env env;



    xmlrpc_env_init(&env);

    //registryP = xmlrpc_registry_new(&env);

   // xmlrpc_registry_add_method(
    //    &env, registryP, NULL, "sample.add", &sample_add, NULL);

    /* In the modern form of the Abyss API, we supply parameters in memory
       like a normal API.  We select the modern form by setting
       config_file_name to NULL:
    */
  //  serverparm.config_file_name = NULint
    RPC_Server(int           const port) {

       // xmlrpc_server_abyss_parms serverparm;
        //xmlrpc_registry * registryP;
        xmlrpc_env env;



        xmlrpc_env_init(&env);

        //registryP = xmlrpc_registry_new(&env);

       // xmlrpc_registry_add_method(
        //    &env, registryP, NULL, "sample.add", &sample_add, NULL);

        /* In the modern form of the Abyss API, we supply parameters in memory
           like a normal API.  We select the modern form by setting
           config_file_name to NULL:
        */
      //  serverparm.config_file_name = NULL;
       // serverparm.registryP        = registryP;
       // serverparm.port_number      = port;
       // serverparm.log_file_name    = "/tmp/xmlrpc_log";

       // printf("Running XML-RPC server...\n");

       // xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name));

        /* xmlrpc_server_abyss() never returns */

        return 0;
    }L;
   // serverparm.registryP        = registryP;
   // serverparm.port_number      = port;
   // serverparm.log_file_name    = "/tmp/xmlrpc_log";

   // printf("Running XML-RPC server...\n");

   // xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name));

    /* xmlrpc_server_abyss() never returns */

    return 0;
}

这是用于加载模块的代码

代码语言:javascript
复制
#ifndef RTLD_NOW

#define RTLD_NOW DL_LAZY
#endif   
void* handle;
char* error;


handle=dlopen(mod->binary_file, RTLD_NOW); 

if (!handle){
LOG( " could not open file [%s]: %s\n",
    mod_cfg->binary_file, dlerror() );
return 0;
}
EN

回答 5

Stack Overflow用户

发布于 2011-12-18 08:04:18

在此代码中:

代码语言:javascript
复制
handle=dlopen(mod->binary_file, RTLD_NOW); 

if (!handle) {
    LOG( " could not open file [%s]: %s\n",
         mod_cfg->binary_file, dlerror() );

我能想到的最有可能让dlerror()在这里返回NULL的方式是LOG本身调用一个dl*例程(这将清除dlerror返回的错误状态)。

所以,

  • 向我们展示了LOG宏(如果它确实是宏)将扩展到什么位置,
  • 在GDB下运行程序,在dlopendlmopendlsymdlvsym上设置断点,并观察到其中一个断点是在您调用上面的<代码>d15之后、调用dlerror.

之前调用的

票数 5
EN

Stack Overflow用户

发布于 2011-12-18 03:37:41

我会使用像gdb这样的调试器。

如果不能使用,请尝试在执行dlopen的进程上使用straceltrace

此外,在调用dlopen之前清除errno,并在失败的dlopen之后立即显示它(或在调试器下打印它)。

fileobjdumpnm -D确认您的dlopen-ed *.so文件具有所有必需的属性(例如符号)。

可能是执行dlopen的进程的内存地址空间太满(或者达到了一些资源限制),导致libdl.so内部的一些内部malloc失败(例如dlerror使用的那个)。

票数 2
EN

Stack Overflow用户

发布于 2019-06-10 12:19:00

代码语言:javascript
复制
handle=dlopen(mod->binary_file, RTLD_NOW); 

if (!handle){
string errmsg = string(dlerror());
LOG( " could not open file [%s]: %s\n",
    mod_cfg->binary_file, errmsg.c_str() );
return 0;
}

我在使用BoostLog时遇到了同样的问题,上面就是我的解决方案。我认为LOG会影响dlerror()。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8547372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档