1

我有一个问题,在 linux 下运行的 C++ 程序,用 g++ 编译一段时间后引发非法指令异常,我得到一个核心转储。当我使用 gdb 进行回溯时,我得到

(gdb) bt
#0  0x005e18cf in ATL_dpotrfL () from /usr/lib/liblapack.so.3gf
#1  0x00000001 in ?? ()
#2  0xb786f2e8 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

我不知道为什么回溯中没有 main 。这 ??似乎是我的 linux 库的一部分,其中没有调试符号。

我现在的问题是:程序有什么问题?库 lapack 是否编译错误(我前几天编译的)?还是有其他错误?

我做了 definitfly 没有汇编程序或类似的事情。只有 C++。

谢谢克里斯蒂安

4

3 回答 3

7

这通常意味着粉碎堆栈。特别是 0x00000001 的值,这该死的不太可能是有效的堆栈地址,所以我会说您溢出了堆栈分配的缓冲区并覆盖了返回地址。

于 2011-08-08T11:19:37.633 回答
2

正如其他人所说,您可能已经搞砸了。

最常见的原因是:

  • 在错误的指针上写(已删除)
  • 在指定空间之外书写
  • 在堆栈上声明大量本地数据

找到原因的神奇方法是:

valgrind  your_program  [args]

(只需在您通常启动的命令前添加“valgrind”。如果此处尚未安装 valgrind,则必须在您的发行版中为它提供一个数据包,因为它是一种广泛使用的工具。)

然后 valgrind 将在程序运行时检查您的程序(稍微减慢它),并在不应该写入的地方(例如,在堆栈上)立即报告您

于 2011-08-08T13:21:40.820 回答
2

DeadMG 所说的,加上:

非法指令通常是编译为使用正在运行的机器上不可用的 CPU 指令的二进制文件的结果。例如,如果您像这样编译,可能会发生这种情况

g++ -msse4 ...

然后在不支持 SSE4 指令集的 Intel Atom CPU 上运行这个东西。崩溃不一定会发生,例如不太可能发生

int main () {}

同时导致生成 SSE4 指令。当然对于不可能的代码路径也是如此,现在可能不会导致崩溃,但在将来。

要查找堆栈粉碎代码,您可以考虑使用类似cppcheck 或类似的 LINT 、Valgrind、以分而治之的方式进行良好的旧 printf/cout 调试,或者使用经过检查的 STL 实现。

于 2011-08-08T11:31:07.177 回答