Linux和Solaris Unix:函数末尾的Coredump [关闭]

Posted

技术标签:

【中文标题】Linux和Solaris Unix:函数末尾的Coredump [关闭]【英文标题】:Linux and Solaris Unix : Coredump at the end of a function [closed] 【发布时间】:2011-08-15 21:16:48 【问题描述】:

我们在高负载条件下非常随机地观察到核心转储。当我们加载核心文件并查看核心转储的位置时,它总是指向函数的最后一行,即右大括号的行号。

该函数有一些遗留的 goto 语句。当我们之前遇到类似问题时,我们将所有本地对象的创建移到函数的顶部,这似乎已经解决了 Solaris Unix 10 上的问题。(我们的怀疑和一些示例测试表明,当执行 goto 语句时,一些这些局部变量从未被创建,但它们的析构函数总是被调用。因此将它们一直移动到顶部确保它们总是被正确构造)。但是这个问题在 Linux 上仍然存在,而我们在 Solaris 上看不到这个问题了。

更新了堆栈跟踪:

#0  0x008a5206 in raise () from /lib/libc.so.6

#1  0x008a6bd1 in abort () from /lib/libc.so.6

#2  0x008de3bb in __libc_message () from /lib/libc.so.6

#3  0x00966634 in __stack_chk_fail () from /lib/libc.so.6

#4  0x08e9ebf5 in our_function (this=0xd2f2c380)

    at sourcefilename.cc:9887

有人遇到过类似的问题吗?非常感谢任何帮助或指示来理解和解决问题。万分感谢。

【问题讨论】:

也许你可以提供一些代码来显示发生了什么? 简单,你有可能破坏堆栈帧的错误,所以当你返回时它会崩溃。我建议使用 Valgrind 进行检测,但如果没有实际代码,我们将无能为力。 C++ 有一条规则,即 goto 不能跳过对象的构造,这正是您概述的原因。因此,如果您有执行此操作的代码,则不应编译。在我看来,通过移动东西只是掩盖了真正的问题,但没有看到任何可以确定的代码。 C++ 中 ctors 和 goto 的一些背景知识,***.com/questions/6537948/… 我知道如果我可以发布代码,它可能有助于查看问题。但它专有的 3rd 方库代码,所以我将无法发布它。顺便说一下,这个函数差不多有 2000 行,并且调用了很多其他的对象和函数。 【参考方案1】:

我怀疑您在向下增长的堆栈中超出了缓冲区(大多数堆栈向下增长;我不知道 Linux 或 Solaris 是否在所有体系结构上都使用向下堆栈,但肯定​​是其中一些)。此时,它会覆盖返回地址,并且程序计数器会跳转到一个非法地址,从而在函数返回的确切位置产生崩溃。

只需 Valgrind 它,它可能会告诉你发生了什么(或者更确切地说,溢出在哪里)。

【讨论】:

谢谢马克。将审查代码并尝试使用 valgrind 来看看我们能收集到什么。我发布了堆栈跟踪。 __stack_chk_fail 根据文档指示缓冲区溢出。 我们无法使用 valgrind 运行,但我们从覆盖率静态分析报告中发现我们正在覆盖函数中本地创建的数组。我们修复了数组大小问题,这个问题现在已经消失了。非常感谢。 我们在编译时使用了 -fstack-protector 选项,这会强制内核溢出。如果没有这个选项,我们就不会强制核心转储。我们在有和没有这个选项的情况下运行了测试。此处有关此选项的一些说明:GCC extension for protecting applications from stack-smashing attacks

以上是关于Linux和Solaris Unix:函数末尾的Coredump [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在Sun Unix solaris 下安装Oracle8i 最好能给完整的安装步骤

如何在unix下安装软件

Unix,BSD,Solaris和Mac OS X的故事

Solaris、HP-UX、IBM-AIX 等平台是不是支持 Unix 域套接字而无需套接字文件,如 Linux?

Unix 迁移到Linux 该怎么做?

linux笔记