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

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

如何调试和解决此问题?下面是代码:

#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()失败,大多数行也被注释掉了:
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;
}

这是用于加载模块的代码
#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;
}

最佳答案

在此代码中:

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上设置断点,并观察其中的一个在调用上面的dlopen之后和调用dlerror之前被调用。
  • 10-06 09:52