代码之家  ›  专栏  ›  技术社区  ›  Chris Jefferson

你最好的调试提示是什么?

  •  9
  • Chris Jefferson  · 技术社区  · 17 年前

    对于你最喜欢的语言,你认为每个人都应该使用哪些专家调试提示?

    作为一个例子,我将提供我的C++调试提示,这些提示可以帮助我摆脱我在这种通常难以调试的语言中遇到的大多数错误。

    C

    • 将编译器的警告级别提高到最大,然后停止那些经常发生并且你已经决定不关心的警告(对我来说,这是未使用的参数)。g++在警告级别非常高之前不会警告函数中缺少返回语句(我经常发现这个问题)。

    • 学习如何打开编译器的调试标准库,并使用它!(g++为-D_GLIBCXX_DEBUG)。这会发现很多错误,也有助于准确显示错误发生的位置。

    • 总是,总是,总是通过一个非常好的内存检查器运行你的代码,比如 valgrind ,并解决它产生的所有问题。

    8 回复  |  直到 17 年前
        1
  •  5
  •   Magnus Westin    17 年前

    了解VS内存处理程序在处理内存时写入的不同幻数意味着什么。

    0xCDCDCDCD已在堆中分配,但尚未初始化。通过malloc
    0xCCCCCCCC已在堆栈上分配,但尚未初始化。
    0xDDDDDDDD释放堆内存。通过免费
    0xFDFDFDFD“NoMansLand”围栏自动放置在堆内存的边界。永远不应该被覆盖。如果你确实覆盖了一个数组,你可能会走到数组的末尾。
    0xFEEEFEEE HeapFree已删除内存
    0xBAADF00D已在堆中分配,但尚未初始化。By HeapAlloc
    0xABABABAB不知道。如果有人知道这意味着什么,请补充一下。

        2
  •  2
  •   Timo Geusch    17 年前

    我自己的几次,因为花了太多时间调试编译器或运行时环境可能会警告我的东西,如果我正确使用的话:

    • 如果你在用C++中的指针做任何事情,只要合适,就断言()它们。事实上,断言()不变量通常是一个好主意,可以将一个模糊bug的调试时间从几周缩短到几分钟。只需记住在发布版本中关闭它们。哦,不要放任何有副作用的东西,否则你将调试你的发布版本一段时间。别问我是怎么知道的
    • 同样,BOOST_STATIC_ASSERT在检查编译时可以检查的差异方面非常有帮助
    • 内存调试器,如 PurifyPlus valgrind 是非常节省时间的设备,应该安装在每个开发人员的机器上
    • 了解如何正确使用调试器,以便充分利用其功能,而不仅仅是将其用作允许您单步执行代码的设备
    • 如果你真的卡住了,向同事解释问题和代码
    • 对于C++,一个类似 FlexeLint/PC-Lint 一旦你正确配置了它,它可以帮助你找出很多很难找到的东西。你必须投入时间来配置它,否则你会淹没在警告中
    • 如果你正在编写C++并使用标准容器,那么编写使用迭代器的代码,让运行时的调试版本(或调试STL)通过一个错误来抓住你。如果你使用索引来引用std::vector中的元素<>你得自己去找
    • 如果可以的话,通过不同的编译器运行代码,并注意每个编译器产生的警告。但是,请确保它们处于类似的语言兼容性水平(通过MS VC++6运行现代C++代码没有意义),否则你最终会遇到不存在的问题。

    理想情况下,您应该在需要启动调试器之前尝试捕捉问题——与在调试器中跟踪并修复它相比,任何可以调整以创建编译错误的东西都更容易修复。

        3
  •  1
  •   Magnus Westin    17 年前

    始终在您的手表窗口中显示“err,hr”。我将显示调用GetLastError得到的结果。当你遍历代码时,它会动态更新。

        4
  •  1
  •   Josephine Josephine    17 年前

    我的调试(PHP)主要包括对(密码,IP锁定)页面最后一行的添加:

    echo '<pre>'; print_r($GLOBALS); echo '</pre>';
    

    如果问题不在那里,你可以“正确”调试,但十有八九它会从那里跳出来。

        5
  •  0
  •   Stephen Darlington    17 年前

    不确定这是否算作调试,但对于C和Objective-C代码,我发现 LLVM/Clang Static Analyzer 是无价的。甚至在你看到它们的影响之前,帮助发现错误、内存泄漏和逻辑错误。

        6
  •  0
  •   user38329    17 年前

    在Visual C++调试器中,您经常发现自己处于内联单行函数中,无法进入并查看其本地函数。例如:

      class foo
      {
         int bar() { int i = func1(); int j = func2(i); return j; }
      };
    

    要显示i的值,您需要一个堆栈帧。但是调试器不会进入bar()并显示i的内容。

    这里的诀窍是在调试器中启用内联汇编。这扩展了函数的处理器指令,现在这些指令不止一行。现在,您可以进入函数并查询变量。

    也许还有另一种方法:)

        7
  •  0
  •   ajs410    16 年前

    偶尔运行发布版本,而不是调试版本。有些bug只有在启用优化时才会发生。

        8
  •  -1
  •   Hazel    16 年前

    我对此没有参考,但我被告知0xABABABAB地址意味着“超出分配内存范围的内存”。希望它能有所帮助。