【问题标题】:Callback throwing a segfault from within a shared object回调从共享对象中引发段错误
【发布时间】:2011-05-23 05:15:23
【问题描述】:

据我了解,当我的.so 使用dlopen 加载时,共享对象被映射到调用进程的地址空间。我可以毫无错误地调用 .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
}

【问题讨论】:

  • 这确实有效,因此您需要发布代码的[最小版本]。
  • 为什么觉得共享地址映射和主程序不一样?
  • 函数是否来自.so 无关紧要。什么触发回调?好像你损坏了一些内存。
  • 是的,这可能是内存损坏或指针杂耍问题。

标签: linux shared-libraries shared-memory


【解决方案1】:

原来内部函数有错误的函数原型。修复原型和调用它的方式修复了段错误。这就是以编译器无法彻底检查的方式编译事物的危险。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 2013-04-16
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    相关资源
    最近更新 更多