我正在工作的系统,通过调用脚本自动加载所有*.so模块库。
我尝试更新其中一个模块以支持XML-RPC。我在Ubuntu10.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;
}发布于 2011-12-18 08:04:18
在此代码中:
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宏(如果它确实是宏)将扩展到什么位置,dlopen、dlmopen、dlsym和dlvsym上设置断点,并观察到其中一个断点是在您调用上面的<代码>d15之后、调用dlerror.之前调用的
发布于 2011-12-18 03:37:41
我会使用像gdb这样的调试器。
如果不能使用,请尝试在执行dlopen的进程上使用strace或ltrace
此外,在调用dlopen之前清除errno,并在失败的dlopen之后立即显示它(或在调试器下打印它)。
与file、objdump和nm -D确认您的dlopen-ed *.so文件具有所有必需的属性(例如符号)。
可能是执行dlopen的进程的内存地址空间太满(或者达到了一些资源限制),导致libdl.so内部的一些内部malloc失败(例如dlerror使用的那个)。
发布于 2019-06-10 12:19:00
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()。
https://stackoverflow.com/questions/8547372
复制相似问题