CodeWarrior 使用教程第五课:调试

本文介绍了CodeWarrior调试器的使用,包括启用调试器、设置断点、查看变量值、理解堆栈和调用历史、以及调试器的全局参数设置。调试器允许程序员逐行执行代码,检查变量值,识别和修复编程错误。通过设置断点,观察变量变化,以及利用调用栈和源代码窗口,可以有效地调试程序。此外,还提到了高级设置如远程调试和异常处理,适用于有经验的开发者。
摘要由CSDN通过智能技术生成

关于调试
 
Purging pesky pests proves productive for programmers!

    调试就是在你的程序代码中找到一个问题并着手去解决它的过程。不管是谁,在编程时都难免出现一些输入或程序逻辑上的错误,一旦出现这种问题,很可能你想破了头也找不到错误在哪。这个问题可能只是一个输入上的小错误或者只是一个变量用错了,因此你很难发现它。但是因为这个错误的存在使得你的程序无法实现预期的功能。有时候会更糟糕,以致你的机器都崩溃了。这时,你就必须借助调试来解决问题。

    CodeWarrior 带有一个集成的调试器,可以让你在 CodeWarrior 主窗口中打开一个窗口来进行调试工作。使用调试器的方法是,从工程菜单中选择 Enable Debugger 项,然后重新编译你的目标文件。完成上述步骤后,你的程序就会在调试窗口中运行,此时你就可以隔离并改正你找到的任何一个问题了。

    通常进行调试时总要生成源程序的一个调试目标文件。该目标文件的源文件保持不变,但是需要预先设置置一些选项才能产生该程序的调试版本。通过点击工程窗口的弹出菜单中的调试目标文件,你就可以进入调试状态。

图 5-1: 调试器界面


图 5-1显示了 Hello World 这个程序在 CodeWarrior 调试器中进行调试时的情况。为了能够更方便地演示调试器的工作过程,我们在程序中添加了一小段循环代码(其中使用了 i、x 和 y 等三个变量)。调试器允许对代码执行单步逐行调试。当你在代码中移动时,你还可以查看程序中所有变量的值。在这种“慢速移动(slow motion)”的方式下调试程序,你可以非常清晰地查看到代码的运行情况并很容易地解决问题。


但实际情况是,不是所有的问题都很容易解决的。有些问题就有可能要花费你长达数周的时间去解决。不管是经验多么丰富的编程老手,同样不可避免地要遇到这样的问题。作为一个初学者,你更容易遇到这样的问题,但是,你千万别被这种情况吓倒。请记住,从错误中学习,你能学到更多的东西。

    请注意在调试器窗口左上角的那些按钮,它们是用于帮助你进行调试工作的。这些按钮从左到右分别是:运行程序(Run Program)、停止(Stop)、退出(Kill (Quit))、跳过(Step Over)、转入(Step Into)和转出(Step Out)。最后两个命令按钮是让你决定在单步调试程序时,如果遇到一个函数,是否要进入函数内部进行代码调试。或者你也可以使用跳过(Step Over)命令让该函数一次执行完毕,而不进入函数体中单步调试函数的代码,这样可以节省一些时间。如果你不能肯定函数是否正确无误,那么你可以转入(step into)该函数体内部对其进行单步调试。对于初学者,你应该单步调试每一个函数,至少可以练练手嘛!

    图 5-1 所示的调试窗口包含三个主要部分:
•栈窗格(The Stack pane):位于左上方的窗格是显示调用栈(也叫做调用栈的记录)的区域。当你在单步调试源码的过程中调用了多个函数时,在这个区域就显示出调试到达当前状态之前调用过的函数名清单。这个清单会随着你的调试过程,根据你是否转入函数内部的情况随时增减;  
•变量窗格(The Variables pane):  位于右上方的窗格是显示变量名和其值的区域。其中显示的是各个变量的名字和它们的值,而且还可以依据变量的类型让你查看(或修改)这些数据。在图5-1中显示的 Hello World x86 程序这个例子中,有四个变量:c,i,x 和 y。当你在代码中执行单步调试时,这些变量的值就会根据程序执行的过程实时地更新。例如,在调试过程中,你可以注意到后三个变量是如何取得它们的值的(这些值是在循环代码中赋给这些变量的),而变量 c 显示的是一个无意义的值(因为你还没有给 getchar() 输入任何值)。你可以使用这个窗格来发现不正常的变量值,从而发现程序设计上的错误这对于程序的调试成功,非常关键;
•源代码窗格(The Source pane):位于下方的窗格显示了 Hello World x86 这个程序的 C 语言源代码,它也可以用来显示该代码的汇编语言版本。随着调试的深入进行,仅仅是程序的 C 语言代码可能不能提供足够的调试信息,这是你就需要查看该程序的汇编语言代码。你可以通过该窗口下端的弹出菜单来选择查看程序的源代码、汇编代码或者两者的混合显示。

    你可能已经注意到在源代码窗格左边的红色停止标记,该标记表示这是一个断点,它用于告诉调试器在此处停止执行程序。此功能可以帮助你很方便地快速到达程序中地某一位置,然后从此位置处开始调试程序。当你设置了一个断点,调试器运行到断点所在的行就停止下来,等待你的控制命令。在某行程序左边显示的蓝色小箭头是当前程序的计数器,它表示指向的程序行为即将要执行到的语句。在图5-1中,我们已经设置了一个断点以便程序执行到完源代码中的循环块后在第二个输出语句前停下来。设置断点的操作也很简单,只需在你希望调试器停止的程序行的左端点一下鼠标即可。

    下面我们来看看关于 CodeWarrior 调试器的一些参数设置。


全局调试器参数设置


    通过选择编辑菜单中的“Preferences”项,可以看见 CodeWarrior 调试器有许多全局的参数设置。

设置内容

图 5-2: 调试器全局参数设置显示 

设置显示面板(见图5-2)包含了一些决定调试器窗口上如何显示信息的参数设置。当你刚开始使用调试器时,你可以在这里把调试器窗口上的某些文字设置得大一些或小一些,或者用一些特殊的颜色来显示它们。

    颜色设置允许你选择在源代码中用于突显观察点(watchpoints)和变量名的文字颜色。这种设置非常有用,可以帮助你在调试代码时很容易地观察到观察点或变量值的变化。观察点可用来帮助你在整个程序中跟踪某个值并将其显示在一个窗口中。

    其它设置的用途都解释得很明白了,你也不需要去更它们,默认设计就可以了。当你对调试器了解得更多了一些时,你才可能会的想去修改这些设置。

关于视窗的设置

图 5-3: 关于视窗的设置 

   在调试程序的过程中,你会发现桌面上很会就挤满了许多打开的窗口。关于视窗的设置(见图5-3)允许你设定在调试中隐藏或显示某些特定的窗口来管理这些窗口。默认的设置是隐藏非调试用的窗口,这在大多数情况下就可以了,不必修改它。

全局设置

    全局设置窗格(如图5-4所示)包含了一些用于控制调试器操作方式的选项。

图 5-4: 全局设置 

调试过程中缓存修改后的文件这一设置是用于决定修改后的文件需要缓存多长时间用的。缓存文件能够提高调试器的速度,但是要牺牲一些磁盘空间。

    其余的设置解释得很清楚了。如果你只是一个初学者,那么默认设置就可以了。

远程连接

图 5-5: 远程连接 

最后是远程连接设置(见图5-5)。该设置面板用于设置通过一个 TCP/IP 网络进行远程调试。这是一些高级设置,作为初学者,使用默认设置就可以了。

    至于 Java 设置和 Java 调试面板用于使用 Java 语言进行编程的情况的,本课程不涉及这个内容。你可以学习一些相应的课程。


目标文件和工程特定的调试器参数设置

    以下是关于被调试的目标文件和工程的设置项。当在 CodeWarrior 的工程窗口的目标文件标签中有一个目标文件被选中时,你再选择编辑菜单中的工程名设置(Project Name Settings)项即可看到这个设置窗口。

 图 5-6: 目标文件和工程调试器设置

调试器设置
•重定位后的库...的位置(Location of Relocated Libraries, etc): 如果你正在调试的文件被移到其它位置了,或者你正在通过一个 TCP/IP 网络来进行远程调试,你就必须将这些文件所在的目录输入到这个文本框中;
•在应用程序启动时在临时断点处停止(Stop at temp breakpoint on application launch): 默认情况下,这个选项在程序的起始位置中断调试器的运行。但你也可以设置为可在任何断点处中断;  
•自动查找目标库(Auto-target Libraries): 选中这个选项可以自动地访问库。此选项用于正在调试的代码是一个库的一部分时,当你调试这些代码时,调试器将“做应做的事”(例如装载库并调用任何初始化函数);
•记录系统消息(Log System Messages): 这个选项用于强制将所有的系统消息写入一个记录文件中。当你遇到代码导致系统崩溃,并因系统崩溃又看不到屏幕显示时,就很有用了。当你重启机器后,你可以从记录文件中查看导致系统崩溃的消息。特别是今后你调试一些大型程序时,记录文件就很有用了,所以一定要学会读懂记录文件!
•数据更新时间间隔(Data Update Interval): 选中这个选项并给它设置一个值,这样你就可以决定数据查看(data view)多长时间更新一次。数据查看更新得越频繁,调试器显示的数据值就越新;  
•缓存运行中的符号文件(Cache symbolics between runs): 在调试器运行时,符号文件(在编译过程中产生的一种文件)将被缓存起来。这可以提高调试的进程;  
•在观察点处停止(Stop at Watchpoints): 选中此项,当观察点值为真时就中断调试。观察点和断点一样是很有用的。不同的是,断点每次都是在一个特定的代码行处停止下来,而观察点是监视一个变量或内存的一块区域,当此被观察的对象发生改变时,它就中断调试过程。这和 VC 中的条件断点相似,都是在设定的条件被满足时中断调试过程的。这是一个很有用的调试工具。

x86 异常(Exceptions)

图 5-7:  x86 出错信息面板 

 当你调试有问题的代码时, CodeWarrior 调试器会截取到由程序的 bug 引起的某些奇怪的操作(即所谓的 异常——Exceptions)。 IDE 会将这些异常传递给一个特殊的代码——一个被称之为处理器的东西——由它来处理这些异常问题。

    但是,对于大多数的异常,调试器只是简单地中断它的工作而已。为什么会这样呢?

    如果你正在做一个高级开发,例如开发一个系统库或一个设备驱动程序,你可能想测试一下这些代码是如何处理这些异常的。只有调试器不截取这些异常时,你才能这么做。如果为了一些特定的原因,你希望调试器抓住某些特定异常发生时的控制("seize control of the moment" for specific exceptions) ,你就应该在这个设置面板上做一些设置。在该面板上显示的异常是 CodeWarrior 的集成开发环境可以处置的情况。点击那些你希望由调试器来处理的异常情况,然后点击“保存”按钮保存设置。就像前面提到的,这是很高级的编程设置,因此我们在这将不作详细讨论。总之,CodeWarrior 的调试器是一个非常先进的,而且很易于使用的附件。如果你学好了调试器的使用,它将会成为你开发软件的最重要的一个工具。

    另外还有“其它的可执行程序”和“远程调试”设置面板,它们是针对高级用户设置的,本课程不打算再作介绍。如果你需要同时调试多个可执行程序或通过 TCP/IP 网络来调试程序的话,你可以自行参看这几个设置面板。

附原文:

An Introduction to Debugging


Purging pesky pests proves productive for programmers!

Debugging is the process of tracking down a problem in your code and fixing it. The sad truth is there is always the possibility that your code contains typing or logic errors. Maybe you thought through a problem thoroughly but still missed a key step in solving it, or maybe you made a tiny typo in your code or used the wrong variable. In many cases, you'll know when you have a flaw in your logic or a programming error because your program will not function as expected. Or, in a worst-case scenario, your computer will crash. When this happens, it's time to begin debugging.

CodeWarrior includes an integrated debugger, which just means that you can view it while you're looking at other windows of CodeWarrior. Begin using the debugger by selecting Enable Debugger from the Project menu; then rebuild your target. Once that's done, your program will run within the debugger window, allowing you to isolate and fix any problems you find.

Quite often you will generate a debug target of the program. The target's source files remain the same, but many of the options required to produce a debuggable version of the program (such as generating a symbol file) are preset. This lets you flip into debug mode by just picking the debug target from the Project window's pop-up menu.

Figure 5-1: The debugger does its thing.

Figure 5-1 shows the Hello World debug program running within the CodeWarrior debugger. Note that we've added a few lines of code to the program in the form of a loop using the variables i, x, and y. We added this code in order to more easily demonstrate how the debugger works. The debugger allows you to step through your code line by line. As you move through the code, you can also note the values of all of your variables. By forcing your program to run in this "slow motion" mode, you can see exactly how your code is working and very easily track down bugs.


I lied. Not all bugs are easy to track down. I've personally worked on bugs that have taken weeks to figure out and fix. Anyone who has programmed for any length of time probably has similar horror stories. Don't let them get you down. On top of everything else, you are a beginner, so you will inevitably be writing buggy code. Remember: we learn more from our mistakes than our successes. OK, I'll stop now.

Notice the buttons at the top left corner of the debugger window. These buttons assist you in stepping through your code. The buttons are, from left to right: Run Program, Stop, Kill (Quit), Step Over, Step Into, and Step Out. The last two step commands allow you to decide whether you want to step into a particular function in your code, or simply step over it and let the entire function execute in one fell swoop. If you know that a certain function does not contain the bug, you can easily step over it and save time. If you're not sure, you can step into it and walk through its code line by line. As a beginner, you should assume that nothing is bug-free -- and you can use the practice.

The Debugging window (Figure 5-1) contains three main sections:
•The Stack pane (top left) contains a display of the call stack, also known as call history. As you step through source code and call function after function, this area displays the history of functions you have called to get to the current location. This list grows and shrinks as you step through different sections of a program and according to whether you step into functions or not.
•The Variables pane (top right) shows variable names and their values. Depending on the type of variable, this display will vary to allow you to view (and edit) the data accordingly. In the case of the Hello World x86 program, shown in Figure 5-1, there are four variables: c, i, x, and y. As you step through your code, the values of the variables will update in this window in real time. For example, notice how the latter three variables have realistic values (since these values were set by the code loop), while c has a nonsense value (you have yet to enter a character into the getchar() function). Using this pane to spot odd or unexpected values is one of the keys to your debugging success.
•The Source pane (bottom) displays the C source code for Hello World x86 program. It can also display the assembly language version of the code. Depending on the type of bug you are tracking down, the C source display may not provide enough detail. In that case, you may need to view the program at a finer level of detail -- in assembly language. The pop-up menu at the bottom of this window lets you choose whether you view the program as source, assembly language, or a mix of the two.

Note the red stop sign on the left edge of the Source pane. The stop sign indicates a breakpoint. You set breakpoints in the debugger to tell it where to stop executing your code. This feature can come in very handy when you want to quickly move to a certain point in your program and begin working from there. When you set a breakpoint, the debugger will automatically stop at that line of code and will let you take control. The small blue arrow is the current program counter; it points to the line of code that is about to be executed. In the Figure 5-1, we have set the breakpoint so that the program executes the code loop before halting on the second printf() statement. You can set and clear breakpoints by simply clicking to the left of the line of code you're interested in.

Let's look at some of the preferences for the CodeWarrior debugger.


Global Debugger Preferences

There are many global preferences in the CodeWarrior debugger. Let's take a look. These settings can be reached by selecting Preferences from the Edit menu.

Display Settings

Figure 5-2: Display settings. 

The Display Settings panel (Figure 5-2) contains preferences that determine how the debugger displays information in its windows. As you begin to use the debugger, you will find that you want certain text to appear larger or smaller, or to be displayed in a specific color. You can select these options here.

Color settings allow you to choose the text color used by watchpoints or variable names when the code alters them. This allows you to see if a watchpoint or variable is being changed without your knowledge as the code executes. Watchpoints are useful if you want to track a variable at intervals throughout the program and want it to be conveniently displayed in a window.

The other settings are self-explanatory. In most cases, the default settings will work. As you learn more about the debugger, you may want to alter these settings.

Windowing Settings

Figure 5-3: Windowing Settings. 

When debugging, you will quickly find that your desktop is cluttered with lots of open windows. The Windowing settings (Figure 5-3) allow you to manage windows by choosing to hide or show certain types of windows when you start debugging. The default setting, Hide Non-Debugging Windows, will probably suffice in most cases.

Global Settings

The Global Settings pane (Figure 5-4) contains options that control the way the debugger operates.

Figure 5-4: Global settings. 

Cache Edited Files Between Debug Sessions setting allows you to choose how long to cache edited files between debug sessions. Caching files can increase the speed of the debugger but will also take up precious disk space.

The remaining settings are self-explanatory. The default settings will serve you well as you begin to use the debugger.

Remote Connections

Figure 5-5: Remote Connections.

Lastly, the Remote Connections Settings (Figure 5-5) allow you to remotely debug code across a TCP/IP network. These settings are advanced, and the default values will work fine as you learn to debug in CodeWarrior.

Note that the Java Settings and Java Debugging panels are for the Java Programming Language and are not covered in this course. However, other courses are available for this language!


Target and Project-Specific Debugger Preferences

The following settings are specific to each target and project that is debugged. You can reach them by selecting Project Name Settings from the Edit menu, while a target is selected in the Target tab in the CodeWarrior Project window.

Figure 5-6: Target and Project Debugger Settings.

Debugger Settings
•Location of Relocated Libraries, etc: If the file you are debugging has been moved, or if you're debugging remotely over a TCP/IP network, you must type the file's directory path into this text box.
•Stop at temp breakpoint on application launch: By default, this option breaks the debugger (stops execution of the code) at the beginning of your program. However, you can choose to break at any point.
•Auto-target Libraries: Check this setting to automatically access libraries. This can assist you when debugging code that is part of a library. The debugger will "do the right thing" (such as loading the library and calling any initialization functions) as you step into its code.
•Log System Messages: This setting forces all system messages to be written to a log file. This can be useful if your code is crashing your computer, and you can't see the screen during the crash. The messages will be written to a log file that you can view after you restart your computer. Log files can save you many headaches later. Learn to read them!
•Data Update Interval: By setting a value here and checking this box, you can choose how often data views are updated. The more often you update data views, the more up-to-date the displayed values will be in the debugger.
•Cache symbolics between runs: Symbolic files (files generated during the compile process) will be cached and referenced between debugger runs. This can speed up the debugging process.
•Stop at Watchpoints: To stop at watchpoints when they are equal to true, check this option. Watchpoints can be very useful, similar to breakpoints. Whereas a breakpoint will break into the debugger on a specific line of code every time, a watchpoint monitors a variable or area of memory and breaks into the debugger only when the contents change. There is also a feature called a conditional breakpoint that will halt execution when the condition is true. Depending on your needs and the way you like to work, these advanced features can be very helpful to you as a programmer.

x86 Exceptions

Figure 5-7: The x86 Exceptions panel.

As you debug questionable code, the CodeWarrior debugger intercepts certain oddball operations (termed exceptions) brought about by a program bug. The IDE passes these exceptions along to special code -- appropriately known as a handler -- that attempts to deal with the problem gracefully.

However, for many exceptions, the debugger simply stays out of the way. Why is this?

If you're doing advanced programming such as writing a system library or a device driver, you may want to test how its code handles some of these exceptions. By not intercepting many exceptions, the debugger lets you do this. If for some reason you want the debugger to "seize control of the moment" for specific exceptions, you can direct it to do so with this panel. The exceptions shown here are ones that the CodeWarrior IDE is prepared to handle. Click on the exception types you need the debugger to field for you, and then click Save. As mentioned previously, this is heavy-duty programming material, so we won't go into any details here. The debugger is a very advanced, yet very easy-to-use addition to the CodeWarrior environment. If you learn to use it well, it will become one of the most important tools in your software development arsenal.

Note that the Other Executables and Remote Debugging panels are for advanced users and are not covered in this course. If you ever have a need to debug multiple-executables at a time and/or debug over a TCP/IP network, you will know it!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值