最佳常规调试技巧是什么? [英] What are the best general practice debugging tricks?

查看:113
本文介绍了最佳常规调试技巧是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最佳常规调试技巧是什么?不是与特定平台,语言等相关的工具,而是与您正在使用的东西和系统无关的使用的工具。

What are the best general practice debugging tricks? Not the ones tied to a specific platform, language, etc., but the ones that you find you use regardless of what you're doing and with what system.

推荐答案

我将首先提供一个我认为是一流的:

I'll start by providing one I think is superb:

难以发现的错误通常发生在相对罕见的情况下。毕竟,如果程序在每次运行时都重新引导系统,通常可以修复该错误。这些罕见情况中的某些情况是由执行以前从未执行过的代码路径引起的。程序首次启动时,通常会创建许多对象。如果这些构造函数抛出异常,那么您有一条代码路径,但是它们曾经失败过吗?

The hard to find bugs generally occur under circumstances that are relatively rare. After all, if the program re-boots your system every time you run it, you will usually fix that error. Some of these rare cases are caused by executing a code path that has never been executed before. When your program first starts, you will generally create a number of objects. You have a code path you take if those constructors throw exceptions, but have they ever failed?

如果没有,那么您就有事故发生了。当特定的构造函数失败时,您的程序实际上会做什么?只要您没有测试代码路径,就没有完全测试您的程序。确保练习每个代码路径。如果您有一个 if()... else ...,并且您始终执行 else部分,则 if部分是一个等待发生的错误。

If not, you have an accident waiting to happen. What does your program actually do when that particular constructor fails? As long as you have not tested a code path, you have not fully tested your program. Be sure that you exercise every code path. If you have an "if () ... else ..." and you have always executed the "else" part, then the "if" part is a bug waiting to happen.

有一个非常简单的方法来处理此问题,并且以一种可以在您第一次运行代码时为您提供帮助的方式进行处理。使用陷阱的好处在于,它可以立即为您提供帮助,这样一来,您很快就会发现在编写代码时会自动将它们放入。

There is a very simple way to handle this, and do so in a manner that will help you as you first run your code. The beauty of using traps is it helps you immediately, so that you will quickly find that you automatically put them in as you write code.

这是由两个方法trap()和trap(bool)组成的–我有包括Java,C ++和&的汇编器示例,但为了进行说明,我将在此处使用C#。陷阱的作用是在您击中陷阱时将您带入调试器。首先是示例,然后为什么如此有用

This is composed of two methods, trap() and trap(bool) – I have included Java, C++, & assembler examples at the, but for illustration I will use C# here. What a trap does is drop you into the debugger when you hit one. First the example, then why this is so useful

// Open an XML file
XmlReader reader;
if (string.IsNullOrEmpty(username)) {
    Trap.Trap();
    reader = XmlReader.Create(filename, xmlSettings);
} else {
    Trap.Trap(!hasDomain);
    Trap.Trap(hasDomain);
    XmlUrlResolver resolver = new XmlZipResolver();
    resolver.Credentials = hasDomain ? new NetworkCredential(user, password, domain) : new NetworkCredential(user, password);
    xmlSettings.XmlResolver = resolver;
    reader = XmlReader.Create(filename, xmlSettings);
}

即时收益

为什么从一开始就有很大帮助?因为它可以帮助您单步执行代码的每个部分。在上面的代码中,您可能首先没有使用用户名进行测试,因此您将进入第一个陷阱的调试器。您标记它,然后跨过创建。您可以单步执行几行以确保xml正确,然后再执行。

Why is this a big help from the start? Because it helps you single step through each part of your code once. In the code above you probably test at first with no username so you'll fall in the debugger on the first trap. You mark it and then step over the Create. You may single step a couple of lines after to make sure the xml is good, then you go.

注意:标记标记为命中陷阱的方法是放置* *在该行的开头。当我完成调试会话时,一个简单的编译将向我显示添加* 的每个位置。因为我将* 添加到同一行,所以行号保持不变,并且调试器正确匹配了源行(如果您在单击该行时使用陷阱删除了该行,则调试器将在任何其他位置偏离一行)

Note: The way I mark a trap I hit is to put ** at the start of that line. When I finish a debug session a simple compile will show me every place I added the *. Because I add the * to the same line, line numbers stay the same and the debugger matches your source line correctly (if you delete the line with the trap when you hit it the debugger will be off by one line anywhere further down in that file).

好,所以您已经在该模块上使用了几天,一切正常,您决定尝试使用XML文件需要凭据。当您这样做时,调试器将停在else的顶部。然后,您逐步执行代码以使用凭证打开XML文件。这种方法的优点在于,您无需记住您还没有遍历这四行代码。您无需去查找那四行代码。它只是将您放在调试器中。 我认为这是我使用的功能最强大的调试工具之一,因为我现在可以轻松地单步执行代码的每一行,并从该实践中找到足够的问题以使其值得。

Ok, so you've been working on this module for a couple of days, it's all working well and you decide to try an XML file that requires credentials. When you do the debugger will stop at the top of the else. You then step through the code opening the XML file with credentials. The beauty of this approach is you don't need to remember that you haven't walked through these 4 lines of code. You don't need to go find those 4 lines of code. It just drops you there in the debugger. I think this is one of the most powerful debugging tools I use because I now easily single step through every line of my code – and find enough issues from this practice to make it well worth it.

次要收益

这种做法还提供了第二个巨大收益。最初删除的所有陷阱都是非常常见的代码路径,或者是由于单元测试而特别命中的路径。因此,当您完成一个模块并编写了所有测试时,任何剩余的陷阱都表示有待编写的测试的指示。现在,您有一种非常简单的方法来识别需要编写的剩余单元测试。

This practice also provides a second great pay-off. All the traps removed initially are either very common code paths or paths specifically hit due to unit testing. So when you are "done" with a module and all your tests are written, any remaining traps are indicators of tests that remain to be written. You now have a very easy way to identify remaining unit tests that need to be written.

陷阱已实现,因此只能在调试版本上运行。因此,您可以发送带有陷阱的代码(我们不应该这样做,但我们都可以这样做),并且不会对发行版产生影响。

And the traps are implemented so they only run on a debug build. So you can ship code with traps in it (we shouldn't, but we all do) and it will have no impact on the release version.

为C#捕获代码,Java,C ++和&可以在其中之一强大的调试实践

Trap code for C#, Java, C++, & assembler available at One of the Most Powerful Debugging Practices

这篇关于最佳常规调试技巧是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆