【问题标题】:Why am I getting a seg fault?为什么我会出现段错误?
【发布时间】:2013-02-11 10:58:28
【问题描述】:

在遇到 seg 错误后,我使用了 gdb a.out core 命令。之后我使用了回溯(bt),这就是 gdb 告诉我的

警告:核心文件可能与指定的可执行文件不匹配。

警告:读取 0xfbe8 处的共享库列表条目时出错

警告:读取 0x74c085ff 处的共享库列表条目时出错

核心由“family.out smith.ged”生成。

程序以信号 11 终止,分段错误。

(poundsign)0 0x08086a6 in count_records ()

(gdb) bt

(poundsign)0 0x080486a6 in count_records()

(poundsign)1 0x08048906 in __libc_csu_init ()

(磅符号)2 0xbf85624c in ??()

(磅符号)3 0xbf856310 在 ?? ()

回溯停止:此帧内部的前一帧(损坏的堆栈?)

有人可以告诉我一些可能导致此段错误的原因吗?通常 gdb 会给我程序中的行号,但这次没有。

【问题讨论】:

  • 很有可能您访问了不属于您的内存。除此之外,可能还需要看代码!
  • gdb 输出表明您正在查看由不同二进制文件生成的核心文件。要调试您的应用程序,您可以在 gdb 中运行它(使用“gdb binary”,然后使用“run”命令),或者使用类似 valgrind 的东西。
  • 绝对使用 valgrind 处理段错误。
  • 你用调试信息编译了吗(-g)?
  • 核心转储完成后您是否重新编译过?这将导致可执行文件不匹配。如果是这样,请删除核心并重新运行以获得匹配的核心。

标签: c gcc segmentation-fault


【解决方案1】:

这里可能发生的情况是您损坏了堆栈。程序的许多状态(包括告诉您当前所在函数的所有堆栈帧)都驻留在堆栈中,因此一旦被覆盖,调试器就只能处理损坏的信息。

执行此操作的常见方法是将声明为局部变量的缓冲区溢出为字符串,例如

int main()
{
    char buf[4];
    return func1(buf);
}

int func1(char* theBuf)
{
    return func2(theBuf);
}

int func2(char* sameBufBackSomeplaceInTheStack)
{
     sprintf(sameBufBackSomeplaceInTheStack, "The stack is doomed.");
     return 0;
}

结果可能会有所不同,但在执行此操作后,我销毁的堆栈在调试器中如下所示:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x0000000100000d00 in _mh_execute_header ()
(gdb) where
#0  0x0000000100000d00 in _mh_execute_header ()
#1  0x0000000000000000 in ?? ()
(gdb) 

无论如何,您的程序在某个地方覆盖了堆栈,这通常很难调试...

【讨论】:

    猜你喜欢
    • 2018-01-07
    • 2011-04-23
    • 2013-01-29
    相关资源
    最近更新 更多