首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >什么是调试器?它如何帮助我诊断问题?

什么是调试器?它如何帮助我诊断问题?
EN

Stack Overflow用户
提问于 2014-08-19 21:49:51
回答 2查看 15.3K关注 0票数 124

这是一个通用问题,旨在帮助那些对程序有问题,但不知道如何使用调试器来诊断问题原因的新程序员。

这个问题包括三类更具体的问题:

  • 当我运行我的程序时,它没有为我给它的输入产生我期望的输出。
  • 当我运行我的程序时,它崩溃了,并给我一个堆栈跟踪。我有examined the stack trace,但我仍然不知道问题的原因,因为堆栈跟踪没有为我提供足够的information.
  • When。如果运行我的程序,它会因为分段错误(SEGV)而崩溃。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-19 21:49:51

调试器是一个程序,它可以在程序运行时检查程序的状态。technical means it uses for doing this对于理解如何使用调试器的基础知识并不重要。当程序到达代码中的特定位置时,可以使用调试器暂停程序的执行,然后检查程序中变量的值。在检查程序变量的值时,可以使用调试器以非常慢的速度运行程序,一次运行一行代码(称为单步执行)。

使用调试器是一项预期的基本技能

调试器是帮助诊断程序问题的一个非常强大的工具。所有实用的编程语言都可以使用调试器。因此,能够使用调试器被认为是任何专业或狂热程序员的基本技能。使用自己的调试器被认为是的基本工作你应该自己做,然后再向别人寻求帮助。由于此站点是面向专业和热心的程序员的,而不是帮助台或指导站点,如果您对特定程序的问题有疑问,但没有使用调试器,则您的问题很可能会被关闭或否决。如果你坚持这样的问题,你最终会被阻止发表更多。

调试器如何帮助您

通过使用调试器,您可以发现变量是否具有错误的值,以及在程序中将其值更改为错误的值的位置。

使用单步执行,您还可以发现控制流是否如您所期望的那样。例如,if分支是否在您预期的时间执行。

有关使用调试器的一般说明

使用调试器的细节取决于调试器,在较小程度上还取决于您正在使用的编程语言。

  • 您可以将调试器附加到已在运行程序的进程。如果你的程序被卡住了,你可能会这样做。
  • 在实践中,从一开始就在调试器的控制下运行你的程序通常更容易。
  • 你可以通过指示执行应该停止的源代码文件和行号,或者通过指示程序应该停止的方法/函数的名称(如果你想在执行进入方法时立即停止)来指示程序应该停止执行的位置。调试器用于使程序停止的技术手段称为断点,此过程称为设置断点( breakpoint.
  • Most modern debuggers are part of an IDE ),它为您提供了一个方便的图形用户界面,用于检查程序的源代码和变量,以及用于设置断点、运行程序和单步执行程序的点击式界面。
  • 使用调试器可能非常困难,除非您的程序可执行文件或字节码文件包含调试符号信息和对源代码的交叉引用。您可能需要使用compile (or recompile) your program slightly differently来确保信息存在。如果编译器执行广泛的优化,这些交叉引用可能会变得令人困惑。因此,您可能需要使用recompile your program with optimizations turned off.
票数 83
EN

Stack Overflow用户

发布于 2015-04-05 20:15:45

我想补充的是,调试器并不总是完美的解决方案,也不应该总是调试的首选解决方案。以下是调试器可能无法为您工作的几种情况:

  • 您的程序中失败的部分非常大(也许模块化不好?)并且您不能确切地确定从哪里开始逐步执行代码。time-consuming.
  • Your程序使用了大量的回调和其他非线性的流控制方法,这会在你单步执行时使调试器感到困惑。
  • 你的程序是多线程的。或者更糟糕的是,你的问题是由竞态条件引起的。
  • 有bug的代码在bug出来之前运行了很多次。这在主循环中可能特别有问题,或者更糟糕的是,在物理引擎中,问题可能是数值问题。在这种情况下,即使设置断点,也只会让您多次点击断点,而不是appearing.
  • Your程序必须实时运行。对于连接到网络的程序来说,这是一个大问题。如果您在网络代码中设置了断点,另一端不会等待您单步执行,它只会超时。依赖系统时钟的程序,比如使用frameskip的游戏,也好不到哪里去。
  • 你的程序会执行某种形式的破坏性操作,比如写入文件或发送电子邮件,而你想要限制运行它的次数。
  • 你可以说你的bug是由到达函数X的不正确值引起的,但你不知道这些值来自哪里。必须一遍又一遍地运行程序,将断点设置得越来越远,这可能是一个巨大的麻烦。尤其是当在整个程序中从许多地方调用函数X时。

在所有这些情况下,要么突然停止您的程序可能导致最终结果不同,要么手动逐步搜索导致bug的一行太麻烦了。无论你的bug是不正确的行为,还是崩溃,都同样会发生这种情况。例如,如果内存损坏导致崩溃,那么当崩溃发生时,它离第一次发生内存损坏的地方太远了,并且没有留下任何有用的信息。

那么,有什么替代方案呢?

最简单的就是日志和断言。在不同的时间点将日志添加到您的程序中,并将您得到的结果与您期望的结果进行比较。例如,看看你认为有bug的函数是否会在第一时间被调用。查看方法开头的变量是否如您所想的那样。与断点不同的是,可以有许多日志行,其中没有什么特别的事情发生。之后,您可以简单地搜索日志。一旦你遇到了一个不同于你期望的日志行,在相同的区域添加更多。越来越远地缩小范围,直到它小到能够记录be区域中的每一行。

断言可用于在不正确的值出现时捕获它们,而不是在它们对最终用户可见时捕获它们。捕获不正确的值越快,就越接近产生它的行。

重构和单元测试。如果您的程序太大,那么一次测试一个类或一个函数可能是值得的。给它输入,并查看输出,看看哪些不是你所期望的。能够将bug的范围从整个程序缩小到单个函数,这将大大缩短调试时间。

在发生内存泄漏或内存践踏的情况下,使用能够在运行时分析和检测这些情况的适当工具。能够检测到实际发生损坏的位置是第一步。在此之后,您可以使用日志返回引入不正确值的位置。

请记住,调试是一个倒退的过程。你得到了最终的结果--一个bug --并找到了它之前的原因。它是关于向后工作的,不幸的是,调试器只向前一步。这就是好的日志记录和事后分析可以为您提供更好的结果的地方。

票数 51
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25385173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档