正常崩溃,但使用 GDB 时不会崩溃

问题描述 投票:0回答:10

我的程序在正常运行时因分段错误而崩溃。所以我用 GDB 运行它,但是当我这样做时它不会崩溃。为什么会出现这种情况?

我知道 Valgrind 的 FAQ 提到了这一点(在 Valgrind 下不会崩溃),但我在 Google 中找不到任何与 GDB 相关的内容。

crash gdb segmentation-fault
10个回答
16
投票

我以前也遇到过这种情况(你并不孤单),但我不记得我做了什么来解决问题(我认为这是双重免费)。

我的建议是设置环境来创建核心转储,然后在程序崩溃后使用 GDB 来调查核心转储。在 Bash 中,这是通过

ulimit -c size
完成的,其中 size 可以是任何值;我个人使用 50000 来表示最大大小为 25 MB;单位以 512 字节为增量。

您可以使用 GDB 通过使用

gdb program core
来调查核心转储。


9
投票

听起来像 Heisenbug 你那里有:-)

如果您使用的平台能够生成核心文件,则应该可以使用核心文件和 gdb 来查明程序崩溃的位置 - 可以在此处找到简短说明。

让它崩溃几次,当崩溃是由堆栈粉碎或变量覆盖引起时,错误可能看起来“四处走动”。


4
投票

尝试附加到

gdb
内正在运行的进程,继续,然后重现崩溃。换句话说,不要在
gdb
内启动程序;相反,正常启动程序,然后
attach <pid>

有时,当单独单步执行各行时,导致程序崩溃的竞争条件不会显现出来,因为步骤之间的“长时间”暂停已经消除了竞争危险,或者使竞争变得极不可能。


3
投票

我追踪到了 pthread_detach 调用。我正在做 pthread_detach(&thethread)。我只是拿走了引用并将其更改为 pthread_detach(thethread) 并且工作正常。我不确定,但也许通过分离引用然后在超出范围时再次销毁它来实现双重释放?


1
投票

检查

pthread_detach
调用的返回值。根据您的回答,您可能正在将无效的线程句柄传递给
pthread_detach


1
投票

如果错误取决于时间,GDB 可以防止它重复出现。


0
投票

我也遇到过这种情况。

我的解决方案:清理并重建一切。

并不是说这总是能解决所有问题(在OP情况下,问题是一些“真的”错误),但是如果你在遇到如此奇怪的“元”错误时首先这样做,你可以节省一些麻烦和时间。至少根据我的经验,这些东西往往来自于应该重建但没有重建的旧目标文件。在 MinGW 和常规 GCC 中。


0
投票
GDB


这是我原来的数据结构:

typedef struct linked_list { node *head; node *tail; } list; typedef struct list_node { char *string; struct list_node *next; } node;

当我创建 
list

的新“实例”并指定其

head
tail
时,程序在
DGB
之外崩溃了:

list *createList(void) { list *newList = (list *) malloc(sizeof(list)); if (newList == NULL) return; return newList; }

在我将 
createList

功能更改为以下内容后,一切开始正常工作:


list *createList(void) { list *newList = (list *) malloc(sizeof(list)); if (newList == NULL) return; newList->head = (node *) 0; newList->tail = (node *) 0; return newList; }

希望它对遇到与我的未初始化指针示例类似的情况的人有所帮助。


0
投票

为了回答你为什么会发生这种情况的问题,我认为这是计时问题,因为gdb会收集一些与线程执行相关的数据,这可能会减慢进程的执行速度。如果线程执行缓慢,则问题不会重现。


-3
投票

© www.soinside.com 2019 - 2024. All rights reserved.