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

Debugging 什么是调试器?它如何帮助我诊断问题?,debugging,language-agnostic,Debugging,Language Agnostic,这是一个通用问题,旨在帮助新程序员解决程序问题,但不知道如何使用调试器诊断问题的原因 本问题包括三类更具体的问题: 当我运行我的程序时,它不会产生我所期望的输入输出 当我运行我的程序时,它崩溃并给我一个堆栈跟踪。我有,但我仍然不知道问题的原因,因为堆栈跟踪没有为我提供足够的信息 当我运行我的程序时,它由于分段错误(SEGV)而崩溃 调试器是一种程序,它可以在程序运行时检查程序的状态。对于理解如何使用调试器的基础知识来说,这些问题并不重要。当程序到达代码中的特定位置时,可以使用调试器停止程序的执

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

本问题包括三类更具体的问题:

  • 当我运行我的程序时,它不会产生我所期望的输入输出
  • 当我运行我的程序时,它崩溃并给我一个堆栈跟踪。我有,但我仍然不知道问题的原因,因为堆栈跟踪没有为我提供足够的信息
  • 当我运行我的程序时,它由于分段错误(SEGV)而崩溃

    • 调试器是一种程序,它可以在程序运行时检查程序的状态。对于理解如何使用调试器的基础知识来说,这些问题并不重要。当程序到达代码中的特定位置时,可以使用调试器停止程序的执行,然后检查程序中变量的值。您可以使用调试器非常缓慢地运行程序,每次运行一行代码(称为单步),同时检查其变量的值

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

      调试器如何帮助您 通过使用调试器,您可以发现变量是否具有错误的值,以及在程序中其值在何处更改为错误的值

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

      关于使用调试器的一般说明 使用调试器的细节取决于调试器,在较小程度上取决于您使用的编程语言

      • 可以将调试器附加到已在运行程序的进程。如果您的程序被卡住,您可能会这样做

      • 实际上,从一开始就在调试器的控制下运行程序通常更容易

      • 您可以通过指示源代码文件和执行应停止的行的行号,或者通过指示程序应停止的方法/函数的名称(如果希望在执行进入方法后立即停止)来指示程序应停止执行的位置。调试器用于使程序停止的技术手段称为断点,此过程称为设置断点

      • Most并为您提供了一个方便的GUI,用于检查程序的源代码和变量,以及一个用于设置断点、运行程序和单步执行程序的点击式界面

      • 除非程序可执行文件或字节码文件包含调试符号信息和对源代码的交叉引用,否则使用调试器可能非常困难。您可能必须确保信息存在。如果编译器执行大量优化,这些交叉引用可能会变得混乱。因此,你可能不得不这样做


        • 我想补充一点,调试器并不总是完美的解决方案,也不应该总是调试的最佳解决方案。以下是调试器可能不适用于您的几种情况:

          • 程序中失败的部分非常大(可能模块化很差?),并且您不确定从何处开始逐步执行代码。一步一步地完成这一切可能太耗时了
          • 您的程序使用了大量回调和其他非线性流控制方法,这会使调试程序在单步执行时变得混乱
          • 您的程序是多线程的。更糟糕的是,你的问题是由比赛条件引起的
          • 有缺陷的代码在出现缺陷之前会运行很多次。这在主回路中可能会特别成问题,更糟糕的是,在物理引擎中,问题可能是数值问题。在这种情况下,即使设置一个断点,也会让您多次命中它,而不会出现错误
          • 您的程序必须实时运行。对于连接到网络的程序来说,这是一个大问题。如果你在网络代码中设置了一个断点,那么另一端就不会等待你通过,它只会超时。依赖于系统时钟的程序,例如带有frameskip的游戏,也不会有太多的好处
          • 您的程序执行某种形式的破坏性操作,如写入文件或发送电子邮件,您希望限制需要运行的次数
          • 您可以判断错误是由到达函数X的不正确值引起的,但您不知道这些值来自何处。必须一次又一次地运行程序,将断点设置得越来越远,这可能是一个巨大的麻烦。特别是如果在整个程序中从多个位置调用函数X
          在所有这些情况下,要么让程序突然停止可能会导致最终结果不同,要么手动搜索导致错误的那一行太麻烦了。无论您的bug是错误行为还是崩溃,这种情况都会发生。例如,如果内存损坏