从共享对象中抛出段错误的回调

发布于 2024-11-09 06:36:28 字数 1296 浏览 2 评论 0原文

据我了解,当使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生来就爱笑 2024-11-16 06:36:28

事实证明,内部函数的函数原型是错误的。修复原型及其调用方式修复了段错误。这就是编译器无法彻底检查的编译方式的危险。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文