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

发布于 2024-12-05 20:09:35 字数 145 浏览 9 评论 0原文

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

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

My program crashes with a segmentation fault when ran normally. So I run it with GDB, but it won't crash when I do that. Why might this occur?

I know that Valgrind's FAQ mentions this (not crashing under Valgrind), but I couldn't really find anything about this related to GDB in Google.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

淡莣 2024-12-12 20:09:35

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

我的建议是设置环境来创建核心转储,然后在程序崩溃后使用 GDB 来调查核心转储。在 Bash 中,这是通过 ulimit -c size 完成的,其中 size 可以是任何值;我个人使用 50000 表示最大大小为 25 MB;单位以 512 字节为增量。

您可以使用 GDB 通过使用 gdb program core 来调查核心转储。

I've had this happen to me before (you're not alone), but I can't remember what I did to fix things (I think it was a double free).

My suggestion would be to set up your environment to create core dumps, and then use GDB to investigate the core dump after the program crashes. In Bash, this is done with ulimit -c size, where size can be anything; I personally use 50000 for 25 MB max size; the unit is in 512-byte increments.

You can use GDB to investigate a core dump by using gdb program core.

爱给你人给你 2024-12-12 20:09:35

听起来像是您那里的 Heisenbug :-)

如果您正在使用的平台是能够产生core文件,应该可以利用core文件和GDB来定位程序崩溃的位置。可以在此处找到简短说明。

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

It sounds like a Heisenbug you have there :-)

If the platform you're working with is able to produce core files, it should be possible to use the core file and GDB to pinpoint the location where the program crashes. A short explanation can be found here.

Let it crash a couple of times though. When the crash is caused by stack smashing or variable overwriting, the bug may seem to "walk around".

奈何桥上唱咆哮 2024-12-12 20:09:35

尝试附加到 gdb 中正在运行的进程,继续,然后重现崩溃。换句话说,不要在 gdb 中启动程序;相反,正常启动程序,然后附加

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

Try attaching to the running process within gdb, continuing, and then reproducing the crash. In other words, don't start the program within gdb; instead, start the program normally and then attach <pid>.

Sometimes when stepping through lines individually, a race condition that causes the program to crash will not manifest, as the race hazard has been eliminated or made exceedingly improbable by the "lengthy" pauses between steps.

云仙小弟 2024-12-12 20:09:35

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

Well I tracked it down to a pthread_detach call. I was doing pthread_detach(&thethread). I just took away the reference and changed it to pthread_detach(thethread) and it worked fine. I'm not positive, but maybe it was a double free by detaching the reference then destroying it again when it went out of scope?

泛泛之交 2024-12-12 20:09:35

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

If a bug depends on timing, GDB could prevent it from repeating.

潇烟暮雨 2024-12-12 20:09:35

检查 pthread_detach 调用的返回值。根据你的答案,你可能传递了一个无效的线程pthread_detach 的句柄。

Check for the return value of the pthread_detach call. According to your answer, you are probably passing an invalid thread handle to pthread_detach.

甩你一脸翔 2024-12-12 20:09:35

我有时也遇到过这种情况。

我的解决方案:清洁和清洁重建一切。

我并不是说这总能解决所有问题(在OP的情况下,问题是确实错误的),但是如果您在遇到这种情况时首先这样做,您可以节省一些麻烦和时间。奇怪的“元”错误。

至少根据我的经验,这些东西往往来自于应该重建但没有重建的旧目标文件。在 MinGW 和常规 GCC 中。

I also had this happen to me sometimes.

My solution: clean & rebuild everything.

I am not saying that this always solves all problems (and in the OP's case, the problem was something really wrong), but you can save yourself some trouble and time if you do this first when encountering such really weird "meta" bugs.

At least in my experience, such things more often than not come from old object files that should have been rebuilt, but were not. In both MinGW and regular GCC.

零度℉ 2024-12-12 20:09:35

我遇到了类似的问题,其中一个线程被随机终止,并且未创建核心转储。当我附加 GDB 时,问题不会重现。

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

I faced a similar issue, where a thread was killed randomly, and a core dump was not created. When I attached GDB, the issue wouldn't reproduce.

To answer your question of why this is happening, I think this is timing issue. Since GDB will collect some data related to thread execution, it might slow down the process execution speed. If thread execution is slow issue, it isn't reproducing.

甚是思念 2024-12-12 20:09:35

我刚刚遇到了类似的问题。就我而言,它连接到我的链表数据结构中的指针。当我动态创建一个新列表而不初始化结构内的所有指针时,我的程序在 GDB 外部崩溃。

以下是我的原始数据结构:

typedef struct linked_list {
    node *head;
    node *tail;
} list;

typedef struct list_node {
    char *string;
    struct list_node *next;
} node;

当我创建一个新的列表“实例”并指定其头部和尾部时,程序在 GDB 之外崩溃了:

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;
}

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

I just had a similar problem. In my case, it was connected to pointers in my linked list data structure. When I dynamically created a new list without initializing all the pointers inside the structure my program crashes outside GDB.

Here are my original data structures:

typedef struct linked_list {
    node *head;
    node *tail;
} list;

typedef struct list_node {
    char *string;
    struct list_node *next;
} node;

When I created a new "instance" of a list specifying its head and tail, the program crashed outside GDB:

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

    return newList;
}

Everything started to work normally after I changed my createList function to this:

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

    newList->head = (node *) 0;
    newList->tail = (node *) 0;

    return newList;
}

I hope it might help to someone in case of something similar to my example with non-initialized pointers.

笑叹一世浮沉 2024-12-12 20:09:35

gdb 中调用 set disable-randomization off 为我解决了这个问题。

Calling set disable-randomization off in gdb fixed this issue for me.

余罪 2024-12-12 20:09:35

当您使用 GDB 运行代码时,它会四处移动。现在,您之前尝试引用的非法地址(导致段错误的地址)突然合法了。这肯定是一种痛苦。

但我知道追踪这种错误的最好方法是开始 输入 printf()到处都是,逐渐缩小范围。

When you run your code with GDB, it gets moved around. Now the illegal address you tried to reference before—the one that caused the segfault—is legal all of a sudden. It's a pain, for sure.

But the best way I know of to track down this kind of error is to start putting in printf()s all over the place, gradually narrowing it down.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文