从共享对象中抛出段错误的回调
据我了解,当使用 dlopen 加载我的 .so 时,共享对象将映射到调用进程的地址空间。我可以调用函数并访问 .so
的全局变量,不会出现错误。但是,每当我将 .so 函数传递给主程序中函数的回调指针时,就会发生以下情况:
- .so 函数按预期进入调用堆栈。
- 回调的地址从 0x400F09(如主程序中所示)更改为 0x6052A0(如
.so
中所示)。 - 当我尝试调用回调时出现段错误。
这是某种基本的内存映射问题,还是有更棘手的问题?
谢谢。
编辑:
这是有问题的代码。在主程序中:
static unsigned char innerFunc_1(unsigned char x) { return x+1; }
static unsigned short innerFunc_2(unsigned short x) { return x+1; }
static unsigned int innerFunc_4(unsigned int x) { return x+1; }
static unsigned long long innerFunc_8(unsigned long long x) { return x+1; }
static void *restrict innerFuncs[] =
{
innerFunc_1,
innerFunc_2,
innerFunc_4,
innerFunc_8
};
typedef void(*IterFunc)(void *context, void *innerFunc);
static IterFunc *restrict fptrIter;
// ...
fptrIter[fptrIterOffset()] = dlsym(libhandle, name);
// ...
unsigned (*fptrInner)(unsigned) = innerFuncs[dimElmSize.index];
fptrInner(10); // does not segfault
fptrIter[fptrIterOffset()](pcontext, fptrInner);
在.so中:
typedef unsigned (*InnerFunc_4)(unsigned x);
void iter_pointstoarray_4_1loop_lrud
(InnerFunc_4 innerFunc)
{
innerFunc(0); // Segfaults
}
As I understand it, when my .so
is loaded using dlopen
, the shared object is mapped into the address space of the calling process. I can call functions and access globals of the .so
without error. However, whenever I pass a .so
function a callback pointer to a function in the main program, the following happen:
- The
.so
function goes onto the call stack as expected. - The address of the callback changes from 0x400F09 (as seen in the main program) to 0x6052A0 (as seen in the
.so
). - When I try to call the callback there's a segfault.
Is this some sort of fundamental memory mapping problem, or is there something trickier afoot?
Thanks.
Edit:
Here is the offending code. In the main program:
static unsigned char innerFunc_1(unsigned char x) { return x+1; }
static unsigned short innerFunc_2(unsigned short x) { return x+1; }
static unsigned int innerFunc_4(unsigned int x) { return x+1; }
static unsigned long long innerFunc_8(unsigned long long x) { return x+1; }
static void *restrict innerFuncs[] =
{
innerFunc_1,
innerFunc_2,
innerFunc_4,
innerFunc_8
};
typedef void(*IterFunc)(void *context, void *innerFunc);
static IterFunc *restrict fptrIter;
// ...
fptrIter[fptrIterOffset()] = dlsym(libhandle, name);
// ...
unsigned (*fptrInner)(unsigned) = innerFuncs[dimElmSize.index];
fptrInner(10); // does not segfault
fptrIter[fptrIterOffset()](pcontext, fptrInner);
In the .so:
typedef unsigned (*InnerFunc_4)(unsigned x);
void iter_pointstoarray_4_1loop_lrud
(InnerFunc_4 innerFunc)
{
innerFunc(0); // Segfaults
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,内部函数的函数原型是错误的。修复原型及其调用方式修复了段错误。这就是编译器无法彻底检查的编译方式的危险。
It turns out that the inner function had the wrong function prototype. Fixing the prototype and the manner in which it was called fixed the segfault. Such is the danger of compiling things in a way that they can't be checked as thoroughly by the compiler.