How can dlerror() return NULL if dlopen() fails?

Mik*_*ren 3 c linux ubuntu shared-libraries

I am working on system that loads all *.so modules library automatically by call a script.

I tried to update one of the modules to support XML-RPC. I used the library ibxmlrpc-c3-dev on Ubuntu 10.10. The problem that dlopen() fails after my changes and dlerror() returns NULL. The compilation does not return any error.

How can I debug and fix this issue? Below is the code:

#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 */
Run Code Online (Sandbox Code Playgroud)

And, I added this function , most of the lines are commented out ,even though dlopen() fails:

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;
}
Run Code Online (Sandbox Code Playgroud)

and this is the code the is used to load modules

#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;
}
Run Code Online (Sandbox Code Playgroud)

Emp*_*ian 5

在这段代码中:

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

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

我能想到的dlerror()返回NULL这里的最可能方法是如果LOG它本身调用其中一个dl*例程(这将清除dlerror返回的错误状态)。

所以,

  • 向我们展示什么LOG宏(如果它确实一个宏)扩展到,以及
  • 运行GDB下的程序,设置断点上dlopendlmopendlsymdlvsym,并观察他们的一个叫您的来电dlopen以上,您的电话之前dlerror