【问题标题】:How do I know which illegal address the program access when a segmentation fault happens发生分段错误时如何知道程序访问哪个非法地址
【发布时间】:2011-02-18 12:57:37
【问题描述】:

另外,该程序运行在运行 Linux 的 arm 设备上,我可以在我分配的 sig-seg 处理程序中打印出堆栈信息和寄存器值。 问题是我无法在源文件中添加 -g 选项,因为由于性能下降,该错误可能不会重现。

【问题讨论】:

  • 至少使用 GCC 您可以添加 -g 而不会禁用优化。在 ELF 目标上,GCC 将调试信息放入单独的部分,因此在需要之前它们甚至不会从磁盘加载。

标签: c linux embedded segmentation-fault


【解决方案1】:

-g 选项编译为gcc 不会不会导致“性能降级”。它所做的只是导致包含调试符号;它确实影响优化或代码生成。

如果使用传递给sigaction()sigaction 结构的sa_sigaction 成员安装SIGSEGV 处理程序,则传递给处理程序的siginfo_t 结构的si_addr 成员包含错误地址。

【讨论】:

  • 我遇到过由写入未初始化指针引起的段错误出现和消失的问题,具体取决于我是否使用了 -g 或我拥有的 -o 级别。这与内存在哪里有关。同样,我也遇到过添加或删除 printf 导致错误出现的地方。 C 中的段错误可能是狡猾的混蛋。
【解决方案2】:

我倾向于使用valgrind,它表示泄漏和内存访问错误

【讨论】:

  • valgrind 适用于 X86、AMD64 和 PPC - 提问者在 ARM 上运行。不过,我很惊喜地看到 ARM 支持正在进行中。
  • @crazyscot 我确实错过了问题的“手臂”部分。但很高兴知道 valgrind 即将支持这种架构;)
【解决方案3】:

这似乎有效 http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV

static void signal_segv(int signum, siginfo_t* info, void*ptr) {
// info->si_addr is the illegal address
}

【讨论】:

  • info->si_addr 是错误的内存地址。如您提供的链接中所述,发出信号时的地址可以从void * ptr 检索。在此处查看我在 ARM 上使用的代码的答案 - stackoverflow.com/questions/77005/…
【解决方案4】:

如果您担心在设备上加载的二进制文件上使用 -g,您可以在 ARM 设备上使用带有剥离版本的可执行文件的 gdbserver,并在您的开发机器上使用可执行文件的未剥离版本。剥离版本和未剥离版本需要匹配才能做到这一点,所以这样做:

# You may add your own optimization flags
arm-gcc -g program.c -o program.debug 
arm-strip --strip-debug program.debug -o program
# or
arm-strip --strip-unneeded program.debug -o program

您需要阅读 gdb 和 gdbserver 文档以了解如何使用它们。这并不难,但它并没有达到应有的水平。主要是很容易不小心告诉 gdb 做一些它最终认为你打算在本地做的事情,所以它会退出远程调试模式。

【讨论】:

    【解决方案5】:

    如果可用,您可能还想使用 backtrace() 函数,该函数将在崩溃时提供调用堆栈。当 C 程序出现分段错误、总线错误或其他内存违规错误时,这可用于转储堆栈,就像在高级编程语言中发生的那样。

    backtrace() 在 Linux 和 Mac OS X 上都可用

    【讨论】:

      【解决方案6】:

      如果 -g 选项使错误消失,那么知道它崩溃的位置无论如何都不太可能有用。它可能正在写入函数 A 中未初始化的指针,然后函数 B 尝试合法地使用该内存,然后死掉。内存错误很痛苦。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多