这是一个通用的问题,旨在帮助那些在程序中遇到问题但不知道如何使用调试器来诊断问题原因的新程序员。
这个问题涵盖了三类更具体的问题:
- 当我运行我的程序时,它没有产生我所期望的输出。
- 当我运行我的程序时,它崩溃并给我一个堆栈跟踪,我有examined the stack trace,但我仍然不知道问题的原因,因为堆栈跟踪没有给我提供足够的信息。
- 当我运行我的程序时,它由于分段错误(SEGV)而崩溃。
这是一个通用的问题,旨在帮助那些在程序中遇到问题但不知道如何使用调试器来诊断问题原因的新程序员。
这个问题涵盖了三类更具体的问题:
2条答案
按热度按时间e0uiprwp1#
A debugger is a program that can examine the state of your program while your program is running. The technical means it uses for doing this are not necessary for understanding the basics of using a debugger. You can use a debugger to halt the execution of your program when it reaches a particular place in your code, then examine the values of the variables in the program. You can use a debugger to run your program very slowly, one line of code at a time (called single stepping), while you examine the values of its variables.
Using a debugger is an expected basic skill
A debugger is a very powerful tool for helping diagnose problems with programs. And debuggers are available for all practical programming languages. Therefore, being able to use a debugger is considered a basic skill of any professional or enthusiast programmer. And using a debugger yourself is considered basic work you should do yourself before asking others for help. As this site is for professional and enthusiast programmers, and not a help desk or mentoring site, if you have a question about a problem with a specific program, but have not used a debugger, your question is very likely to be closed and downvoted. If you persist with questions like that, you will eventually be blocked from posting more.
How a debugger can help you
By using a debugger you can discover whether a variable has the wrong value, and where in your program its value changed to the wrong value.
Using single stepping you can also discover whether the control flow is as you expect. For example, whether an
if
branch executed when you expect it ought to be.General notes on using a debugger
The specifics of using a debugger depend on the debugger and, to a lesser degree, the programming language you are using.
o0lyfsai2#
我想补充的是,调试器并不总是完美的解决方案,也不应该总是调试的首选解决方案。下面是调试器可能不适合你的几种情况:
在所有这些情况下,要么让程序突然停止可能导致最终结果不同,要么手动单步执行以查找导致bug的行太麻烦了。无论bug是错误行为还是崩溃,这都可能发生。例如,如果内存损坏导致崩溃,那么在崩溃发生时,它离内存损坏第一次发生的位置太远,没有留下任何有用的信息。
那么,还有什么选择呢?
最简单的方法就是记录日志和Assert。在程序的不同点添加日志,并将得到的结果与预期的结果进行比较。例如,查看您认为存在bug的函数是否在第一时间被调用。查看方法开始处的变量是否与您所认为的一样。与断点不同的是,有很多日志行没有发生什么特别的事情是可以的。您可以在以后简单地搜索日志。一旦您找到了与预期不同的日志行,就在同一区域添加更多的日志行。将范围越缩小越好,直到它小到可以记录被窃听区域的每一行。
Assert可用于在错误值出现时捕获错误值,而不是在它们对最终用户产生可见影响时捕获错误值。捕获错误值越快,就越接近产生它的行。
重构和单元测试。如果你的程序太大,一次测试一个类或一个函数可能是值得的。给予它输入,看看输出,看看哪些不是你所期望的。能够把bug从整个程序缩小到单个函数,可以在调试时间上有很大的不同。
在内存泄漏或内存践踏的情况下,使用适当的工具,能够分析和检测这些在运行时。能够检测到实际损坏发生的位置是第一步。在这之后,您可以使用日志工作的方式回到哪里引入了不正确的值。
请记住,调试是一个向后的过程。你有最终的结果--一个bug --并找到它之前的原因。这是关于你向后工作的方式,不幸的是,调试器只向前走。这是好的日志和事后分析可以给予你更好的结果。