How can dlerror() return NULL if dlopen() fails?
Solution 1
In this code:
handle=dlopen(mod->binary_file, RTLD_NOW);
if (!handle) {
LOG( " could not open file [%s]: %s\n",
mod_cfg->binary_file, dlerror() );
the most likely way I can think of for the dlerror()
to return NULL
here is if LOG
itself calls one of the dl*
routines (which would clear the error state that dlerror
returns).
So,
- show us what
LOG
macro (if indeed it is a macro) expands to, and - run the program under GDB, set breakpoints on
dlopen
,dlmopen
,dlsym
anddlvsym
, and observe that one of them is called after your call todlopen
above and before your call todlerror
.
Solution 2
I would use a debugger like gdb
.
If you cannot use it, try to use strace
or ltrace
on the process doing the dlopen
Also, clear errno
before calling dlopen
and display it (or print it under the debugger) just after the failing dlopen
.
Check with file
, objdump
, and nm -D
that your dlopen
-ed *.so
file has all the required properties (e.g. symbols).
Perhaps the memory address space of the process doing the dlopen
is so full (or has reached some resource limits) that some internal malloc
inside libdl.so
fails (e.g. the one used by dlerror
).
Mike Albren
Updated on June 05, 2022Comments
-
Mike Albren almost 2 years
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 thatdlopen()
fails after my changes anddlerror()
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 */
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; }
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; }
-
Basile Starynkevitch over 12 yearsbut the original poster says that it returns NULL !
-
Tim Post over 12 years@jørgensen Just a ping to let you know the question was edited. The OP did note that
dlerror()
returned NULL, but has since been edited for clarity. -
yugr almost 5 yearsThis is a duplicate of another answer.