【问题标题】:Heap corruption with function pointer on Solaris 64-bitsSolaris 64 位上的函数指针导致堆损坏
【发布时间】:2014-10-16 16:52:29
【问题描述】:

我在 Solaris 5.10 64 位上使用带有标志的 CC 5.10 编译了以下 C 代码 -m64 -KPIC -x04

header.h

typedef struct functions
{
   double (* pfComputeGeneric) (myStruct *, myStruct *, double, double *, int);
} functions;

...

double myCompute(myStruct *, myStruct *, double, double *, int);  

source.c

double myCompute(myStruct * px1, myStruct *px2, double d1, double *pd1, int i1)
{
    // Do stuff with px1
}

...

myStruct *pxStruct = alloc(...);    
functions *pxFunctions = alloc(...);
pxFunctions->pfComputeGeneric = myCompute;

...

double dResult += pxFunctions->pfComputeGeneric(pxStruct, pxStruct, 0.0, NULL, 0);

source.c 中的代码运行良好(没有什么奇怪的),直到我通过函数指针 pfCompute 进入 myCompute,其中 px1 损坏。我不知道为什么。

将通过 pfCompute 的调用替换为直接调用 myCompute 可以解决问题。

删除 -x04 选项也可以解决问题。

我查看了this question 的答案,但我确定我没有弄乱指针大小。

【问题讨论】:

  • } functions 后面少了一个分号。
  • 也许分配有误,或者在您省略的部分中发生了一些狡猾的事情。请编辑您的问题以包括分配,或者更好:发布MCVE。
  • @wildplasser :确实,谢谢。
  • 也许函数没有期望接收到 px1 和 px2 都指向同一个内存?
  • @NisseEngström 这是我的第一个猜测:我检查了 Windows 32 位、Linux 32 位和 64 位以及 Solaris 32 位。代码在所有这些平台上运行良好。净化/博士。记忆也不抱怨。我怀疑那里的选项 (-x04) 有副作用(错误?)。我不能真正包含完整的代码(这是一个高度简化的代码版本,有几百行代码)。实际上,发布这个问题,我想知道在具有 -x04 的 Solaris 64 位上使用函数指针是否存在一些已知问题。

标签: c function-pointers solaris


【解决方案1】:

我觉得确实是-x04的问题。当我查看汇编调用时,我看到:

...
0x0000000000987eb2: myCaller+0x081a:  movq     0xfffffffffffffe28(%rbp),%rcx
0x0000000000987eb9: myCaller+0x0821:  movq     $0x0000000000000006,%rax
0x0000000000987ec0: myCaller+0x0828:  movq     0xfffffffffffffe08(%rbp),%rdi
0x0000000000987ec7: myCaller+0x082f:  call     *0x0000000000000018(%rdi)
0x0000000000987eca: myCaller+0x0832:  addq     $0x0000000000000010,%rsp

所以编译器使用 %rdi (!) 从 pxFunctions 中获取 myCompute 的真实地址。而在 64 位中,%rdi 用于存储函数的第一个参数,因此进行了更改。

【讨论】:

  • 在 C++ 中,函数的第一个参数是 this 指针。上面你说你正在使用 CC (Solaris C++ 编译器) - 这是真的还是你真的是指 cc (Solaris C 编译器)?
  • 我正在使用 CC (c++)。我说 C 代码是因为我没有使用 C++ 功能(尽管类方法和存储在结构中的函数指针之间没有太大区别)。你是说 %rdi 持有一个指向 pxFunctions 的指针,它被推送 @myCaller+0x0828 (作为this),并且 0x18(%rdi)是this->pfComputeGeneric的地址?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多