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

时间:2011-05-23 05:15:24

标签: linux shared-libraries shared-memory

据我了解,当使用.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
}

1 个答案:

答案 0 :(得分:1)

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