需要有关 Seg 故障调试的建议
我正在开发这个在 Linux 中运行的旧 C++ 程序。这是我读过的最糟糕的代码,用 ValGrind 运行它会带来大量的内存问题。
我想一一剔除段错误,但是当 ValGrind 找到该行时,代码因损坏已经造成而崩溃。该代码使用第三方库以及本地库。第三方库可以信任,但国产库则不可信。
有人对如何查找导致段错误的内存损坏有任何建议吗?我从来没有必要在别人的代码中查找段错误,尤其是在没有文档的情况下发布的代码。
我今天发现的两件事是,编译器设置已更改为“不自动初始化”。值和字大小从 32 位更改为 64 位。
我束手无策,试图取得任何进展,有人有任何深度记忆分析的想法吗?
谢谢
I am working on this old c++ program that runs in Linux. It is the worst code I had ever tried to read, and running it with ValGrind gives tons of memory problems.
I want to pick off the seg faults one by one, but by the time ValGrind finds the line the code crashes on the damage has been done. This code uses third party libraries as well as home grown libraries. The third party libs can be trusted but not the home grown.
Does anyone have any suggestions on how to find memory corruption that causes a seg fault? I have never had to find seg faults in someone else's code, especially code that was released with no documentation.
Two things that I found out today was, the compiler settings were changed to NOT automatically init. values and the word sized changed from 32 to 64 bit.
I'm at my witts end trying to make any headway, anyone have any deep memory analysis ideas?
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
GDB是一个很好的建议。您还可以使用
ulimit unlimited
(手册页)来获取系统当程序崩溃时转储核心文件。也就是说,在处理内存错误时,这些工具为您提供的信息可能会产生误导。内存损坏可能会导致程序在与问题根源无关的随机位置崩溃。如果您发现自己在查看核心转储或 GDB 输出并想知道程序如何可能进入该状态,那么很可能就是这样。
在这种情况下,valgrind 是你最好的朋友。只需从内存错误列表的顶部开始,一次修复一个错误(我的意思是修复一个错误,然后重新运行,然后修复下一个错误,依此类推;这是因为修复一个错误通常会消除许多其他错误) )直到他们全部消失。那么你的程序要么会更加稳定,要么你的工具将再次为你提供有用的信息。
GDB is a good suggestion. You can also use
ulimit unlimited
(man page) to get the system to dump core files when your program crashes.That said, the information these tools give you may be misleading when dealing with memory errors. Memory corruption can cause the program to crash in a random place that has little to do with the source of the problem. If you find yourself looking at core dumps or GDB output and wondering how the program could have possibly gotten into that state, it's likely this is what's going on.
In such cases, valgrind is your best friend. Just start at the top of its list of memory errors and fix them one at a time (by which I mean fix one, then rerun, then fix the next, and so on; this is because fixing one error often gets rid of many others) until they're all gone. Then your program will either be more stable or your tools will give you useful information again.
Gdb 可能是比 valgrind 更好的选择;当您的应用程序(在 gdb 下运行)收到 SIGSEGV 时,gdb 将停止执行并生成堆栈跟踪,列出到目前为止已调用的函数,并将保留程序内存的状态以供您细读。您需要使用调试信息(gcc 中的 -g)构建应用程序才能使其正常工作。即使无法重建库,保留程序内存也可能会有很大帮助。
Gdb is probably a better choice than valgrind; when your application (running under gdb) receives a SIGSEGV, gdb will halt execution and generate a stack trace, listing what functions have been called up to that point, and will preserve the state of your program's memory for your perusal. You'll need to build your application with debugging information (-g in gcc) for this to work. Even if the libraries can't be rebuilt, the preservation of the memory of the program will probably be a big help.
调试内存损坏的最简单方法是在损坏发生后尽早捕获它,最好是在准确的时间 - 这将使您能够看到哪个线程和方法出了问题。
一般来说,损坏是难以捉摸的,因为故障仅在损坏后一段时间才会发生。 Valgrind 和其他工具旨在通过采用一些检查来确保捕获缓冲区溢出和其他覆盖,从而帮助尽早捕获损坏。
尝试查看用户指南,或者尝试其他工具,看看是否可以在损坏附近强制崩溃或断点。
也就是说,在自然崩溃点使用调试器可以揭示有关损坏内存的信息,但有时这可能是一个艰难的过程。如果像 valgrind 这样的工具不能解决问题,或者导致性能低得令人无法接受,那么它们的价值是无价的。
The easiest way to debug memory corruption is to catch the corruption as early as possible after it happens, preferably at the exact time - this will allow you to see which thread and method is at fault.
Generally corruption is elusive because failures only occur some time after the damage. Valgrind and other tools are intended to help capture corruption earlier by employing some checks to make sure that buffer overflows and other overlays are caught.
Try looking through the user guides, or try alternative tools to see if you can force a crash or breakpoint close to the corruption.
That said, using a debugger at the natural crash point can reveal information about the corrupted memory, but sometimes it can be a hard slog. Tools like valgrind are invaluable if they don't cause the problem to go away, or cause unacceptably low performance.
查看是否可以在内存分配器中启用调试功能。 glibc 的 malloc 实现确实有一些可以以某种方式启用的健全性检查。
我曾经遇到过一个案例(在具有简单的基于链的 malloc 的嵌入式系统上),其中应用程序覆盖了所使用的内存分配器的内部数据结构 - 导致内存分配上出现零星的段错误。
See if you can enable debugging features in the memory allocator. glibc's malloc implementation does have some sanity checks which can somehow be enabled.
I once had a case (on an embedded system with a simple chain-based malloc) where the application overwrote the internal data structures of the memory allocator used - resulting in sporadic segfaults on memory allocations.
谢谢大家,不知道该归功于谁,但是 valGrind 发现了我的问题,似乎代码在需要它们的保存操作之前删除了对象。我花了一点时间才得到 valgrind 的输出,但它已经死在哪里出了问题。
Thanks everyone, not sure who to give credit to, but valGrind found my problem, seems the code was deleting objects before the save operation which needed them. It took me a little but to get the output for valgrind but it was dead on what was wrong.