无法在 gdb 中重现段错误

发布于 2024-11-29 15:34:27 字数 398 浏览 1 评论 0原文

当我运行我的项目时,我遇到了段错误。每次我在 gdb 中运行该程序时,段错误都会消失。这种行为不是随机的:每次我在 shell 中运行它时,它都会出现段错误,每次我在 gdb 中运行它时,段错误都会消失。 (我确实使用-g重新编译)。

因此,在我开始在代码中到处疯狂添加 printfs 之前,我想知道一些事情:

  • 这种行为常见吗?
  • 解决这个问题的最佳方法是什么?

我不知道是否可以编写测试脚本,因为我的应用程序是交互式的,并且会在特定用户输入时崩溃。

我没有将代码粘贴到这里,因为它太长了。但如果有人有兴趣帮忙,这里是: https://github.com/rahmu/Agros

I'm getting segfaults when I run my project. Every time I run the program in gdb, the segfaults disappear. This behavior is not random: each time I run it in my shell it segfaults, each time I run it in gdb, the segfaults disappear. (I did recompile using -g).

So before I start adding printfs frantically everywhere in my code, I would like to know a few things:

  • Is this behavior common?
  • What's the best way to approach the issue?

I don't know if tests can be scripted since my application is interactive and crashes on a particular user input.

I didn't paste my code here because it'd be way too long. But if anyone is interested in helping out, here it is:
https://github.com/rahmu/Agros

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

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

发布评论

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

评论(4

吹梦到西洲 2024-12-06 15:34:27

解决这个问题的最简单方法是捕获核心转储:

$ ulimit -c unlimited

然后运行您的程序。它将生成一个 core 文件

,然后使用 gdb:

$ gdb ./program core

gdb 将加载,您可以运行回溯来准确查看是什么操作引发了段错误。

The easiest way to figure it out is to capture core dumps:

$ ulimit -c unlimited

Then run your program. It will generate a core file

Then use gdb:

$ gdb ./program core

And gdb will load and you can run a backtrace to see exactly what operation elicited the segfault.

爱的那么颓废 2024-12-06 15:34:27

它会进行核心转储吗?以便在调试器中加载核心转储。否则更改代码以使其执行核心转储。

Does it do a core dump? Is so that load up the core dump in the debugger. Otherwise change the code to get it to do a core dump.

最终幸福 2024-12-06 15:34:27

我的猜测是,这是一个并发问题,导致在方法调用下释放引用,假设它所拥有的指针将保持有效。 gdb 屏蔽这一点的原因可能是因为 GDB 只允许 2 个线程实际并发运行。如果您有超过 2 个线程在运行,那么只有 2 个线程会同时主动运行。 GDB 还存在性能问题,这可能会掩盖这一特定情况。正如 Ed 所提到的,只需创建应用程序核心转储,您就可以在 GDB 中打开核心并检查堆栈。

My guess is that it's a concurrency problem causing a reference to be freed out from under a method call that's assuming that the pointer it has will stay valid. The reason that gdb is probably masking this is because GDB only allows 2 threads to actually concurrently run. If you have more than 2 threads running the only 2 will actively run concurrently. GDB also has performance hits which could be masking this specific condition. As mentioned by Ed just make your application core dump and you can open up the core in GDB and check the stack.

罗罗贝儿 2024-12-06 15:34:27

这种行为常见吗?

是的。未定义的行为是大多数此类问题的根源,而且根据定义,它是未定义的。使用 -g 重新编译肯定会影响结果。如果编译器使用某种伪随机遗传算法来优化某些东西或类似的东西,那么重新编译可能会改变结果。

解决该问题的最佳方法是什么?

一分预防胜于大量治疗;了解未定义行为的常见原因并养成良好的习惯以避免编写它们。一旦发现存在问题,对代码进行静态分析通常是一个好主意;仔细检查并推理,证明索引将保持在边界内,数据将适合其数组,无效指针不会被取消引用等。

Is this behavior common?

Yes. Undefined behaviour is the source of most of these problems, and by definition it is undefined. Recompiling with -g may certainly affect the results. Recompiling at all may change the results, if the compiler uses some pseudo-random genetic algorithm to optimize stuff or something like that.

What's the best way to approach the issue?

An ounce of prevention is worth a ton of cure; learn the common causes of undefined behaviour and pick up good habits to avoid writing them. Once you've found that there is a problem, static analysis of the code is often a good idea; go through and reason to yourself and prove that indices will stay in bounds, data will fit its arrays, invalid pointers won't be dereferenced etc.

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