Turbo Debugger 3.0 For Windows Users Guide 1991
Turbo Debugger 3.0 For Windows Users Guide 1991
DEBUGGER®3.0
FOR WINDOWS
USER'S GUIDE
BORLAND
...
Version 3.0
User's Guide
iii
Always ...................... 112 Previous . . . . . . . . . . . . . . . . . . . . . . . 126
Changed memory . . . . . . . . . . . . . 112 Line ........................... 126
Expression true . . . . . . . . . . . . . . . 112 Search ......................... 126
Hardware . . . . . . . . . . . . . . . . . . . . 112 Next .......................... 127
The action radio buttons . . . . . . . . . 113 Origin ......................... 127
Break ........................ 113 Goto .......................... 127
Execute . . . . . . . . . . . . . . . . . . . . . . 113 Examining other disk files ............ 127
Log ......................... 113 The File window . . . . . . . . . . . . . . . . . . 127
Enable group . . . . . . . . . . . . . . . . . 113 The File window local menu . . . . . . . . 128
Disable group . . . . . . . . . . . . . . . . 113 Goto .......................... 129
Setting conditions and actions . . . . 114 Search ......................... 129
Condition Expression . . . . . . . . . . . . 114 Next .......................... 130
Action Expression ............... 115 Display As . . . . . . . . . . . . . . . . . . . . . 130
Pass count . . . . . . . . . . . . . . . . . . . . . 115 File ........................... 130
Customizing breakpoints ............ 116
Simple breakpoints ................ 116 Chapter 9 Expressions 131
Global breakpoints . . . . . . . . . . . . . . . . 116 Choosing the language for expression
Changed memory breakpoints . . . . . . 117 evaluation . . . . . . . . . . . . . . . . . . . . . . . . . 132
Conditional expressions . . . . . . . . . . . 118 Code addresses, data addresses, and line
Scope of breakpoint expressions . . 118 numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Hardware breakpoints . . . . . . . . . . . . . 118 Accessing symbols outside the current
Logging variable values . . . . . . . . . . . . 119 scope .............................. 133
Breakpoints and templates . . . . . . . . . 119 Scope override syntax ............. 134
Breakpoints on class templates . . . . 119 Overriding scope in C, C++, and
Breakpoints on function templates . 120 assembler programs . . . . . . . . . . . . . 134
Breakpoints on template class Scope override tips . . . . . . . . . . . . 136
instances and objects . . . . . . . . . . . . 120 Overriding scope in Pascal
The Log window . . . . . . . . . . . . . . . . . . . . 120 programs . . . . . . . . . . . . . . . . . . . . . . 137
The Log window local menu . . . . . . . 121 Scope override tips . . . . . . . . . . . . 138
Open Log File . . . . . . . . . . . . . . . . . . 121 Scope and DLLs . . . . . . . . . . . . . . . . 138
Close Log File . . . . . . . . . . . . . . . . . . 122 Implied scope for expression
Logging ....................... 122 evaluation . . . . . . . . . . . . . . . . . . . . . . . 139
Add Comment . . . . . . . . . . . . . . . . . 122 Byte lists . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Erase Log . . . . . . . . . . . . . . . . . . . . . . 122 C expressions . . . . . . . . . . . . . . . . . . . . . . 140
Display Windows Info . . . . . . . . . . . 122 C symbols . . . . . . . . . . . . . . . . . . . . . . . 140
C register pseudovariables . . . . . . . . . 140
Chapter 8 Examining files 123 C constants and number formats .... 142
Examining program source files . . . . . . . 123 Escape sequences ................. 142
The Module window . . . . . . . . . . . . . . 124 C operator precedence . . . . . . . . . . . . . 143
The Module window local menu . . . . 125 Executing C functions in your pro-
Inspect . . . . . . . . . . . . . . . . . . . . . . . . 125 gram ............................ 144
Watch ......................... 125 C expressions with side effects ...... 144
Module ........................ 126 C reserved words and type
File ........................... 126 conversion . . . . . . . . . . . . . . . . . . . . . . . 145
iv
Assembler expressions .............. . 146 Chapter 11 Using Windows debugging
Assembler symbols ............... . 146 features 157
Assembler constants 146 Windows features . . . . . . . . . . . . . . . . . . . 157
Assembler operators . : : : : : : : : : : : : : : 147 Logging window messages . . . . . . . . . 158
Format control ..................... . 147 Selecting a window for a standard
Chapter 1O Object-oriented Windows application . . . . . . . . . . . . 158
Adding a window selection for a
debugging 149
standard Windows aoolication 159
The Hierarchy window . . . . . . . . . . . . . . i 49
Selecting a window for ·a~ .
The Class List pane . . . . . . . . . . . . . . . . 150
ObjectWindows application . . . . . . 159
The Class List pane local menu . . . 150
Obtaining a window handle . . . . 159
Inspect ...................... 150
Specifying a window with
Tree ......................... 151
ObjectWindows support
The Hierarchy Tree pane . . . . . . . . . . . 151
enabled . . . . . . . . . . . . . . . . . . . . . . 160
The Hierarchy Tree pane local
Adding a window with
menu(s) . . . . . . . . . . . . . . . . . . . . . . . 151
ObjectWindows support
The Parent Tree pane . . . . . . . . . . . . . . 151
enabled ...................... 161
The Parent Tree pane local menu . . 152
Deleting a window selection . . . . . . 162
Class Inspector windows . . . . . . . . . . . . . 152
Specifying a message class and
The class Inspector window local
action ......................... 162
menus ........................... 153
Adding a message class . . . . . . . . 162
The Data Member (top) pane 153
Deleting a message class . . . . . . . 164
Inspect ...................... 153
Window message tips . . . . . . . . . 165
Hierarchy .................... 153
Viewing messages . . . . . . . . . . . . . . 165
Show Inherited . . . . . . . . . . . . . . . 153
Obtaining memory and module lists. 166
The Member Function (bottom)
Listing the contents of the global
pane .......................... 154
heap .......................... 166
Inspect ...................... 154
Listing the contents of the local
Hierarchy . . . . . . . . . . . . . . . . . . . . 154
heap .......................... 168
Show Inherited . . . . . . . . . . . . . . . 154
Obtaining a list of modules ....... 168
Object Inspector windows . . . . . . . . . . . . 154
Debugging dynamic link libraries
The object Inspector window local
(DLLs) .......................... 169
menus ........................... 155
Using the Load Modules or DLLs
Range ......................... 155
dialog box ..................... 170
Change ........................ 155
Changing source modules . . . . . . 170
Methods . . . . . . . . . . . . . . . . . . . . . . . 155
Working with DLLs and
Show Inherited . . . . . . . . . . . . . . . . . 156
programs .................... 171
Inspect . . . . . . . . . . . . . . . . . . . . . . . . 156
Adding a DLL to the DLLs &
Descend . . . . . . . . . . . . . . . . . . . . . . . 156
Programs list . . . . . . . . . . . . . . . . . . . 172
New Expression ................ 156
Setting debug options in a DLL ... 173
Type Cast . . . . . . . . . . . . . . . . . . . . . . 156
Controlling TDW's loading of DLL
Hierarchy . . . . . . . . . . . . . . . . . . . . . . 156
symbol tables ................... 173
The middle and bottom panes . . . . . . 156
Debugging DLL startup code ..... 173
v
Converting memory handles to Instructions pane . . . . . . . . . . . . . . . 194
addresses . . . . . . . . . . . . . . . . . . . . . . . . 175 File window . . . . . . . .. . . . . . . .. . . . . . 194
Log window menu . . . . . . . . . . . . . . . . 194
Chapter 12 Assembler-level Module window . . . . . . . . . . . . . . . . . . 195
debugging 177 Windows Messages window . . . . . . . 195
When source debugging isn't enough . . 177 Window Selection pane . . . . . . . . . . 195
The CPU window . . . . . . . . . . . . . . . . . . . 178 Message Class pane . . . . . . . . . . . . . 196
The Code pane . . . . . . . . . . . . . . . . . . . . . 180 Messages pane . . . . . . . . . . . . . . . . . 196
The disassembler . . . . . . . . . . . . . . . . . 180 Clipboard window . . . . . . . . . . . . . . . . 196
The Register and Flags panes . . . . . . . . . 181 Numeric Processor window . . . . . . . . 197
The Selector pane . . . . . . . . . . . . . . . . . . . 181 Register pane . . . . . . . . . . . . . . . . . . . 197
The Selector pane local menu ....... 182 Status pane . . . . . . . . . . . .. . . . . . . . 197
Selector . . . . . . . . . . . . . . . . . . . . . . . . 182 Control pane . . . . . . . . . . . . . . . . . . . 197
Examine . . . . . . . . . . . . . . . . . . . . . . . 182 Hierarchy window . . . . . . . . . . . . . . . . 197
The Data pane . . . . . . . . . . . . . . . . . . . . . . 183 Class pane . . . . . . . . . . . . . . . . . . . . . 197
The Stack pane . . . . . . . . . . . . . . . . . . . . . 183 Hierarchy Tree pane ............. 198
The Dump window . . . . . . . . . . . . . . . . . 184 Parent Tree pane . . . . . . . . . . . . . . . . 198
The Registers window . . . . . . . . . . . . . . . 184 Registers window menu . . . . . . . . . . . 198
Chapter 13 Command reference 185 Stack window . . . . . .. . . . . . . . . . . . . . 198
Hot keys . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Variables window .. . . . . . . . . . . . . . . . 198
Commands from the menu bar . . . . . . . 187 Global Symbol pane . . . . . . . . . . . . . 198
The = (System) menu . . . . . . . . . . . . . . 187 Local Symbol pane . ; . . . . . . . . . . . . 199
The File menu . . . . . . . . . . . . . . . . . . . . 187 Watches window ................. 199
The Edit menu . . . . . . . . . . . . . . . . . . . . 188 Inspector window . . . . . . . . . . . . . . . . . 200
The View menu . . . . . . . . . . . . . . . . . . . 188 Class Inspector window . . . . . . . . . . . 200
The Run menu . . . . . . . . . . . . . . . . . . . . 189 Object Inspector window . . . . . . . . . . 200
The Breakpoints menu . . . . . . . . . . . . . 189 Text panes ......................... 201
The Data menu . . . . . . . . . . . . . . . . . . . 189 List panes . . . . . . . . . . . . . . . . . . . . . . . . . . 202
The Options menu . . . . . . . . . . . . . . . . 189 Commands in input and history list
The Window menu . . . . . . . . . . . . . . . . 190 boxes .............................. 202
The Help Menu . . .. . .. . . . . . . . . . . . . 190 Window movement commands . . . . . . . 203
The local menu commands . . . . . . . . . . . 190 Wildcard search templates . . . . . . . . . . . 204
Breakpoints window . . . . . . . . . . . . . . 191 Complete menu tree . . . . . . . . . . . . . . . . . 204
The CPU window menus . . . . . . . . . . 191 Chapter 14 Debugging a standard C
Code pane . . . . . . . . . . . . . . . . . . . . . 191 application 207
Selector pane . . . . .. . .. . . .. . . . .. . 192 When things don't work ... ~ . . . . . . . . . 207
Data pane . . . . . . . . . . . . . . . . . . . . . . 192 Debugging style . . . . . . . . . . . .. . . . . . . . 208
Flags pane . . . . . . . . . . . . . . . . . . . . . 193 Run the whole thing . . . . . . . . . . . . . . . 209
Register pane . . . . . . . . . . . . . . . . . . . 193 Incremental testing . . . . . . . . . . . . . . . . 209
Stack pane . . .. .. . .. . . . . . . . . .. . . 193 Types of bugs . . . . . . . . . . . . . . . . . . . . . . 209
Dump window ................... 194 General bugs . . . . . . . . . . . . . . . . . . . . . 210
The Execution History window Hidden effects . . . . . . . . . . . . . . . . . . 210
menus ........................... 194 Assuming initialized data ........ 210
vi
Not cleaning up . . . . . . . . . . . . . . . . 210 WMRButtonDown . . . . . . . . . . . . . . 226
Fencepost errors . . . . . . . . . . . . . . . . 211 WMMouseMove . . . . . . . . . . . . . . . . 226
C-specific bugs . . . . . . . . . . . . . . . . . . . 211 The pen-color routines . . . . . . . . . . . 226
Using uninitialized automatic Creating the application . . . . . . . . . . . 226
variables . . . . . . . . . . . . . . . . . . . . . . . 211 Debugging the program . . . . . . . . . . . . . 227
Confusing= and== ............. 212 Finding the first bug . . . . . . . . . . . . . . . 227
Confusing operator precedence ... 212 Finding the function that called
Bad pointer arithmetic . . . . . . . . . . . 212 Windows . . . . . . . . . . . . . . . . . . . . . . 227
Unexpected sign extension ....... 213 Debugging wMLButtonDown . . . . 228
Unexpected truncation . . . . . . . . . . . 213 Debugging MoveTo . . . . . . . . . . . . . 228
Misplaced semicolons . . . . . . . . . . . 213 Fixing the bug . . . .. . . . . . . . . . . . . . 229
Macros with side effects . . . . . . . . . 214 Testing the fix .................. 229
Repeated autovariable names ..... 214 Finding the pen color bug . . . . . . . . . . 230
Misuse ofautovariables .......... 214 Setting a window message
Undefined function return value .. 214 breakpoint . . . . . . . . . . . . . . . . . . . . . 230
Misuse of break keyword . . . . . . . . 215 Setting a window message
Code has no effect . . . . . . . . . . . . . . . 215 breakpoint with a handle ...... 231
Accuracy testing .................... 215 Setting a window message
Testing boundary conditions . . . . . . . 216 breakpoint with a window
Invalid data input . . . . . . . . . . . . . . . . . 216 object ........................ 232
Empty data input .. . . . . . .. . . . . . .. . 216 Inspecting wParam . . . . . . . . . . . . . . 233
Debugging as part of program design . . 216 Testing the fix . . . . . . . . . . . . . . . . . . 234
The sample debugging session ........ 217 Finding the off-screen drawing bug 234
Looking for errors . . . . . . . . . . . . . . . . . 217 Logging the window messages . . . 234
Deciding your plan of attack . . . . . . . . 218 Discovering the bug . . . . . . . . . . . . . 234
Starting Turbo Debugger . . . . . . . . . . . 218 Fixing the bug . . .. . . . . . . . . . . . . . . 235
Inspecting . . . . . . . . . . . . . . . . . . . . . . . 219 Testing the fix .................. 236
Breakpoints . . . . . . . . . . . . . . . . . . . . . . 219 Finding the erase-screen bug . . . . . . . 236
The Watches window . . . . . . . . . . . . . . 220 Analyzing the cause of the bug . . . 237
The Evaluate/Modify dialog box . . . . 220 Fixing the bug . . .. . . . . . . . . . . . . . . 238
Eureka! . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Testing the fix . . . . . . . . . . . . . . . . . . 238
Chapter 15 Debugging an Appendix A Summary of command-line
ObjectWindows options 239
application 223
Appendix B Error and information
About the program . . . . . . . . . . . . . . . . . . 223
messages 241
The Color Scribble window type
Dialog box messages . . . . . . . . . . . . . . . . 241
definition . . . . . . . . . . . . . . . . . . . . . . . . 224
Error messages . . . . . . . . . . . . . . . . . . . . . 248
ScribbleWindow ................ 225
Fatal errors . . . . . . . . . . . . . . . . . . . . . . . 248
GetWindowClass . . . . . . . . . . . . . . . 225
Other error messages . . . . . . . . . . . . . . 249
WMLButtonDown . . . . . . . . . . . . . . 226
WMLButtonUp . . . . . . . . . . . . . . . . . 226 Index 263
vii
T A B L E s
2.1: What goes in a dialog box ........... 21 13.1: The function key and hot key
2.2: Clipboard item types ............... 38 commands ...................... 186
2.3: Clipboard local menu commands .... 39 13.2: Text pane key commands ......... 201
11.l: Windows message classes ........ 163 13.3: List pane key commands ......... 202
11.2: Fonnat of a global heap list ....... 167 13.4: Dialog box key commands ........ 203
11.3: Format of a local heap list ........ 168 13.5: Window movement key
11.4: Format of a Windows module list .. 169 commands ..................... 203
11.5: DLLs & Programs list dialog box A.1: TOW command-line options ....... 239
controls ........................ 171
viii
F G u R E s
2.1: Glabal and local menus __ - .. 23 6.4: A C pointer Inspector window ...... 96
2.2: A history list in an input box ........ 24 6.5: A C structure or union Inspector
2.3: The active window has a double window .......................... 97
outline ........................... 32 6.6: A C array Inspector window ........ 97
2.4: A typical window ................. 32 6.7: A C function Inspector window ..... 98
2.5: The Pick dialog box ................ 37 6.8: An assembler scalar Inspector
2.6: The Clipboard window ............. 38 window .......................... 98
2.7: The normal status line .............. 42 6.9: An assembler pointer Inspector
2.8: The status line with Alt pressed ...... 42 window .......................... 99
2.9: The status line with Ctr/ pressed ..... .42 6.10: An assembler array Inspector
3.1: The startup screen showing window ........................ 100
TDDEMO ........................ 44 6.11: An assembler structure Inspector
3.2: The menu bar ..................... 45 window ........................ 100
3.3: The status line ................... .46 7.1: The Breakpoints window .......... 106
3.4: The Module and Watches windows, 7.2: The Edit Breakpoint Groups dialog
tiled ............................. 47 box ............................. 108
3.5: Program stops on return from 7.3: The Add Group dialog box ........ 108
function showargs ................. 49 7.4: The Breakpoint Options dialog box . 110
3.6: A breakpoint at line 44 ............. 50 7.5: The Conditions and Actions dialog
3.7: AC variable in the Watches window .51 box ............................. 111
3.8: An Inspector window .............. 52 7.6: The Log window ................. 120
3.9: Inspecting a structure .............. 53 8.1: The Module window .............. 124
3.10: The Change dialog box ............ 54 8.2: The File window ................. 128
3.11: The Evaluate/Modify dialog box ... 55 8.3: The File window showing hex data . 128
4.1: The Display Options dialog box ..... 65 10.1: The Hierarchy window ........... 149
4.2: The Save Options dialog box ........ 67 10.2: A class Inspector window ........ 152
5.1: The Variables window ............. 70 10.3: An object Inspector window ...... 155
5.2: The Local Display dialog box ........ 73 11.1: The Windows Messages window for
5.3: The Stack window ................. 74 a standard Windows application ... 158
5.4: The Get Info text box ............... 75 11.2: The Add Window dialog box for a
5.5: The Execution History window ...... 82 standard Windows application .... 159
5.6: The Enter Program Name to Load 11.3: The Windows Messages window with
dialog box ........................ 85 ObjectWindows support enabled .. 161
6.1: The Evaluate/Modify dialog box .... 89 11.4: The Add Window dialog box with
6.2: The Watches window .............. 92 ObjectWindows support enabled .. 162
6.3: A C scalar Inspector window ........ 95 11.5: The Set Message Filter dialog box .. 163
ix
11.6: The Windows Information dialog 12.1: The CPU window ............... 178
box ............................ 166 12.2: The Dump window .............. 184
11.7: The Load Modules or DLLs dialog 12.3: The Registers window ........... 184
box ............................ 170 13.1: The Turbo Debugger menu tree ... 205
x
N T R 0 D u c T 0 N
Introduction
•set and remove breakpoints on all functions or procedures in
a module
• set and remove breakpoints on all methods in an object type
or all member functions in a class
• C++ templates and nested classes are supported (see page 119).
•International sort orders are supported through the Windows
Language setting. You turn this feature on by using the configu-
ration program TDWINST.EXE (see the file TDWINST.DOC).
• The CPU window has a new pane that shows protected mode
selectors and lets you look at the contents of memory locations
referenced by these selectors (see page 181).
•The device driver TDDEBUG.386 provides support for Ctrl-Alt-
SysRq program. In addition, this device driver supports the
hardware debug registers of the Intel 83086 processor (and
higher). See page 12 for TDDEBUG.386 installation information.
See page 118 and the online file HDWDEBUG.TDW for
information on hardware debugging.
• Debugging of DLLs is faster now that TOW simultaneously
loads both the application's symbol table and the symbol table
of any DLL you explicitly load or whose code you step into (see
page 138).
A note on terminology
For convenience and brevity, we use two terms in this manual in
slightly more generic ways than usual. These terms are module
and argument.
Module Refers to what is usually called a module in C++ and assembler,
but also to what is called a unit in Pascal.
Argument Is used interchangeably with parameter in this manual. This
applies to references to command-line arguments (or parameters),
as well as to arguments (or parameters) passed to functions.
Introduction 3
Chapter 5: Controlling program execution demonstrates the
various ways of starting and stopping your program, as well as
how to restart a session or replay the last session.
Chapter 6: Examining and modifying data explains the unique
capabilities TOW has for examining and changing data inside
your program.
Chapter 7: Breakpoints introduces the concept of actions, and
how they encompass the behavior of what are sometimes referred
to as breakpoints, watchpoints, and tracepoints. Both conditional
and unconditional actions are explained, as well as the various
things that can happen when an action is triggered.
Chapter 8: Examining files describes how to examine program
source files, as well as how to examine arbitrary disk files, either
as text or binary data.
Chapter 9: Expressions describes the syntax of C and assembler
expressions accepted by the debugger, as well as the format
control characters used to modify how an expression's value is
displayed.
Chapter 10 Object-oriented debugging explains the debugger's
special features that let you examine objects in Turbo C++ for
Windows.
Chapter 11: Using Windows debugging features describes how to
use the TOW features that support debugging of Windows
applications.
Chapter 12: Assembler-level debugging describes the CPU
window. Additional information about this window and about
assembler-level debugging is in the file ASMOEBUG.TOW.
Chapter 13: Command reference is a complete listing of all main
menu commands and all local menu commands for each window
type.
Chapter 14: Debugging a standard C application is an intro-
duction to strategies for effective debugging of your programs.
Chapter 15: Debugging an ObjectWindows application leads you
through a debugging session on a sample Windows program
written using the ObjectWindows class library.
Appendix A: Summary of command-line options summarizes all
the command-line options described in Chapter 4.
Resources in your
package This product contains many resources to help you:
• The manuals provide information on every aspect of the
program. Use them as your main information source.
•While using the program, you can press Ft for help.
• Some common questions are answered in the file
HELPME!.TDW, located in the DOC subdirectory of your
language compiler directory, and the README file, located in
the main language compiler directory.
Borland resources
Borland Technical Support publishes technical information sheets
on a variety of topics and is available to answer your questions.
800-822-4269 (voice) TechFax is a 24-hour automated service that sends free technical
TechFax
information to your fax machine. You can use your touch-tone
phone to request up to three documents per call.
408-439-9096 (modem) The Borland File Download BBS has sample files, applications,
File Download BBS
2400Baud
and technical information you can download with your modem.
No special setup is required.
Subscribers to the CompuServe, GEnie, or BIX information
services can receive technical support by modem. Use the
commands in the following table to contact Borland while
accessing an information service.
Introduction 5
Online information services
Service Command
CompuServe GO BORLAND
BIX JOIN BORLAND
GEnie BORLAND
Recommended reading
The manuals accompanying your language compiler contain
excellent information on programming Windows applications.
The Help system also has a complete Windows API reference.
Introduction 7
__ , _____ - - - -
8 Turbo Debugger for Windows User's Guide
c H A p T E R
Getting started
See the FILELIST.DOC file for Turbo Debugger for Windows is part of the Turbo C++ for
information about the online
Windows package, which consists of a set of distribution disks,
files that document subjects
not covered in this manual. the Turbo Debugger for Windows User's Guide (this manual), and the
Turbo C++ for Windows manuals. The distribution disks contain
all the programs, files, and utilities needed to debug programs
written in Turbo C ++ for Windows.
The Turbo Debugger for Windows User's Guide provides a subject-
by-subject introduction of TDW's capabilities and a complete
command reference.
The MANUAL.TOW
file After installation, the\ TCW\DOC directory on your hard disk
also contains a file called MANUAL.TDW that indicates
corrections and additions to the TDW manual. Be sure to consult
this file before making extensive use of the manual.
The HELPME!.TDW
file Your installation disk also contains a file called HELPME!.TDW,
which contains answers to problems that users commonly run
into. Consult it if you find yourself having difficulties. The
HELPME!.TDW file discusses:
• the syntactic and parsing differences between TDW and Turbo
C ++ for Windows
•debugging multi-language programs with TDW
• common questions about using TDW with Windows
The
ASMDEBUG.TDW This file contains information on debugging Turbo Assembler
programs. You might also find the information in this file helpful
file
for debugging your inline assembler code.
Installing
TDDEBUG.386 There's a file on your installation disks, TDDEBUG.386, that
provides the same functionality as the Windows SDK file
WINDEBUG.386. In addition, it provides support for the
hardware debugging registers of Intel 80386 (and higher)
processors.
The installation program should copy this file to your hard disk
and alter your Windows SYSTEM.IN! file so that Windows loads
TDDEBUG.386 instead of WINDEBUG.386. If the installation
program can't complete this task for you, it tells you. You then
have to do it by hand, as follows:
Where to now?
Now you can start learning about TOW. Since this User's Guide is
written for three types of users, different chapters of the manual
might appeal to you. The following road map will guide you.
Programmers
learning Turbo If you're just starting to learn C or C++, you want to be able to
create small programs using it before you learn about the de-
C++
bugger. After you have gained a working knowledge of the
language, work your way through Chapter 3, "A quick example,"
for a speedy tour of the major functions of TOW. There you'll
learn enough about the features you need to debug your first pro-
gram; you'll find out about the debugger's more sophisticated
capabilities in later chapters.
TOW basics
Debugging is the process of finding and correcting errors (''bugs")
in your programs. It's not unusual to spend more time on finding
and fixing bugs in your program than on writing the program in
the first place. Debugging is not an exact science; the best debug-
ging tool you have is your own "feel" for where a program has
gone wrong. Nonetheless, you can always profit from a system-
atic method of debugging.
The debugging process can be broadly divided into four steps:
Is there a bug? The first step can be really obvious. The computer freezes up (or
hangs) whenever you run it. Or perhaps it crashes in a shower of
meaningless characters. Sometimes, however, the presence of a
bug is not so obvious. The program might work fine until you
enter a certain number (like 0 or a negative number) or until you
examine the output closely. Only then do you notice that the
result is off by a factor of .2 or that the middle initials in a list of
names are wrong.
What is it? The third step, finding the cause of the error, is probably the
second-hardest part of debugging. Once you've discovered where
the bug is, it's usually somewhat easier to find out why the pro-
gram is misbehaving. For example, if you've determined the error
is in a procedure called PrintNames, you have only to examine the
lines of that procedure instead of the entire program. Even so, the
error can be elusive and you might need to experiment a bit
before you succeed in tracking it down.
Fixing it The final step is fixing the error. Armed with your knowledge of
the program language and knowing where the error is, you can
squash the bug. Now you run the program again, wait for the
next error to show up, and start the debugging process again.
See Chapter 14 for a more Many times this four-step process is accomplished when you are
detailed discussion of the
writing the program itself. Syntax errors, for example, prevent
debugging process.
your programs from compiling until they're corrected. Turbo C++
for Windows has a built-in syntax checker that informs you of
these errors and lets you fix them on the spot.
But other errors are more insidious and subtle. They lie in wait
until you enter a negative number, or they're so elusive you're
stymied. That's where TOW comes in.
You can use these powerful tools to dissect your program into
discrete chunks, confirming that one chunk works before moving
to the next. In this way, you can burrow through the program, no
matter how large or complicated, until you find where that bug is
hiding. Maybe you'll find there's a function that inadvertently
reassigns a value to a variable, or maybe the program gets stuck
in an endless loop, or maybe it gets pulled into an unfortunate
recursion. Whatever the problem, TOW helps you find where it is
and what's at fault.
Menus and
dialog boxes As with many Borland products, TDW has a convenient global
menu system accessible from a menu bar running along the top of
the screen. This menu system is always available except when a
dialog box is active.
A pull-down menu is available for each item on the menu bar.
Through the pull-down menus, you can
•execute a command.
•open a pop-up menu. Pop-up menus appear when you choose a
menu item that is followed by a menu icon (Ii>).
•open a dialog box. Dialog boxes appear when you choose a
menu item that is followed by a dialog box icon (... ).
Using the menus There are four ways you can open the menus on the menu bar:
Getting in •Press F10, use~ or (----to go to the desired menu, and press
Enter.
•Press F10, then press the first letter of the menu name (Spacebar,
F, E, V, R, B, 0, 0, W, H).
•Press Alt plus the first letter of any menu bar command
(Spacebar, F, E, V, R, B, D, 0, W, H). For example, wherever you are
in the system, Alt-F takes you to the File menu. The = (System)
menu opens with Alt-Spacebar.
iii.&, • Click the menu bar command with the mouse.
Dialog boxes Many of TDW's command options are available to you in dialog
boxes. A dialog box contains one or more of the following items:
Knowing where
you are In addition to the convenient system of Borland pull-down
menus, the TOW advantage consists of a powerful feature that
lessens confusion by actually reducing the number of menus.
To understand this feature, you must realize that first and fore-
most, TOW is context-sensitive. That means it keeps tabs on
History lessons
Menus and context-sensitivity comprise just two aspects of the
convenient environment of TDW. Another habit-forming feature
is the history list.
Conforming to the philosophy that the user shouldn't have to
type more than absolutely necessary, TDW remembers whatever
you enter into input boxes and displays that text whenever you
call up the box again.
For example, to search for the function called MyPercentage, you
have to type in all or part of that word. Then suppose you want to
search for a variable called ReturnOnlnvestment. When you see the
dialog box this time, you'll notice that MyPercentage appears in
the input box. When you search for another text string, both pre-
viously entered strings appear in the input box. The list keeps
growing as you continue to use the Search command.
The search input box might look like this:
Figure 2.2
Ahistorylistinanlnputbox TDD~ .c
if! PROMPT
ll[!=Mo.u e: TDDEM. File: l=[tJ [~]=;i
/* program entry point
•
~
*/
int PASCAL WinMain(HANDLE hlnstance, HANDLE hPrevlnstance,
LPSTR lpszCmdLine, int nCmdShow )
I
I
InitWinCrt();
iilines = O;
nwords = O;
totalcharacters = O;
showargs( argc, argv);
while (readaline\) != O) {
wordcount = makei ntowords
nwords += wordcount;
Automatic name Whenever you are prompted for text entry in an input box, you
completion can type in just part of a symbol name in your program, then
press Ctrl-N.
Warning! When the word READY ••• appears in the upper right corner of the
screen with three dots after it, it means the symbol table is being
sorted. Ctrl-Nwon't work until the three dots go away, indicating
that the symbol table is available for name completion.
• If you have typed enough of a name to uniquely identify it,
TOW simply fills in the rest of it.
•If the name you have typed so far is not the beginning of any
known symbol name, nothing happens.
•If what you have typed matches the beginning of more than
one symbol name, a list of matching names is presented for you
to pick the one you want.
Incremental
matching TOW also lets you use incremental matching to find entries in a
dialog box list of file and directory names. Start typing the name
of the file or directory; if the file is available from the names at or
below the current position in the list box, the highlight bar moves
Making macros
Whenever you find yourself Macros are simply hot keys you define to perform a series of
repeating a series of steps,
commands and other keystrokes.
say to yourself, "Shouldn't I
be using a macro for this?° You can assign any series of TDW commands and keystrokes to a
single key, for playback whenever you want.
See page 64 in Chapter 4 for an explanation of how to define
macros.
Window shopping
TDW displays all information and data in menus (local and
global), dialog boxes (which you use to set options and enter
information), and windows. There are many types of windows; a
window's type depends on what sort of information it holds. You
open and close all windows using menu commands (or hot key
shortcuts for those commands). Most of TDW's windows come
from the View menu, which lists fifteen types of windows.
Another class of window, called the Inspector window, is opened
by choosing either Data I Inspect or Inspect from a local menu.
Windows from the View To the left is a list of the fifteen types of windows you can open
menu from the View menu.
Breakpoints Once you have opened one or more of these windows, you can
Stack
Log move, resize, close, and otherwise manage them with commands
Watches
Variables
from the Window and = (System) menus, which are discussed
Module... F3 later in this chapter in the section "Working with windows."
File ••.
CPU
Dump
Registers Breakpoints window
Numeric processor
Execution history Displays the breakpoints you have set. A breakpoint defines a
Hierarchy
Windows messages location in your program where execution stops so you can
Clipboard
Another ~ examine the program's status. The left pane lists the position of
every breakpoint (or indicates that it is global), and the right pane
See Chapter 7 for a indicates the conditions under which the currently highlighted
complete description of this
breakpoint executes.
type of window and how
breakpoints work. Use this window to modify, delete, or add breakpoints.
Log window
Chapter 7 tells you more Displays the contents of the message log. The log contains a
about the Log window.
scrolling list of messages and information generated as you work
in TDW. It tells you such things as why your program stopped,
the results of breakpoints, the contents of windows you saved in
the log, and Windows information.
You can also use the log window to obtain information about
memory usage and modules for a Windows application.
This window lets you look back into the past and see what led up
to the current state of affairs.
Watches window
See Chapter 6 for more Displays variables and expressions and their changing values.
about the Watches window.
You can add a variable to the window by pressing Ctrl-Wwhen the
cursor is on the variable in the Module window.
Variables window
Chapter 5 describes the Displays all the variables accessible from a given spot in your pro-
Variables window in more
detail.
gram. The upper pane has global variables; the lower pane shows
variables local to the current function or module, if any.
This window is helpful when you want to find a function or
variable that you know begins with, say, "abc," and you can't
remember its exact name. You can look in the global Symbol pane
and quickly find what you want.
File window
You can learn more about Displays the contents of a disk file. You can view the file either as
the File window in Chapter 8.
raw hex bytes or as ASCII text, and you can search for specific text
or byte sequences.
CPU window
Chapter 12 discusses the Displays the current state of the central processing unit (CPU).
CPU window and assembler-
This window has six panes: one that contains disassembled
/eve/ debugging.
machine instructions, one that shows the contents of a selector,
one that shows hex data bytes, one that displays a raw stack of
hex words, one that lists the contents of the CPU registers, and
one that indicates the state of the CPU flags.
The CPU window is useful when you want to watch the exact
sequence of instructions that make up a line of source code or the
bytes that comprise a data structure. If you know assembler code,
this can help locate subtle bugs. You do not need to use this
window to debug the majority of programs.
TDW sometimes opens a CPU window automatically if your
program stops in Windows code or on an instruction in the
middle of a line of source code.
Dump window
See Chapter 12, which Displays a raw display of an area of memory. (This window is the
discusses assembler
debugging, for more on this
same as the Data pane of a CPU window.) You can view the data
window. as characters, hex bytes, words, doublewords, or any floating-
point format. You can use this window to look at some raw data
when you don't need to see the rest of the CPU state or to gain
direct access to I/ 0 ports. The local menu has commands to let
Registers window
Chapter 72, which discusses Displays the contents of the CPU registers and flags. This window
assembler debugging, has
more information on this
has two panes, which are the same as the registers pane and flags
window. pane, respectively, of a CPU window. Use this window when you
want to iook at the contents of the registers but don't need to see
the rest of the CPU state. You can change the value of any of the
registers or flags through commands in the local menu.
Hierarchy window
Lists and displays a hierarchy tree of all classes used by the
~
See Chapter 70 for more
current module. The window has two panes: one for the class list,
information about using the the other for the class hierarchy tree. This window shows you the
Hierarchy window. relationship of the classes used by the current module. By using
Clipboard window
See page 36 for an Displays the items that have been clipped into the Clipboard,
explanation of how to use
showing you their types and allowing you to inspect or delete an
the Clipboard.
item and to freeze the value of any item in the Clipboard.
Duplicate windows
Module •••
You can also open duplicates of three types of windows-Dump,
Dump File, and Module-by choosing View IAnother. This lets you keep
File ..•
track of several separate areas of assembly code, different files the
program uses or generates, or several distinct program modules
at once.
Don't be alarmed if TDW opens one of these windows all by itself.
It will do this in some cases in response to a command.
User screen The User screen shows your program's full output screen. The
screen you see is exactly the same as the one you would see if
your program was running directly under Windows and not
underTDW.
Alt·F5 is the hot key that You can use this screen to check that your program is at the place
toggles between the
environment and the User
in your code that you expect it to be, as well as to verify that it is
screen. displaying what you want on the screen. To switch to the User
screen, choose Window IUser Screen. After viewing the User
screen, press any key to go back to the debugger screen.
The active window Even though you can have many windows open in TDW at the
same time, only one window can be active. You can spot the active
window by the following criteria:
• The active window has a double outline around it, not a single
line.
•The active window contains the cursor or highlight bar.
• If your windows are overlapping, the active window is the
topmost one.
When you issue commands, enter text, or scroll, you affect only
the active window, not any other windows that are open.
unsigned int
unsigned lon
•=um
ds :0000 00 00 00 00 00 00 50 lE
InitWinCrt( [[ ds:0008 00 00 C2 OA 2C lE 2C lE
iilines = O; ds:OOlO 00 00 08 00 00 00 4D OA
nwords = O; ds:0018 66 OA 36 OA 80 00 01 00
total charact
showar~s ( argc, argv ;
while (readalineTl != OJ {
wordcount = makeintowords(buffer);
nwords += wordcount;
What's in a window A window always has most or all of the following features, which
give you information about it or let you do things to it:
Figure 2.4 ZoOll and
Window Iconlze
A typical window Close box Title number boxes
~ ~ ~ ~
[•]=Module: TDDEMO File: TDDEMO.C 37========l=[t] [~]
static void showargs(int argc, char •argv[]);
/• program entry point
•/
~ int PASCAL Wi nMai n (HANDLE hlnstance, HANDLE hPrevinstance,
LPSTR l pszCmdli ne, int nCmdShow )
unsigned int nlines, nwords, wordcount;
unsigned long totalcharacters;
InitWinCrt();
iilines = 0;
nwords = O; + Scroll bar
total characters = O;
showarQs( argc, argv);
while (readalineT) != OJ {
wordcount = makei ntowords (buffer); ,.
IL<QllllllJIMllllllllillilliRllliiliililllliiiiiililrilllBllllll~~
t t
Scroll bar Resize box
Working with windows With all these different windows to work with, you will probably
have several open onscreen at a time. TOW makes it easy for you
to move from one window to another, move them around, pile
them on top of one another, shrink them to get them out of your
way, expand them to work in them more easily, and close them
when you are through.
Press Alt-Spacebar to open the Most of the window-management commands are in the Window
=menu, or Aff-W to open the menu. You'll find a few more commands in the = (System) menu,
Window menu.
the menu marked with the =icon at the far left of the menu bar.
Window hopping
Each window that you open is numbered in the upper right
corner. Usually, the Module window is window 1 and the
Watches window is window 2. Whatever window you open after
that will be window 3, and so on.
This numbering system gives you a quick, easy means of moving
from one window to another. You can make any of the first nine
open windows the active window by pressing Alt in combination
with the window number. If you press Alt-2, for example, to make
Copying and
pasting TOW has an extensive copy and paste feature called the
Clipboard. With the Clipboard you can copy and paste between
TOW windows and dialog boxes.
The items you copy into the Clipboard are dynamic; if an item has
an associated value, the Clipboard keeps that value current as it
changes in your program.
You can use the Ins key to To copy an item into the Clipboard, position the cursor on the
mark multiple items in a list. item or highlight it with the Ins key, then press Shift-F3. To paste
something into a window or dialog box from the Clipboard, press
The Pick dialog box Pressing Shift-F4 er the Clip butter. brings up a dialcg box listing
Clipboard contents and showing the categories you can use for
pasting an item into the dialog box.
Figure 2.5
The Pick dialog box
The leftmost field of this window describes the type of the entry,
followed by a colon and the clipped item. If the clipped item is an
expression from the Watches window, a variable from the
Inspector window, or data, a register, or a flag from the CPU
window, the item is followed by its value or values.
String A text string, like a marked block from the File window
Module A module context, including a source code position,
like a variable from the Module window
File A position in a file (in the File window) that isn't a
module in the program
CPU code An address and byte list of executable instructions
from the Code pane of the CPU window
CPU data An address and byte list of data in memory from the
Data pane of the CPU window or the Dump window
CPU stack A source position and stack frame from the Stack pane
of the CPU window
CPU register A register name and value from the Register pane of
the CPU window or the Registers window
CPU flag A CPU flag value from the Flags pane of the CPU
window
Inspector One of the following:
A variable name from an Inspector window
A constant value from an Inspector or Watches
window
Inspect If you're in the Clipboard window and you press Alt-F10 or click
Remove the right mouse button, you see the menu at the left. Alterna-
Delete all tively, you can press Ctr/ and the highlighted key of the local menu
Freeze
command to execute a command.
Table 2.3
Clipboard local menu Command Description
commands Inspect Positions the cursor in the window from which the
item was clipped.
Remove Removes the highlighted item or items. Pressing Del has
the same effect on a highlighted item.
Delete All Deletes everything in the Clipboard.
Freeze Stops the Clipboard item from being dynamically
updated.
Dynamic updating
The Clipboard dynamically updates any item with an associated
value, such as an expression from the Watches window, a variable
from the Inspector window, or a register from the CPU window.
You can use the Clipboard as a large Watches window if you
wish, and you can freeze the value of any item you like.
See Chapter 6 for more For example, you might want to put a Watches window
information on watching
expression in the Clipboard. To do so, first put it in the Watches
expressions.
window, then press Shift-F3 to copy it into the Clipboard. The
value of the item then changes just as it would in a Watches
window, unless you use the local menu Freeze command to
disable the watchpoint.
Tips for using the The possible uses of the Clipboard are too numerous to list here.
Clipboard Some of the things you can do with it are
•clipping from lines in Module windows as a way of marking
locations that you can later return to using the local menu Goto
command (by pasting a location into the dialog box displayed
by the Goto command)
• watching an expression (see the previous section)
• pasting new values into variables using the Data I Evaluate
dialog box or the dialog box for the Change command of the
Inspector window or the Watches window
• pasting strings into the Log window to help you keep track of
what you did during a debugging session
•pasting an address (the location category of an item) into any of
the places where an address is requested (such as the
Breakpoints I Options dialog box Address field, or the Run I
Execute To dialog box)
• pasting expressions into conditions and actions of breakpoints
• pasting parameters into the Run I Arguments dialog box
• pasting a Window proc name or an OWL object name into the
Windows Messages window
•pasting a string into the dialog box for the Module window
Search command
•copying data from and pasting it to the CPU data pane
• copying code from one part of the CPU window to another and
then running the program with the copied code
Getting help
As you've seen, TOW goes out of its way to make debugging easy
for you. It doesn't require you to remember obscure commands; it
keeps lists of what you type, in case you want to repeat it; it lets
you define macros; and it offers sophisticated control of your
windows. To avoid potential confusion, TOW offers the following
help features:
Index Shi ft-Fl You can also access the onscreen help feature by choosing Help
Previous topic Alt-Fl from the menu bar (Alt-H).
Help on help
If you want to return to a previous Help screen, press Alt-Ft or
choose Previous Topic from the Help menu. From within the
Help system, use PgUp to scroll back through up to 20 linked help
screens. (PgDn only works when you're in a group of related
screens.) To access the Help Index, press Shift-Ft (or Ft from within
The status line Whenever you're in TOW, a quick-reference help line appears at
the bottom of the screen. This status line provides at-a-glance
keystroke or menu command help for your current context.
In a window
The normal status line shows the commands performed by the
function keys and looks like this:
If you hold down the Alt key for a second or two, the commands
performed by the Alt keys are displayed.
Figure 2.8
The status line with Alt pressed A1t' F2a!IBEIF3lilill!IF4&11F!ill!lli'mF6mrilF7llililaFl!IDIF91BFlOIBI
If you hold down the Ctr/ key for a second or two, the commands
performed by the Ctr/ letter keys are displayed. This status line
changes depending on the current window and current pane, and
it shows the single-keystroke equivalents for the current local
menu. If there are more local menu commands than can be
described on the status line, only the first keys are shown. You
can view all the available commands on a local menu by pressing
Alt-F10to pop up the entire menu.
Figure 2.9
The status line with Ctrl Ctrl' 1 ~FIDl!llPIH411FU•Lllasmt41M
pressed
A quick example
If you're eager to use TDW and aren't the sort of person to work
through the whole manual first, this chapter gives you enough
knowledge to debug your first program. Once you've learned the
basic concepts described here, the integrated environment and
context-sensitive Help system make it easy to learn as you go
along.
This chapter leads you through all TDW's basic features. After
describing the demo program TDDEMO provided on the
distribution disks, it shows you how to
• run and stop program execution
• examine the contents of program variables
•look at complex data objects, like arrays and structures
• change the value of variables
TDW loads the demo program, displays the startup screen, and
positions the cursor at the start of the program.
Figure 3.1
The startup screen showing
TD DEMO
/* program entry point
*/
.. int main(int argc, char **argv) {
unsigned int nlines, nwords, wordcount;
unsigned 1ong tota lcharacters;
nlines = O;
nwords = O;
totalcharacters • O;
showargs(argc, argv);
while (readaline() != O) {
wordcount = makei ntowords (buffer);
nwords += wordcount;
totalcharacters += analyzewords(buffer);
nl ines++;
The startup screen consists of the menu bar, the Module and
Watches windows, and the status line.
Using TDW
The menus
The top line of the screen shows the menu bar. To pull down a
menu from it, press FtO. Then, to choose a menu command, you
can either use f- or ~ to highlight your selection and press Enter,
or press Alt in combination with the highlighted letter of one of the
menu names.
Figure 3.2
The menu bar
Press FtO now. Notice that the cursor disappears from the Module
window, and the = command on the menu bar becomes high-
lighted. The bottom line of the screen also changes to indicate
what sort of functions the =menu performs.
Use the arrow keys to move around the menu system. Press t to
pull down the menu for the highlighted item on the menu bar.
You can also open a menu by clicking an item in the menu bar
with your mouse.
Press Esc to move back through the levels of the menu system.
When just one menu item on the menu bar is highlighted, pres-
sing Esc returns you to the Module window, with the menu bar
no longer active.
The windows
The window area takes up most of the screen. This area is where
you examine various parts of your program through the different
windows.
The display starts up with two windows: a Module window and
the Watches window. Until you open more windows or adjust
these two, they remain tiled, filling the entire screen without
overlapping. New windows automatically overlap existing
windows until you move them.
Setting
breakpoints Another way to control where your program stops running is to
set breakpoints. The simplest way to set a breakpoint is with the
[ill F2 key. Move the cursor to line 44 and press F2. TDW highlights
the line, indicating there is a breakpoint set on it.
You can also use the mouse to toggle breakpoints by clicking the
first two columns of the Module window.
I
r,=[iJ=MOOiiTe: TDDEMO Fire;=tddemo.c 4 l=LfJ [+]=;i
nwords = 0; •
totalcharacters = O;
showargs(argc, ar9v);
while (readal ine() != O) (
wordcount = makei ntowords (buffer); •
nwords += wordcount;
tota lcharacters += ana lyzewords (buffer);
.. nlines++;
I
pri ntstati sti cs (nl i nes, nwords, totalcharacters);
return (0);
=====
G ~
•
Now press F9 to execute your program without interruption. The
screen switches to the program's display. The demo program is
now running and waiting for you to enter a line of text. Type abc,
a space, def, and then press Enter. The display returns to the TDW
screen with the arrow on line 44, where you set a breakpoint that
has stopped the program. Now press F2 again to toggle it off.
See Chapter 7 for a complete description of breakpoints, including
conditional and global breakpoints.
Using watches
The Watches window at the bottom of the screen shows the value
[]D[]QJ of variables you specify. For example, to watch the value of the
variable nwords, move the cursor to the variable name on line 42
and choose Watch from the Module window local menu (bring it
up with A/t-F10 or the right-hand mouse button, or use the shortcut
Ctrl-W).
I
[• ,.f.lodu e: TDDEMO Fi e: tddemo.c 4 l=lfJ [+]=;i
window nwords = O; '"
total characters = 0;
showargs(argc, ar9v);
while (readaline(J I= O) {
wordcount = makeintowords(buffer);
nwords += wordcount;
total characters += anal yzewords (buffer);
""' nlines++;
}
l
printstati sti cs(nl ines, nwords, totalcharacters);
return(O);
Examining simple
C data objects Once you have stopped your program, there are a number of
ways of looking at data using the Inspect command. This facility
lets you examine data structures in the same way that you
visualize them when you write a program.
The Inspect commands (in various local menus and in the Data
menu) let you examine any variable you specify. Suppose you
want to look at the value of the variable nlines. Move the cursor so
it is under one of the letters in nlines and choose Inspect from the
Module window local menu (press Ctr/-/). An Inspector window
pops up.
while readaline( I• 0) {
... 1-
lEADY
wordcount • makeintowords(buffer);
nwords += wordcount;
.. totalcharacters +• analyiewords(buffer);
nlines++;
}~ ers);
printstati fil793E:FFCO
return(O);
}
liSii
F F3M1lf4l!l!!Pf
uiii:Uilb\nt;;u
' ' F•"'!,'Jlmfl
,,21
The title tells you the variable name; the next line shows you its
address in memory. The third line shows you what type of data is
stored in nlines (it's a C unsigned int). To the right is the current
value of the variable.
Now, having examined the variable, press Esc to close the
Inspector window. You can also use Alt-F3to remove the Inspector
window, just like any other window, or you can click the close
box with your mouse.
Let's review what you actually did here. By pressing Ctr/, you took
a shortcut to the local menu commands in the Module window.
Pressing I specified the Inspect command.
To examine a data item that is not conveniently displayed in the
Module window, choose Data IInspect. A dialog box appears,
asking you to enter the variable to inspect. Type :ietterinfo and
press Enter. An Inspector window appears, showing the values of
the letterinfo array elements. The title of the Inspector window
shows the name of the data you are inspecting. The first line
under the title is the address in main memory of the first element
of the array letterinfo. Use the arrow keys to scroll through the 26
elements that make up the letterinfo array. The next section shows
you how to examine this compound data object.
When you place the cursor over one of the member names, the
data type of that member appears in the bottom pane of the
Inspector window. If one of these members were in turn a com-
pound data object, you could issue an Inspect command and dig
down further into the data structure.
Press Alt-F3 to remove both Inspector windows and return to the
Module window. (Alt-F3 is a convenient way of removing several
Inspector windows at once. If you had pressed Esc, only the latest
Inspector window would have been deleted.)
Changing C data
values So far, you've learned how to look at data in the program. Now,
let's change the value of data items.
Use the arrow keys to go to line 38 in the source file. Place the
cursor at the variable totalcharacters and press Ctr/-/ to inspect its
-
the Inspector's local menu, and choose the Change option. (You
could also have done this directly by pressing Ctr/-C.) A dialog box
.........,_.
appears, asking for the new value.
Figure 3.10
The Change dialog box odule: rnoEMOfi:tdd:o.c 3
static void showargs(int argc, char *argv[]);
Starting TOW
This chapter tells you how to prepare programs for debugging.
We show you how to start TOW from Windows and how to tailor
its many command-line options to suit the program you are
debugging. We explain how to make these options permanent in a
configuration file and, finally, how to return to Windows when
you are done.
Starting TDW
There are four ways to run TOW:
•If you are in Turbo C++ for Windows, you can debug the
program in the active window by choosing Run I Debugger.
You can also choose Run I Debugger Arguments if you want to
set TOW command-line arguments.
• If you are in Windows, the easiest method is to open the
appropriate program group in the Windows Program Manager
and choose the TOW icon. Then choose File I Open to load the
program you're debugging.
For this and the next option, unless TOW is in your path and
warning! your program is in your Windows directory, you must be
careful to type in the correct path for both TOW and your
application.
• If you are in Windows and you want to enter command-line
options, you can start TOW by using the Windows Program
Manager File I Run command to open the Run dialog box. Then,
in the Command Line input box, just type TDW, followed by any
command-line options and, optionally, the name of the
program you're debugging, as if you were at the DOS prompt.
• If you are at the DOS prompt, you can start TOW by entering
the following and pressing Enter:
WIN TOW [options] [progname [progargs]]
Command Action
tdw -tc:\progl progl ab Starts the debugger in the C:\PROGl
directory and loads program progl
with two command-line arguments, a
andb.
tdw prog2 -x Starts the debugger with default
options and loads program prog2
with one argument, -x.
If you simply type TDW Enter, TDW loads and uses its default
options.
Entering command-line If you start TOW from Turbo C++ for Windows and you want to
options from TCW indicate command-line options, chose Run IDebugger Arguments
to enter any TOW command-line options except the program
name and program arguments.
The program to be run in TOW is the one in the current Edit
window. If you want to enter arguments for the program before
running TOW on it, choose Run IArguments and type the
arguments in the Program Arguments window.
Running TOW
When you run TDW, it comes up in full-screen character mode,
not in a window. Despite this appearance, TDW is a Windows
application and will run only under Windows.
Unlike other applications that run under Windows, you can't use
the Windows shortcut keys (like Alt-Esc or Ctrl-Esc) to switch out of
the TDW display and run another program. However, if the appli-
cation you are debugging is active (the cursor is active in one of
its windows), you can use Alt-Esc, Ctrl-Esc, or the mouse to switch
to other programs.
¢ If you do use Ctrl-Esc to switch out of an application running
under TDW, you see the application name on the list of tasks. You
will never see TDW on the task list because TDW is not a normal
Windows task that you can switch into or out of.
Command-line options
Appendix A has an easy-to- All TDW command-line options start with a hyphen(-) and are
use list of TDW:S command-
separated from the TDW command and each other by at least one
line options.
space. You can explicitly turn a command-line option off by
following the option with another hyphen. For example, -p-
Loading the
configuration file This option loads the specified configuration file. There must not
(-C) be a space between -c and the file name.
If the -c option isn't included, TDCONFIG.TDW is loaded if it
exists. Here's an example:
TDW -cMYCFG.TDW TDDEMO
This command loads the configuration file MYCONF.TDW and
the source code for TDDEMO.
Display updating
(-d) The -d options affect the way in which display updating is
performed.
-do Runs TDW on your secondary display. View your pro-
gram's screen on the primary display, and run the
debugger on the secondary one.
-ds The default option for all displays, it's also called screen
swapping. Required for a monochrome display. Maintains
a separate screen image for the debugger and the
program being debugged by loading the entire screen
from memory each time your program is run or the de-
bugger is restarted. This technique is the most time-
consuming method of displaying the two screen images,
but works on any display hardware and with programs
that do unusual things to the display.
Mouse support
(-p) This option enables mouse support. However, since the default
for mouse support in TDW is On, you won't have much use for
the -p option unless you use TDWINST to change the default to
Off. If you want to disable the mouse, use -p-.
If the mouse driver is disabled for Windows, it will be disabled
for TDW as well, and the -p command-line option will have no
effect.
Source code
handling (-s)
-SC Ignores case when you enter symbol names, even if your
program has been linked with case sensitivity enabled.
Without the -sc option, Turbo Debugger ignores case
only if you've linked your program with the case ignore
option enabled.
This option doesn't change -sd Sets one or more source directories to scan for source files;
the starting directory. the syntax is
-sddirname[;dirname ... ]
Configuration files
See the file TDWlNST. TDW for TOW uses a configuration file to override built-in default values
a description of how to use
TDWlNST to create
for command-line options. You can use TOWlNST to set the
configuration files. options that TOW will default to if there is no configuration file.
You can also use it to build configuration files.
TOW looks for the configuration file TOCONFIG.TOW first in the
current directory, next in the TOW directory set up with the
Turbo C++ for Windows installation program, and then in the
directory that contains TOW.EXE.
If TOW finds a configuration file, the settings in that file override
its built-in defaults. Any command-line options that you supply
when you start TOW from DOS override both the corresponding
default options and any corresponding values in
TDCONFIG.TOW.
The Language
command Chapter 9 describes how to set the current expression language
and how it affects the way you enter expressions.
Stop Recording The Stop Recording command terminates the macro recording
session. Use the Alt- (Alt-Hyphen) hot key to issue this command
or press the macro keystroke that you are defining to stop
recording.
¢ Do not use the Options I Macro IStop Recording menu selection to
stop recording your macro, as these keystrokes will then be added
to your macro! (The menu item is added to remind you of the Alt-
hot key.)
Delete All Removes all keystroke macro definitions and restores all keys to
the meaning that they originally had.
Display Options
command This command opens a diaiog box in which you can set several
options that control the appearance of the TDW display.
Figure 4.1
. . .FllmmllmVll!lm. .B!Wainii#Mllm!llC~Hllii•PROMPT
The Display Options dialog [iJ=MoiliiTe7"11iiiEMOrfle: TOOEMIT.c 3r.;;;;;;,. 1 Lt] [•J=n
box static void showargs (int argc, char •argv []);
/• program entry point
•/
.. int PASCAL WinMain(HAND
LPST
Display Swapping The Display Swapping radio buttons let you choose from two
ways of controlling how the User screen gets swapped back and
forth with TDW's screen:
Smart Swap to the User screen only when display output may
occur. TDW swaps the screens any time that you step
over a routine.
Always Swap to the User screen every time the user program
runs. Use this option if the Smart option is not catching
all the occurrences of your program writing to screen.
If you choose this option, the screen flickers every time
you step through your program because TDW's screen
is replaced for a short time with the User screen.
Screen Lines These radio buttons are used to determine whether TDW's screen
uses the normal 25-line display or the 43- or SO-line display
available on EGA and VGA display adapters.
Tab Size This input box lets you set how many columns each tab stop
occupies. You can reduce the tab column width to see more text in
source files that have a lot of code indented with tabs. You can set
the tab column width from 1 to 32.
Save Options
command This command opens a dialog box from which you can save your
current options to a configuration file on disk. The options you
can save are
•your macros
• the current window layout and pane formats
• all settings made in the Options menu
TDW lets you save your options in any or all of these ways,
depending on which of the Save Configuration check boxes you
turn on:
Options Saves all settings made in the Options menu.
Layout Saves only the windowing layout.
Macros Saves only the currently defined macros.
You can also use the Save To input box to change the name of the
configuration file to which you are saving the options.
Restore Options
command Restores your options from a disk file. You can have multiple
configuration files, containing different macros, window layouts,
and so forth. You must choose a configuration file that was
created with the Save Options command or with TDWINST.
Returning to Windows
You can end your debugging session and return to the Windows
Program Manager at any time by pressing Alt-X, except when a
dialog box is active (in that case, first close the dialog box by
pressing Esc). You can also choose File IQuit.
The Variables
window You open the Variables window by choosing View I Variables.
This window shows you all the variables (names and values) that
are accessible from the current location irt your program. Use it to
find variables whose names you can't remember. You can then
use the local menu commands to further examine or change their
values. You can also use this window to examine the variables
local to any function that has been called.
Figure 5.1
CRTWINPROC$QUIUIUIL ""
The Variables window
11------1
CreateWinCrt$qv ????
Ex i tWinCrt$qv "??
In1 tWinCrt$qv ""
EGINPAINT ""
REATECAREI ""
RfA TEW I NDOh " 77
The Global pane local This local menu consists of three commands: Inspect, Change, and
menu Watch.
Inspect
Inspect Opens an Inspector window that shows you the contents of the
Change ..• currently highlighted global symbol.
Watch
If the variable you want to inspect is the name of a function, you
are shown the source code for that function, or if there is no
source file, a CPU window shows you the disassembled code.
See Chapter 6 for more If the variable you inspect has a name that is superseded by a
information on how Inspector
local variable with the same name, you'll see the actual value of
windows behave.
the global variable, not the local one. This characteristic is slightly
different than the usual behavior of Inspector windows, which
normally show you the value of a variable from the point of view
of your current program location (CS:IP). This difference gives
you a convenient way of looking at the value of global variables
whose names are also used as local variables.
Watch
See Chapter 6 for more Opens a Watches window and puts the currently selected
information on the Watches (highlighted) global symbol in the window. This command
window.
simply puts a character string in the Watches window.
The Watches window doesn't keep track of whether the variable
is local or global. If you insert a global variable using the Watch
command and later encounter a local variable by the same name,
the local variable takes precedence as long as you are in the local
variable's block. In other words, the Watches window always
shows you the value of a variable from the point of view of your
current program location (CS:IP).
The Static pane local Press the Alt-F10 key combination to pop up the Static pane's local
menu menu; if control-key shortcuts are enabled, use the Ctr/ key with
the first letter of the desired command to access it.
Inspect The Static pane has four local menu commands: Inspect, Change,
Change •.• Watch, and Show.
Watch
Show •••
Inspect
See Chapter 6 for more Opens an Inspector window that displays the contents of the
information on how Inspector
windows behave.
currently highlighted module's local symbol.
Change
See Chapter 9 for more Changes the value of the currently selected (highlighted) local
information on assignment
symbol to the value you enter in the Change dialog box. TDW
and data type conversion.
performs any data type conversion necessary, exactly as if the
assignment operator had been used to change the variable.
Watch
See Chapter 6 for more The Watch command opens a Watches window and puts the
!r:farmat!ar: or: how ~A/atches
windows behave.
currentiy seiected (h1ghhghted) static or iocal symbol in the
window.
Show
Choosing Show brings up the Local Display dialog box, which
enables you to change both the scope of the variables being
shown (static, auto, or both) and the module from which these
variables are selected.
The following radio buttons appear in this dialog box:
Static Show only static variables.
Auto Show only variables local to the current block.
Both Show both types of variables (the default).
Module Change the current module. Brings up a dialog box
showing the list of modules for the program, from
which you can select a new module.
Figure 5.2
The Local Display dialog box
The Stack window local The Stack window local menu has two commands: Inspect and
menu Locals.
Inspect
Locals
Inspect
Opens a Module window positioned at the active line in the
currently highlighted function. If the highlighted function is the
top (most recently called) function, the Module window shows
the current program location (CS:IP). If the highlighted function is
one of the functions that called the most recent function, the
cursor is positioned on the line in the function that will be
executed after the called function returns.
You can also invoke this command by positioning the highlight
bar over a function, then pressing Enter.
Locals
Opens a Variables window that shows the symbols local to the
current module, as well as the symbols local to the currently high-
lighted function. If a function calls itself recursively, there are
multiple instances of the function in the Stack window. By posi-
tioning the highlight bar on one instance of the function, you can
use this command to look at the local variables in that instance.
Figure 5.4
The Get Info text box
Global memory TOW provides you with the following information about global
information memory:
Mode Memory modes can be large-frame EMS, small-
frame EMS, and non-EMS (extended memory).
Status line messages Here are the messages you'll see on the second (status) line,
describing why your program stopped:
Stopped at_
Your program stopped as the result of a completed Run I
Execute To, Run IGo to Cursor, or Run IUntil Return
command. This status line message also appears when your
program is first loaded, and the compiler startup code in your
program has been executed to put you at the start of your
source code.
No program loaded
You started TOW without loading a program. You cannot
execute any code until you either load a program or assemble
some instructions using the Assemble local menu command in
the Code pane of a CPU window.
Trace
You executed a single source line or machine instruction with
F7 (Run ITrace).
Step
You executed a single source line or machine instruction,
skipping function calls, with FB (Run IStep Over).
Breakpoint at _
Your program encountered a breakpoint that was set to stop
your program. The text after "at" is the address in your pro-
gram where the breakpoint occurs.
Window message breakpoint at_
Your program encountered a Windows message breakpoint
that was set to stop your program. The text after "at" is the
window procedure the message was destined for.
Run
Runs your program at full speed. Control returns to TDW when
[ff] one of the following events occurs:
•Your program terminates.
•A breakpoint with a break action is encountered.
•You interrupt execution with Ctrl-Alt-SysRq.
Goto Cursor
Executes your program up to the line that the cursor is on in the
current Module window or CPU Code pane. If the current
window is a Module window, the cursor must be on a line of
source code.
Trace Into
Executes a single source line or assembly level instruction. If the
current window is a Module window, a single line of source code
is executed; if it's a CPU window, a single machine instruction. If
the current line contains any function calls, TDW traces into the
routine. If the current window is a CPU window, pressing Fl on a
CALL instruction steps to the routine being called
Turbo Debugger treats a class member function just like any other
function. Fl traces into the source code if it's available.
Execute To
Executes your program until the address you specify in the dialog
box is reached. The address you specify might never be reached if
a breakpoint action is encountered first or you interrupt
execution.
Until Return
Executes until the current function returns to its caller. This is
useful in two circumstances: When you have accidentally exe-
cuted into a function you aren't interested in with Run I Trace
instead of Run I Step, or when you've determined that the current
Animate
Performs a continuous series of Trace Into commands, updating
the screen after each one. (The effect is to run your program in
slow motion.) You can watch the current location in your source
code and see the values of variables changing. Press any key to
interrupt this command.
After you choose Run I Animate, TOW prompts you for a time
delay between successive traces. The time delay is measured in
tenths of a second; the default is 3.
Back Trace
If you are tracing (F7 or Alt-Fl) through your program, Back Trace
reverses the order of execution. Reverse execution is handy if you
trace beyond the point where you think there may be a bug, and
want to reverse program execution back to that point. This feature
Some restrictions apply to lets you "undo" the execution of your program by stepping
using the Execution History
window. See page 82 for
backward through the code, either a single step at a time or to a
more information. specified point highlighted in the Execution History window.
Reverse execution is always available in the CPU window.
However, you can only execute source code in reverse if full
history is On. (Use the View I Execution History command to
bring up the Execution History window, then in the local menu
set Full History On.)
TOW will not execute in reverse any Windows code called by
your program unless you are in the CPU window and the code is
in a DLL you have selected for debugging.
Instruction Trace
Executes a single machine instruction. Use this command when
you want to trace into an interrupt, or when you're in a Module
window and you want to trace into a procedure or function that's
in a module with no debug information (for example, a library
routine).
Since you will no longer be at the start of a source line, this
command usually places you in a CPU window.
Program Reset
Reloads from disk the program you're debugging. You might use
.,_i..,.; ..... ,... ...... _...--~-....l
Ui..li.'.) LU.l.ll11la.tlU
•When you've executed past the place where you think there is a
bug.
•When your program has terminated and you want to run it
again.
•If you're in a Module or CPU window, you've suspended your
Windows application program with Ctr/-A/t-SysRq, and you want
to terminate it and start over.
•If you've already loaded your application, you've just set
startup debugging for one or more dynamic link libraries
(DLLs), and you now want to debug those DLLs.
If you're in a Module or CPU window, the debugger sets the
current-line marker at the start of the program, but the display
stays exactly where you were when you chose Program Reset.
This behavior makes it easier for you to set the cursor near where
you were and run the program to that line.
If you chose Program Reset because you just executed one source
statement more than you intended, you can position the cursor up
a few lines in your source file and press F4 to run to that location.
Alternatively, if Full History had been on (see the local menu of
the View I Execution History window), you could have chosen
Run I Back Trace to step back through previously executed code
instead of choosing Program Reset.
Inspect
Reverse execute Inspect
Full history No This command takes you to the command highlighted in the
Instructions pane. If it is a line of source code, you are shown that
line in the Module window; if there is no source code, the CPU
window opens, with the instruction highlighted in the Code pane.
Reverse Execute
This command reverses program execution to the location
~[ill highlighted in the Instructions pane. If you selected a line of
Full History
This command is a toggle. If it is set to On, backtracing is enabled.
If it is Off, backtracing is disabled.
Program termination
When your program terminates and exits back to Windows, TDW
regains control. It displays a message showing the exit code that
your program returned to Windows. Once your program
terminates, using any of the Run menu options causes TDW to
reload your program.
The segment registers and stack are usually not correct when your
program has terminated, so do not examine or modify any pro-
gram variables after termination.
bi dsp.exe
donuthin.exe
dotota l . exe myprogs
drwhappy. exe
echo.exe
hell o.exe
little.exe
mytest.exe
pwrs.exe
reverse. exe
small .exe
tcdemo.exe
You can enter a file name (extension .EXE) in the File Name input
box, or press Enter to activate a list box of all the .EXE files in the
current directory. Move the highlight bar to the file you want to
load and press Enter.
Inspect .•• The Data menu lets you choose how to examine and change pro-
Evaluate/modify ..• Ctrl-F4 gram data. You can evaluate an expression, change the value of a
Add watch... Ctrl-F7
Function return variable, and open Inspector windows to display the contents of
your variables.
Inspect
Prompts you for the variable that references the data you want to
inspect, then opens an Inspector window that shows the contents
of the program variable or expression. You can enter a simple
variable name or a complex expression.
If the cursor is on a variable in a text pane when you issue this
command, the dialog box automatically contains the variable at
the cursor, if any. If you select an expression in a text pane (using
Ins), the dialog box contains the selected expression.
Inspector windows really come into their own when you want to
examine a complicated data structure, such as an array of
structures or a linked list of items. Since you can inspect items
within an Inspector window, you can "walk" through your pro-
gram's data objects as easily as you scroll through your source
code in the Module window.
¢ See the "Inspector windows" section later in this chapter for a
complete description of how Inspector windows behave.
Evaluate/Modify
Opens the Evaluate/Modify dialog box (Figure 6.1), which
See Chapter 9 for a
prompts you for an expression to evaluate, then evaluates it
complete discussion of exactly as the compiler would during compilation when you
expressions. choose the Eval button.
If the cursor is in a text pane when you issue this command, the
dialog box automatically contains the variable at the cursor, if
any. If you select an expression (using Ins), the dialog box contains
the marked expression.
See Chapter 9 for a Remember that you can add a format control string after the
discussion of format control.
expression you want to watch. TDW displays the result in a
format suitable for the data type of the result. To display the
result in a different format, put a comma (,) separator, then a
format control string after the expression. Displaying in a
different format is useful when you want to watch something, but
your program displays it in a format other than TDW's default
display format for the data type.
The dialog box has three fields.
•In the top field, you type the expression you want to evaluate.
This field is the Evaluate input box, and it has a history list just
like any other input box.
•The middle field displays the result of evaluating your
expression.
•The bottom field is an input box where you can enter a new
value for the expression. If the expression can't be modified,
this box reads <Not available>, and you can't move your cursor
into it.
Your entry in the New Value input box takes effect when you
choose the Modify button. Use Tab and Shift-Tab to move from one
box to another, just as you do in other dialog boxes. Press Esc from
inside any input box to remove the dialog box, or click the Cancel
button with your mouse.
Data strings too long to display in the Result input box are termi-
nated by an arrow(•). You can see more of the string by scrolling
to the right.
If you're debugging a C++ program, the Evaluate/Modify dialog
box also lets you display the members of a class instance. You can
use any format specifier with an instance that can be used in
evaluating a record.
point APoint;
you could enter any of these expressions in Turbo Debugger's
Evaluate window:
Expression Result
APoint.x int 2 (Ox2)
APoint class point (1,2,27489)
APoint.MoveTo void() @6B61:0299
APoint.Show int() @6B61:0285
APoint.Show() int 1 (Oxl)
Expressions with side effects The C language has a feature called expressions with side effects that
can be powerful and convenient, as well as a source of surprises
and confusion.
An expression with side effects alters the value of one or more
variables or memory areas when it is evaluated. For example, the
increment(++) and decrement(·-) operators and the assignment
operators (=, +=, and so on) have this effect. If you execute
functions in your program within a C expression (for example,
myfunc(2)), note that your function can have unexpected side
effects.
If you don't intend to modify the value of any variable but merely
want to evaluate an expression containing some of your program
variables, don't use any of the operators that have side effects. On
the other hand, side effects can be a quick and easy way to change
Add Watch
Prompts you for an expression to watch, then places the expres-
sion or program variable on the list of variables displayed in the
Watches window when you press Enter or choose the OK button.
If the cursor is in a text pane when you issue this command, the
dialog box automatically contains the variable at the cursor, if
any. If you select an expression (using Ins), the dialog box contains
the selected expression.
Function Return
Shows you the value the current function is about to return. Use
this command only when the function is about to return to its
caller.
The return value is displayed in an Inspector window, so you can
easily examine return values that are pointers to compound data
objects.
Function Return saves you from having to switch to a CPU
window to examine the return value placed in the CPU registers.
And since TOW also knows the data type being returned and
formats it appropriately, this command is much easier to use than
a hex dump.
The Watches
window local As with all local menus, press Alt-F10to pop up the Watches
window local menu. If you have control-key shortcuts enabled,
menu
press Ctr/ with the first letter of the desired command to access it.
Watch •••
Edit •••
Remove
Delete all
Inspect
Change •••
Watch Prompts you for the variable name or expression to add to the
Watches window. It is added at the current cursor location.
Edit Opens a dialog box in which you can edit an expression in the
Watches window. You can change any watch expression that's
there, or enter a new one.
You can also invoke this command by pressing Enter once you've
positioned the highlight bar over the watch expression you want
to change. Press Enter or choose the OK button to put the edited
expression into the Watches window.
Remove Removes the currently selected item from the Watches window.
Delete All Removes all the items from the Watches window. This command
is useful if you move from one area of your program to another,
and the variables you were watching are no longer relevant.
(Then use the Watch command to enter more variables.)
Inspector windows
An Inspector window displays your program data appropriately,
depending on the data type you're inspecting. Inspector windows
behave differently for scalars (for example, char or int), pointers
(char*), arrays (long x[4]), functions, and structures.
The Inspector window lists the items that make up the data object
being inspected. The title of the window shows the expression or
the name of the variable being inspected.
The first item in an Inspector window is always the memory
address of the data item being inspected, expressed as a segment:
offset pair, unless it has been optimized to a register or is a
constant (for example, 3).
To examine the contents of a variable in an Inspector window as
raw data bytes, choose View I Dump while you're in the Inspector
window. The Dump window comes up, with the cursor posi-
tioned to the data displayed in the Inspector window. You can
return to the Inspector window by closing the window with the
Window I Close command (Alt-F3), or clicking the close box with
your mouse.
The following sections describe the different Inspector windows
that can appear for two of the languages supported by TOW: C++
and assembler. The programming language used dictates the
format of the information displayed in Inspector windows. Data
items and their values always appear in a format similar to the
one they were declared with in the source file.
Remember that you don't have to do anything special to cause the
different Inspector windows to appear. The right one appears
automatically, depending on the data you're inspecting.
Pointers Pointer Inspector windows show you the value of data items that
point to other data items, such as
char *p = "abc";
int *ip = 0;
int **ipp = &ip;
Structures and unions Structure and union Inspector windows show you the value of
the members in your structure and union data items. For
example,
struct linfo {
unsigned int count;
unsigned int firstletter;
letterinfo [26];
union {
int small;
long large;
) holder;
These Inspector windows have another pane below the one that
shows the values of the members. This additional pane shows the
data type of the member highlighted in the top pane.
liiiii
(17937:0852
A C structure or union
Inspector window
Arrays Array Inspector windows show you the value of arrays of data
items, such as ·
long thread[3] [4] [5];
char message[] = "eat these words";
There is a line for each member of the array. To the left on each
line appears the array index of the item. To the right appears the
value of the item. If the value is a complex data item such as a
structure or array, as much of it as possible is displayed.
You can use the Range local menu command to examine any
portion of an array. This is useful if the array has a lot of elements,
and you want to look at something in the middle of the array.
Figure6.6 [•]=Inspecting letterinf0=3=[t] [~]9
(17682:0852 ..
A C array Inspector window I
lliiii
A C function Inspector tl71E9:02DD
window
Assembler data
Inspector
windows
Scalars Scalar Inspector windows in assembly language programs show
you the value of simple data items, such as
VARl DW 99
MAGIC DT 4.608
BIGNUM DD 123456
These Inspector windows have only a single line of information
following the top line that gives the address of the variable. To the
left appears the type of the scalar variable (BYTE, WORD,
DWORD, QWORD, and so forth), and to the right appears its
present value. The value can be displayed as decimal, hex, or
both. It's usually displayed first in decimal, with the hex values in
parentheses (using the standard assembler hex postfix H). You
can use TDWINST to change how the value is displayed.
Flgure6.8
~]
~
An assembler scalar
Inspector window
Structures and unions Structure Inspector windows in assembler programs show you
the value of the fields in your STRUC and UNION data objects. For
example,
x STRUC
MEMl DB ?
MEM2 DD ?
x ENDS
ANX x <l,ANX>
y UNION
ASBYTES DB 10 DUP (?)
ASFLT DT ?
y ENDS
AY y <?I 1. 0>
These Inspector windows have another pane below the one that
shows the values of the fields. This additional pane shows the
data type of the field highlighted in the top pane.
Figure6.l l
An assembler structure
Inspector window
Range ••• The commands in this menu give the Inspector window its real
Change ••• power. By choosing the Inspect local menu command, for
Inspect example, you create another Inspector window that lets you go
Descend into your data objects. Other commands in the menu let you
New expression •••
Type cast ••• inspect a range of values or a new variable.
Range
Sets the starting element and number of elements that you want
to display. Use this command when you are inspecting an array,
an<l you only wanl lo look at a ('t:rtain subrange of all the
members of the array.
If you have a long array and want to look at a few members near
the middle, use this command to open the Inspector window at
the array index that you want to examine.
Change
Changes the value of the currently highlighted item to the value
you enter in the dialog box. If the current language permits it,
TOW performs any necessary casting exactly as if the appropriate
assignment operator had been used to change the variable. See
Chapter 9 for more information on the assignment operator and
casting.
Inspect
Opens a new Inspector window that shows you the contents of
the currently highlighted item. This is useful if an item in the
Inspector window contains more items itself (like a structure or
array), and you want to see each of those items.
You can also invoke this command by pressing Enter after high-
lighting the item you want to inspect.
You return to the previous Inspector window by pressing Esc to
close the new Inspector window. If you are through inspecting a
data structure and want to remove all the Inspector windows, use
the Window I Close command or its shortcut, Alt-F3.
Descend
This command works like the Inspect local menu command
except that instead of opening a new Inspector window to show
the contents of the highlighted item, it puts the new item in the
New Expression
Prompts you for a variable name or expression to inspect, without
creating another Inspector window. This lets you examine other
data without having to put more Inspector windows on the
screen. Use this command if you are no longer interested in the
data in the current Inspector window.
Inspector windows for C++ classes are somewhat different from
regular Inspector windows. See Chapter 10 for a description of
class Inspector windows.
Type Cast
Chapter 11 explains on page Lets you specify a different data type (int, char *, gh2fp, lh2fp) for
175 how to use the gh2fp
and lh2fp types.
the item being inspected. Typecasting is useful if the Inspector
window contains a symbol for which there is no type information,
as well as for explicitly setting the type for untyped pointers.
Breakpoints
TOW uses the single term "breakpoint" to refer to the group of
functions that other debuggers usually call breakpoints,
watchpoints, and tracepoints.
Traditionally, breakpoints, watchpoints, and tracepoints are
defined like this: A breakpoint is a place in your program where
you want execution to stop so that you can examine program
variables and data structures. A watchpoint causes your program
to be executed one instruction or source line at a time, watching
for the value of an expression to become true. A tracepoint causes
your program to be executed one instruction or source line at a
time, watching for the value of certain program variables or
memory-referencing expressions to change.
TOW unifies these three concepts by defining a breakpoint in
three parts:
•the location in the program where the breakpoint occurs
•the condition under which the breakpoint is triggered
• the action that takes place when the breakpoint triggers
The location can be either a single source line in your program or it
can be global in context; a global breakpoint checks the
breakpoint condition after the execution of each source line or
instruction in your program.
The condition can be
•always
•when an expression is true
Changed memory Changed Memory Global sets a global breakpoint that's triggered
global when an area of memory changes value. You are prompted for
For more information, see the the area of memory to watch with the Enter Memory Address,
"Changed Memory" section Count input box. The variable expression entered is checked for
onpage 117. change each time a line of source code is executed.
Expression true global Expression True Global sets a global breakpoint that is triggered
when the value of a supplied expression is true (nonzero). You are
For more information, see
"Conditional Breakpoints" on prompted for the expression to evaluate with the Enter
page 778. Expression for Condition Breakpoint input box. The expression
entered is evaluated each time a line of source code is executed.
Hardware breakpoint Use this command to access the Hardware Breakpoints Options
For more information on
dialog box. You must have the proper system setup in order to
hardware debugging, see use hardware debugging.
page 178.
Delete all The Delete All command erases all the breakpoints you've set. Use
this command when you want to start over from scratch.
The Breakpoints window has two panes; the Breakpoint List (left
pane) shows a list of all the addresses at which breakpoints are set
and the Breakpoint Detail (right pane) shows the details of the
breakpoint highlighted in the left pane. Although a breakpoint
can have several sets of actions and conditions associated with it,
only the first set of details is displayed in the Breakpoint Detail
pane.
The Breakpoints window has a local menu, which you access by
pressing Alt-F10when inside the left pane. If you have control-key
shortcuts enabled, press Ctr/ with the first letter of the command
to access that command directly.
The Breakpoints
window local The commands in this menu let you add new breakpoints, delete
menu existing breakpoints, and change how a breakpoint behaves.
Set options •••
Add •••
Remove
Delete all
Inspect
Group ••.
Set Options Once a breakpoint is set, the Set Options command opens the
Breakpoint Options dialog box, allowing you to modify the
breakpoint. Using this box, you can
For a detailed explanation of • declare a global breakpoint
the Breakpoint Options
dialog box, see page 709. •disable/ enable the breakpoint
•attach the breakpoint to a specific group
• access the Conditions and Actions dialog box
Add The Add command on the Breakpoints local menu opens the
Breakpoint Options dialog box, much like the Set Options
command does. The difference is that the cursor is positioned on
an empty Address text box. Enter into the Address text box the
address for which you'd like the breakpoint to be set. For
Delete all Delete All removes all breakpoints, both global and those set at
specific addresses. You will have to set more breakpoints if you
want your program to stop on a breakpoint. Use this command
with caution!
Inspect The Inspect command displays the source code line or assembler
instruction that corresponds to the currently highlighted break-
point item. If the breakpoint is set at an address that corresponds
to a source line in your program, a Module window is opened
and set to that line. Otherwise, a CPU window is opened, with the
Code pane set to show the instruction at which the breakpoint is
set.
You can also invoke this command by pressing Enter once you
have the highlight bar positioned over a breakpoint.
Chapter 7, Breakpoints l 07
Once a breakpoint is created, you may modify the breakpoint
group number from the Breakpoint Options dialog box, placing
the breakpoint into a group associated with other breakpoints.
Grouping breakpoints together allows you to enable, disable, or
remove a collection of breakpoints with a single action.
When the Group command is chosen from the Breakpoint
window's local menu, the Edit Breakpoint Groups dialog box is
displayed. This dialog box shows a listing of the current
breakpoint groups and allows you to easily collect all functions
within a module into a single group.
Groups
The Groups list box displays the currently assigned breakpoint
groups.
Add
The Add button activates the Add Group dialog box.
The Add Group dialog box has a single list box and a single set of
radio buttons that allow you to add all functions in a single
module, or all member functions in a class, to a breakpoint group.
•The Module/Class list box displays a list of the modules or
classes contained in the program loaded into the Module
window. Highlight the desired module or class, then press OK
Delete
The Delete button in the Edit Breakpoint Groups dialog box
removes the group currently highlighted in the Groups list box.
All breakpoints in this group, along with their settings, will be
erased.
Enable
The Enable button activates a breakpoint group that has been
previously disabled.
Disable
The Disable command temporarily masks the breakpoint group
that is currently highlighted in the Groups list box. Breakpoints
that have been disabled are not erased; they are merely set aside
for the current debugging session. Enabling the group reactivates
all the settings for all the breakpoints in the group.
The Breakpoint
Options dialog The Breakpoint Options dialog box is reached from the
Breakpoints IAt command, and from the Set Options and Add
box
commands on the Breakpoints window local menu.
Address The Address text box contains the address tag associated with the
currently highlighted breakpoint. Normally, you will not edit this
field. However, if you want to change the name of the tag
associated with the breakpoint, type the new name into the
Address text box.
Group ID The Group ID text box allows you to assign the current
See page 107 for a breakpoint to a new or existing group. A breakpoint group is
description of breakpoint identified by a unique positive integer.
groups.
Global Global, when checked, enables global checking. This means that
every time a source line is executed, the breakpoint conditions
will be checked for validity. Because global breakpoints are tested
after every line of code is executed, the Address field is set to <not
available> since it is no longer pertinent.
For more Information on When you set a global breakpoint, you must set a condition that
global breakpoints, see
page 116.
will trigger the global breakpoint. Otherwise, you'll end up with a
breakpoint that activates on every line of source code (if this is the
effect you want to achieve, use the Run I Trace Into command on
the Main menu).
Disabled The Disabled check box turns off the current breakpoint. While
this command is similar to the Toggle command on the
Breakpoints menu (see page 105), Disable does not clear the
breakpoint of its settings (as does the Toggle command). Disable
simply masks the breakpoint until you want to reenable it by
unchecking this box. When the breakpoint is reenabled, all
settings previously made to the breakpoint will become effective.
This check box is useful if you have defined a complex breakpoint
that you don't want to use just now, but will want to use again
Conditions and Actions The Conditions and Actions list box displays the set of conditions
and actions associated with the current breakpoint.
Change The Change button, when selected, opens up the Conditions and
A-=tions dialog box (see the next section). 'vVilh this rnmmand, you
can edit the item currently highlighted in the Conditions and
Actions list box.
The Conditions
and Actions When you choose either the Change or the Add button from the
dialog box Breakpoint Options dialog box, you're presented with the
Conditions and Actions dialog box.
Figure 7.5
The Conditions and Actions
dialog box
See "Customizing When a breakpoint is set on a line of source code, its default
breakpoints• on page 116 for
characteristics are Always Break execution when the line of code
details on modifying
breakpoints. is encountered. With the Conditions and Actions dialog box, you
can customize the conditions under which the breakpoint will be
activated and specify different actions that take place once the
breakpoint does trigger.
The condition radio The Condition radio buttons have four settings:
buttons
Always
When Always is chosen, it indicates that no additional conditions
need be true for the breakpoint to trigger; it will be triggered each
time program execution encounters the breakpoint.
Changed memory
See page 777 for more A Changed Memory breakpoint watches a memory variable or
information on Changed
Memory breakpoints.
object; the breakpoint is triggered if the object changes value. Use
the Condition Expression input box to enter an expression
representing the data object you want to watch.
Expression true
The Expression True button allows the breakpoint to be triggered
when an expression becomes true (nonzero). Use the Condition
See page 778 for details on Expression input box to enter an expression that's evaluated each
expressions.
time the breakpoint is encountered.
Hardware
See page 778 for more Causes the breakpoint to be triggered by the hardware-assisted
information about hardware
breakpoints.
device driver. Because you can use hardware assistance only with
a global breakpoint, you must check the Global check box in the
Breakpoint Options dialog box before you can access this option.
The Hardware I Breakpoint You must select the Hardware radio button before the Hardware
command offers an easy button at the bottom of the dialog box can become active. Pushing
way to set hardware
breakpoints. that button displays the Hardware Breakpoint Options dialog
box. The choices you can make in this box are described in the
online text file HDWDEBUG.TD.
Execute
Execute causes an expression to be executed. Enter the expression
in the Action Expression input box. The expression should have
some side effect, such as setting a variable to a value. By executing
an expression that has side effects each time a breakpoint is
triggered, you can effectively "splice in" new pieces of code
before a given source line. This is useful when you want to alter
the behavior of a routine to test a diagnosis or bug fix. This saves
you from going through the compile-and-link cycle just to test a
minor change to a routine.
Of course, this technique is limited to the insertion of an expres-
sion before an already existing line of code is executed; you can't
use this technique to modify existing source lines directly.
Log
See Chapter 9 for a The Log button causes the value of an expression to be recorded
description of expressions
and side effects.
in the Log window. You are prompted for the expression whose
value you want to log. Be careful that the expression doesn't have
any unexpected side effects.
Enable group
The Enable Group action button allows for a breakpoint to
reactivate a group of breakpoints that have been previously
disabled.
Disable group
The Disable Group radio button lets you disable a group of
breakpoints. When a group of breakpoints is disabled, the
Setting conditions and The most important step when setting up breakpoints is
actions specifying the conditions under which the breakpoint triggers and
specifying the actions to be taken once the breakpoint takes effect.
Two text boxes control these settings, the Condition Expression
text box and the Action Expression text box.
Condition Expression When you choose either a Changed Memory, Expression True, or
Hardware Condition radio button, you must provide a set of
conditions so TDW knows when to trigger the breakpoint. A
condition set consists of one or more expressions; each condition
has to evaluate true in order for the whole set to evaluate true.
For more information on A condition set is associated with a set of actions. When the
specifying breakpoint
actions, see the "Action
condition set evaluates true, the corresponding action set is
Expression· section that performed.
follows.
To add a condition set to a breakpoint,
Action Expression When either an Execute, Log, Enable Group, or Disable Group
Action radio button is chosen, an action set must be provided so
TOW knows what to do when the breakpoint triggers. An action
set is composed of one or more actions.
To add an action set to a breakpoint,
Pass count The Pass Count input box lets you set the number of times the
breakpoint condition set must be met before the breakpoint is
triggered. The default number is 1. The pass count is decremented
only when the entire condition set attached to the breakpoint is
true. This means that if you set a pass count ton, the breakpoint is
triggered the nth time that the condition set is true.
Simple
breakpoints When a breakpoint is initially set, it is given the default setting of
Always Break. Once a simple breakpoint is set, the actions and
conditions of the breakpoint may be customized. There are a
number of ways to set a simple breakpoint, each one being
convenient in different circumstances:
•Move to the desired source line in a Module window (or Code
pane of a CPU window) and issue the Breakpoints I Toggle
command (or press F2, or click the line with your mouse).
Doing this on a line that already has a breakpoint set causes
that breakpoint to be deleted.
• Issue the Add local menu command from the Breakpoint List
pane of the Breakpoints window and enter a code address at
which to set a breakpoint. (A code address has the same format
as a pointer in the language you're using. See Chapter 9 about
expressions.)
•Issue the Breakpoints I At command to set a breakpoint at the
current line in the Module window.
Global
breakpoints When a breakpoint is made global, TDW will check the
breakpoint on the execution of every line of code. If the set of
conditions evaluates true, then the corresponding set of actions
will be executed.
If you want a global check to occur on every machine code
instruction, set a global breakpoint, and press F9 from within the
CPU window. This type of code monitoring should only be done
once you have isolated a small area of your program known to
contain a problem. The CPU window can then be used to locate
the exact position of the difficulty.
You must check Global if you Since a debugger action will occur on every line of source code or
want to set hardware
breakpoints.
machine instruction, global breakpoints greatly slow the
Changed
memory When you want to find out where in your program a certain data
breakpoints object is being changed, first set a breakpoint using one of the
techniques outlined in the preceding section. Then, using the
Changed Memory radio button in the Conditions and Actions
dialog box, enter an expression that refers to the memory area you
want to watch along with an optional count of the number of
objects to track. The total number of bytes in the watched area is
the size of the object that the expression references times the
number of objects. For example, suppose you have declared the
following C array:
int string[81];
If you want to watch for a change in the first ten elements of this
array, enter the following item into the Condition Expression
input box:
&string[O], 10
The area watched is 20 bytes long, since an Int is 2 bytes and you
said to watch ten of them.
If the Changed Memory breakpoint is global, your program
executes much more slowly because the memory area is checked
for change after every source line has been executed. If you've
installed a hardware device driver, TDW will try to set a
hardware breakpoint to watch for a change in the data area.
Different hardware debuggers support different numbers and
types of hardware breakpoints. You can see if a breakpoint is
using the hardware by opening a Breakpoint window with the
Conditional
expressions There are many occasions when you won't want a breakpoint to
be triggered every time a certain source statement is executed,
particularly if that line of code is executed many times before the
occurrence you are interested in. TOW gives you two ways to
qualify when a breakpoint is actually triggered: pass counts and
conditions.
Scope of breakpoint Both the action that a breakpoint performs and the condition
expressions under which it is triggered can be controlled by an expression you
supply. That expression is evaluated using the scope of the
See Chapter 9 for a address at which the breakpoint is set, not the scope of the current
complete discussion of
scopes and scope overrides.
location where the program is stopped. This means that your
breakpoint expression can use only variable names that are valid
at the address in your program where you set the breakpoint,
unless you use scope overrides.
If you want to set a breakpoint for an expression in a module that
isn't currently loaded and TOW cannot find that expression, you
can use either a scope override to specify the file that contains the
expression or the View I Module command to change modules.
If you use variables that are local to a routine as part of an expres-
sion, that breakpoint will execute much more slowly than a break-
point that uses only global or module local variables.
Hardware
breakpoints A hardware breakpoint uses hardware debugging support, either
through a hardware debugging board or through the debugging
registers of the Intel 80386 (or higher) processor. If your system is
See page 72 for information set up for hardware debugging (File I Get Info shows Breakpoints
on setting up device drivers set to Hardware), you can set a hardware breakpoint using one of
for hardware debugging.
the following methods:
• Choose Breakpoints I Changed Memory Global, the most
common use of hardware breakpoints.
•Choose Breakpoints I Hardware.
Logging variable
values Sometimes, you may find it useful to log the value of certain
variables each time you reach a certain place in your program.
For more information on the You can log the value of any expression, including, for example,
Log window, see page 120. the values of the parameters a function is called with. By looking
at the log each time the function is called, you can determine
when it was called with erroneous parameters.
Be careful of side effects Choose the Log radio button from the Breakpoint Options dialog
when logging expressions.
box. You are prompted for the expression whose value is to be
logged each time the breakpoint is triggered.
Breakpoints and
templates TOW supports breakpoints on C++ templates. Breakpoints get set
differently depending on if you use F2 in the Module window, F2
in the CPU window, or the Breakpoint Options dialog box to set
them.
Breakpoints on class There are several methods for setting breakpoints in templates:
templates
• If you set a breakpoint in the template itself by pressing F2
while the cursor is on a line of template source code in the
Module window, breakpoints are set in all class instances of
that template. This feature allows you to debug overall
behavior of the template.
Breakpoints on function You set and remove breakpoints for function templates just as you
templates do for class templates. The two methods for setting breakpoints,
pressing F2 or using the Breakpoint Options dialog box, have the
same effects on function instances as they do on class instances.
Breakpoints on You set breakpoints for template class instances and objects of
template class template class instances just like you do for ordinary classes and
instances and objects objects.
Open Log File Causes all lines written to the log to be written to a disk file as
well. A dialog box appears that prompts you for the name of the
file to write the log to (or you can select a directory and file from
the list boxes).
Close Log File Stops writing lines to the log file specified in the Open Log File
local menu command, and closes the file.
Add Comment Lets you insert a comment in the log. You are prompted for a line
of text that can contain any characters you want.
Erase Log Clears the log list. The Log window will now be blank. Only the
log in memory is affected, not the parts of the log that have been
written to a disk file.
Display Windows Info Displays the Windows Information dialog box, which lets you list
10 global heap information, local heap information, or the list of
lEll modules making up your application. See page 166 in Chapter 11
for an explanation of how to use this feature.
Examining files
TDW treats disk files as a natural extension of the program you're
debugging. You can examine any file on the disk, viewing it either
as ASCII text or as hex data.
This chapter shows you how to examine disk files that contain
your program source code and other files on disk.
The Module
window Before you can open a module window, you must have a program
loaded. You create a Module window by choosing the View I
Module command from the menu bar (or pressing the hot key, F3).
Figure 8.1 [•]=4>1odule: TDDEMO File: TDDEMO.C 37=======1=[t] [~]
static void showargs (1 nt argc, char *argv []);
The Module window
f* program entry point
*/
.. int main(int argc, char *•argv)
{
unsigned int nl ines, nwords, wordcount;
unsigned long totalcharacters;
nlines = 0;
nwords = O;
totalcharacters = O;
showargs( argc, argv);
while (readalineTl != 0) {
wordcount = makeintowords(buffer); "
nwords += wordcount; "
totalcharacters += analyzewords(buffer); "
See page 769 for a A dialog box appears in which you can enter the name of the
description of this Dialog box.
module or OLL you want to view.
When you run TOW, you need TOW then loads the source file for the module you select. If you
both the .EXE file and the select a source module (and not a OLL), TOW searches for the
original source file.
source file in the following places:
Module windows show the contents of the source file for the
module you've selected. The title of the Module window shows
the name of the module you're viewing, along with the source file
name and the line number the cursor is on. An arrow <~) in the
first column of the window shows the current program location
(CS:IP).
The Module
window local The Module window local menu provides a number of com-
menu mands that let you move around in the displayed module, point
at data items and examine them, and set the window to display a
Inspect new file or module.
Watch
Module ... You will probably use this menu more than any other menu in
File ... TDW, so you should become quite familiar with its various
Previous options.
Line ...
Search .•. Use the Alt-F10 key combination to pop up the Module window
Next local menu. If you have control-key shortcuts enabled, you can
Origin
Goto ..• access local menu commands without popping up the menu: Use
the Ctr/ key with the highlighted letter of a command to access that
command (for example, Ctrl-S for Search).
Watch Adds the variable at the current cursor position to the Watches
window. Putting a variable in the Watches window lets you
If the cursor isn't currently on
a variable, you're prompted monitor the value of that variable as your program executes.
to enter one.
File Lets you switch to view one of the other source files that makes
up the module you are viewing. Pick the file that you want to
view from the list of files presented. Most modules only have a
single source file that contains code. Other files included in a
module usually only define constants and data structures. Use
this command if your module has source code in more than one
file.
Use View I Module to look at the first file. If you want to see more
than one, use View IAnother I Module to open subsequent Module
windows.
Previous Returns you to the last source module location you were viewing.
You can also use this command to return to your previous
location after you've issued a command that changed your
position in the current module.
Line Positions you at a new line number in the file. Enter the new line
number to go to. If you enter a line number after the last line in
the file, you will be positioned at the last line in the file.
Origin Positions you at the module and line number that is the current
program location (CS:IP). If the module you are currently viewing
is not the module that contains the current program location, the
Module window will be switched to show that module. This com-
mand is useful after you have looked around in your code and
want to return to where your program is currently stopped.
Goto Positions you at any location within your program. Enter the
address you want to examine; you can enter a procedure name or
a hex address. See Chapter 9 for a complete description of the
ways to enter an address.
If the address doesn't have a You can also invoke this command by simply starting to type the
corresponding source line, a
CPU window is opened.
label to go to. This brings up a dialog box exactly as if you had
chosen the Goto command. Entering the label name is a handy
way to invoke this frequently used command.
File windows show the contents of the file you've selected. The
name of the file you are viewing is displayed at the top of the
window, along with the line number the cursor is on if the file is
displayed as ASCII text.
When you first create a File window, the file appears either as
ASCII text or as hexadecimal bytes, depending on whether the file
contains what TOW thinks is ASCII text or binary data. You can
switch between ASCII and hex display at any time using the
Display As local menu command described later.
~ I
Figure 8.3 [•]=File ••• S\DEBUG\DEMOS\TDDEMO.C 3=[t)[~]"'il
0000: 2f 2a 09 66 69 6c 65 20 /*ofile •
The File window showing hex 0008: 3c 74 64 64 65 6d 6f 2e <tddemo. •
data 0010: 63 3e Od Oa 20 2a Od Oa c>Jll *JI
0018: 20 2a 09 44 65 6d 6f 6e *oDemon
0020: 73 74 72 61 74 69 6f 6e stration
0028: 20 70 72 6f 67 72 61 6d program
0030: 20 74 6f 20 73 68 6f 77 to show .,
•I Ill 11111111 I 111111 __)
Use the A/t-F10 key combination to pop up the File window local
menu or, if you have control-key shortcuts enabled, use the Ctr/
key with the highlighted letter of the desired command to access
the command without invoking the local menu.
File Lets you switch to a different file. You can use DOS wildcards to
get a list of file choices, or you can type a specific file name to
load. File lets you view a different file without putting a new File
window onscreen. If you want to view two different files or two
parts of the same file simultaneously, choose View IAnother I File
to make another File window.
Expressions
Expressions can be a mixture of symbols from your program (that
is, variables and names of routines), and constants and operators
from one of the supported languages: C, Pascal, or assembler.
Each language evaluates an TDW can evaluate expressions and tell you their values. You can
expression differently. also use expressions to indicate data items in memory whose
value you want to know. You can supply an expression in any
dialog box that asks for a value or an address in memory.
Use Data I Evaluate/Modify to open the Evaluate/Modify dialog
box, which tells you the value of an expression. (You can also use
this dialog box or the Watches window as a simple calculator.)
In this chapter, you'll learn how TDW chooses which language to
use for evaluating an expression and how you can make it use a
specific language. We describe the components of expressions that
are common to all the languages, such as source-line numbers and
access to the processor registers. We then describe the
components that can make up an expression in each language,
including constants, program variables, strings, and operators.
For each language, we also list the operators that TDW supports
and the syntax of expressions.
For a complete discussion of C, C++, a.nd assembler expressions,
refer to your Turbo C++ for Windows User's Guide.
Overriding scope in C, Use a pound sign (#) to separate the components of the scope.
C++, and assembler
The following syntax describes scope overriding; brackets ([])
programs
indicate optional items:
Scope operators don't work [#module[#filename.ext]]#linenumber[#variablename]
with register variables.
or
[#module[#filename.ext]#] [functionname#]variablename
If you don't specify a module, the current module is assumed.
For example, in the Watches window, you could enter different
line numbers for the TDDEMO variable nlines so you could see
how its value changes in different routines in the current module.
To watch the variable both on line 51 and on line 72, you would
make the following entries in the Watches window:
#Sl#nwords
#72#nwords
Here are some examples of valid symbol expressions with scope
overrides. There is one example for each of the legal combinations
of elements that you can use to override a scope.
or
[unit.] [objecttype.] [objectinstance.] [method.]fieldname
Scope and DLLs Because TDW simultaneously loads the symbol tables of the
current module of your .EXE file and of any DLLs it accesses that
have source code and symbol tables, you might not have
immediate access to variables in your DLLs (or in your .EXE if
you're currently in a DLL).
TDW looks for a variable first in the symbol table of the current
module or DLL, and then in any other symbol tables in order of
loading. If a variable has the same name in multiple DLLs or in
your .EXE and one or more DLLs, TDW sees only the first
instance it finds. You can't use scope override syntax to access any
Byte lists
Several commands ask you to enter a list of bytes, including the
Search and Change local menu commands in the Data pane of the
CPU window, and the Search local menu command of the File
window when it's displaying a file in hexadecimal format.
C expressions
TOW supports the complete C expression syntax. A C expression
consists of a mixture of symbols, operators, strings, variables, and
constants. Each of these components is described in one of the
following sections.
C symbols
A symbol is the name of a data object or routine in your program.
A symbol name must start with a letter (a-z, A-Z) or underscore
(_). Subsequent characters can be any of these characters as well
as the digits 0 through 9. You can omit the beginning underscore
from symbol names; if you enter a symbol name without an
underscore and TOW can't find that name, it searches for the
name again with an underscore at the beginning. Because the
compiler automatically puts an underscore at the start of your
symbol names, you don't have to remember to add one.
C register
pseudovariables mw lets you access the processor registers using the same
technique as one of Borland's C or C++ compilers, namely
pseudovariables. A pseudovariable is a variable name that
corresponds to a given processor register.
Format Radix
digits decimal
Odigits octal
OXdigits hexadecimal
Oxdigits hexadecimal
Constants are normally of type int (16 bits). If you want to define
a long (32-bit) constant, you must add an l or L at the end of the
number. For example, 123456L.
A floating-point constant contains a decimal point and can use
decimal or scientific notation. For example,
1. 23 4 4. Se+ 11
Escape
sequences A string is a sequence of characters enclosed in double quotes("").
You can use the standard C backslash(\) as an escape character.
If you follow the backslash with any other character than those
listed here, that character is inserted into the string unchanged.
I
&&
lowest II
The single ternary operator, ?:, has a priority below that of the
binary operators.
The assignment operators are below the ternary operator in
priority. They are all of equal priority, and group from right to
left:
= += -= *= I= %= >>= <<= &= "= I=
The following table shows the result of calls to this function with
different function arguments:
C expression Result
power(3,2) * 2 18
25 + power(5,8) 390650
power(2) Error (missing argument)
C expressions with
side effects A side effect occurs when you evaluate a C expression that
changes the value of a data item in the process of being evaluated.
In some cases, you may want a side effect, using it to intentionally
modify the value of a program variable. At other times, you want
to be careful to avoid them, so it's important to understand when
a side effect can occur.
The assignment operators (=, +=, and so on) change the value of
the data item on the left side of the operator. The increment and
decrement(++ and - -) operators change the value of the data
item that they precede or follow, depending on whether they are
used as prefix or postfix operators.
C reserved words
and type TDW lets you perform type conversions on (cast) pointers exactly
conversion as you would do in a C program. A type conversion consists of a C
data-type declaration between parentheses. It must come before
an expression that evaluates to a memory pointer.
Type conversions are useful if you want to examine the contents
of a memory location pointed to by a far address you generated
using the double colon (::) operator. For example,
(long far *)Ox3456::0
You can also use the Type Cast command in the Inspector
window local menu for this purpose.
TDW provides two reserved words, lh2fp and gh2fp, for
dereferencing memory handles used in Windows applications.
See page 175 for an explanation of these two type conversions.
Assembler expressions
TDW supports the complete assembler expression syntax. An
assembler expression consists of a mixture of symbols, operators,
strings, variables, and constants. Each of these components is
described in this section.
Assembler
symbols Symbols are user-defined names for data items and routines in
your program. An assembler symbol name starts with a letter (a-z,
A-Z) or one of these symbols: @ ? _ $. Subsequent characters in
the symbol can contain the digits 0 to 9, as well as these char-
acters. The period (.) can also be used as the first character of a
symbol name, but not within the name.
The special symbol $ refers to your current program location as
indicated by the CS:IP register pair.
Assembler
constants Constants can be either floating point or integer. A floating-point
constant contains a decimal point and may use decimal or scien-
tific notation. For example,
1.234 4.Se+ll
Integer constants are hexadecimal unless you use one of the
assembler conventions for overriding the radix:
Assembler
operators TOW supports most of the assembler operators. The first line in
the list that follows shows the operators with the lowest priority,
and the last line those operators with the highest priority. Within
a line, all the operators have the same priority.
xxx PTR (BYTE PTR .. .)
. (structure member selector)
: (segment override)
OR XOR
AND
NOT
EQ NE LT LE GT GE
+ -
* I MOD SHR SHL
Unary+ Unary-
OFFSET SEG
() []
Format control
When you supply an expression to be displayed, TOW displays it
in a format based on the type of data it is. TOW ignores a format
control that is wrong for a particular data type.
Character Format
c Displays a character or string expression as raw
characters. Normally, nonprinting character values are
displayed as some type of escape or numeric format.
This option forces the characters to be displayed using
the full IBM display character set.
d Displays an integer as a decimal number.
f[#] Displays as floating-point format with the specified
number of digits. If you don't supply a number of
digits, as many as necessary are used.
m Displays a memory-referencing expression as hex
bytes.
md Displays a memory-referencing expression as decimal
bytes.
p Displays a raw pointer value, showing segment as a
register name if applicable. Also shows the object
pointed to. This is the default if no format control is
specified.
s Displays an array or a pointer to an array of characters
as a quoted character string.
xorh Displays an integer as a hexadecimal number.
10
Object-oriented debugging
To meet the needs of the object-oriented programming revolution,
TOW supports C++. Besides extensions that let you trace into
member functions and examine objects in the Evaluate/Modify
dialog box and the Watches window, TOW comes equipped with
a special set of windows and local menus specifically designed for
object types and classes.
The Class List pane Press Alt-F10 to display the local menu for the pane. You can use
local menu the control-key shortcuts if you've enabled hot keys with
TDWINST. This local menu contains two items: Inspect and Tree.
Inspect
Tree Inspect
Displays a class Inspector window for the highlighted type.
The Hierarchy
Tree pane The top right pane displays the hierarchy tree for al! dasses used
by the current module. Base class and derived class relationships
are indicated by lines, with derived classes to the right of and
below their base classes.
To locate a single class in a complex hierarchy tree, go back to the
left pane and use the incremental search feature; then choose the
Tree command from the local menu to move back into the
hierarchy tree. The matched class appears under the highlight bar.
When you press Enter, a class Inspector window appears for the
highlighted class.
The Hierarchy Tree The Hierarchy Tree pane local menu (press Alt-F10 in the pane) has
pane local menu(s) only one item for C programs or for C ++ programs without
multiple inheritance: Inspect. When you choose it, a Inspector
Inspect window appears for the highlighted class. However, a faster and
easier method is simply to press Enter when you want to inspect
the highlighted class.
Inspect If you have loaded a C++ program that uses classes with multiple
Parents Yes inheritance, the Hierarchy Tree pane local menu contains a
second command, Parents. Use this command to toggle between
showing and not showing the base classes of a class with multiple
inheritance in the Parent Tree pane. The default for Parents is Yes.
The Parent Tree pane The Parent Tree pane, if it exists, has a local menu of its own with
local menu a single command, Inspect. It works just the same as the Inspect
command in the Hierarchy Tree pane local menu: It opens an
J Inspect Inspector window for the highlighted class.
The window is divided horizontally into two panes, with the top
pane listing the data members of the class and their types, and the
bottom pane listing the member function names and the function
return types. Use Tab to move between the two panes of the class
Inspector window.
If the highlighted data member is a pointer to a class, pressing
Enter opens another class Inspector window for the highlighted
class. (This action is identical to choosing Inspect in the local
menu for this pane.) In this way, complex nested structures of
classes can be inspected quickly with a minimum of keystrokes.
For brevity's sake, member function parameters are not shown in
the class Inspector window. To examine parameters, highlight the
member function and press Enter. A member function Inspector
window appears that displays the code address for the object's
implementation of the selected member function and the names
and types of all its arguments.
The ciass
Inspector window Pressing Alt-F10brings up the local menu for either pane. If
local menus control-key shortcuts are enabled (through TDWINST), you can
get to a local menu item by pressing Ctr/ and the first letter of the
item.
Inspect
Hierarchy
Show inherited Yes
The Data Member (top) The Data Member pane local menu contains these items:
pane
Inspect
If the highlighted field is a a pointer to a class, a class Inspector
window is opened for the highlighted field.
Hierarchy
Opens a Hierarchy window for the class being inspected. The
Hierarchy window is described on page 149.
Show Inherited
Yes is the default value of this toggle. When Show Inherited is set
to Yes, TOW shows all data members, whether they are defined
within the class of the inspected object or inherited from a base
class.
When the toggle is set to No, TOW displays only those data
members defined within the class being inspected.
Inspect
A member function Inspector window is opened for the
highlighted item. If you press Ctr/-/ when the cursor is positioned
over the address shown in the member function Inspector win-
dow, the Module window is brought to the foreground with the
cursor at the code that implements what is being inspected.
Hierarchy
Opens a Hierarchy window for the class being inspected. The
Hierarchy window is described on page 149.
Show Inherited
Yes is the default value of this toggle. When it is set to Yes, all
member functions are shown, whether they are defined within the
class being inspected or inherited from a base class. When it is set
to No, only those member functions are displayed that are defined
within the class being inspected.
The object
Inspector window Each of the top two panes of the object Inspector window has its
local menus own local menu, displayed by pressing Alt-F10in that pane. Use
the control-key shortcuts to get to individual menu items if you've
enabled hot keys with TDWINST.
Range ...
Change ..• Similar to structure Inspector windows, the bottom pane serves
Methods Yes only to display the class of the highlighted data member and
Show inherited Yes
doesn't have a local menu.
Inspect
Descend The local menu commands for the top pane, which summarizes
New expression .•.
Type cast the data members for the selected item, are described here.
Hierarchy
Range This command displays the range of array items. If the inspected
item is not an array or a pointer, the item cannot be accessed.
Change By choosing this command, you can load a new value into the
highlighted data member.
Methods This command is a Yes/No toggle, with Yes as the default condi-
tion. When it's set to Yes, member functions are summarized in
the middle pane. When it's set to No, the middle pane doesn't
appear. This toggle is remembered by the next Inspector window
to be opened.
Descend The highlighted item takes the place of the item in the current
Inspector window. No new Inspector window is opened.
However, you can't return to the previously inspected data
member, as you could if you had used the Inspect option.
¢ Use Descend to inspect a complex data structure when you don't
want to open a separate Inspector window for each item.
New Expression This command prompts you for a new data item or expression to
inspect. The new item replaces the current one in the window; it
doesn't open another window.
Type Cast Lets you specify a different data type for the item being inspected.
This command is useful if the Inspector window contains a
symbol for which there is no type information, as well as for
explicitly setting the type for pointers.
Hierarchy When you choose this command, a Hierarchy window opens. For
a full description of this window, see page 149.
ll
Windows features
The features that support debugging of Windows programs are
•A view window, the Windows Messages window, which shows
messages passed to windows in your program
•Three types of data you can display in the Log window:
• The data segments in your program's local heap
• The data segments in the global heap
• A complete list of modules making up your program,
including any dynamic link libraries (DLLs)
Logging window
messages To track messages being passed to your program's windows,
choose the View IWindows Messages command to open the
Windows Messages window. This window shows you the
messages that Windows is passing to one or more windows in
your program.
The Windows Messages window is composed of three panes, the
Window Selection pane (top left), the Message Class pane (top
right), and the Messages pane (bottom). The messages show up in
the Messages pane.
The appearance of this window and the way you add application
windows to it differ depending on whether you're working with
an ObjectWindows application or a standard Windows
application.
Selecting a window for If you're debugging a standard Windows application and you
a standard Windows select View IWindows Messages, you see the following window:
application
Figure 11.l
The Windows Messages
window for a standard
Windows application
Add •••
Before you can log messages, you must first indicate which
Remove window you're logging messages for. You do this in the top left
Delete all
pane, the Window Selection pane. This pane's local menu
(activated by pressing Alt-F1(J) lets you add a window selection,
delete a window selection, or delete all window selections.
Adding the first window proc You can enter either the name of the object that processes
to this box also sets the
message class to "Log all
messages for the window (select the Window Proc button) or a
messages." handle value (select the Handle button). Enter as many routine
names or handle values as necessary to track messages for your
windows.
It's easier to indicate the window by the name of the routine that
processes its messages (for example, WndProc) because you can
enter a routine name any time after loading your program.
If you prefer to use a handle variable name, you must first step
through the program past the line where the handle variable is
assigned a handle. (Use the Fl or FB key to single-step through the
program.) If you try to enter the variable name before stepping
past its assignment statement, TOW will not let you.
Selecting a window for If you're debugging an ObjectWindows application and you select
an ObjectWindows View I Windows Messages, by default you see the standard
application Windows Messages dialog box in Figure 11.1. This dialog box
works the same for ObjectWindows programs as for standard
Windows programs, except that you can't use a Windows proce-
dure name. Instead, you must use the handle to the window
object for the window whose messages you want to log or break
on.
I Add •••
Remove
Before you can log messages, you must first indicate which
window. dialog box, or dialog control you're logging messages
I Delete all for. You do this in the top left pane, the Window Selection pane.
This pane's local menu (activated by pressing Alt-F10) lets you add
a window object, delete a window object, or delete all window
objects.
Adding the first object to this You can enter either the name of the object that processes
pane also sets the message
class to "Log all messages.·
messages for the window, dialog box, or control (select the
Window Object button) or a handle value (select the LJ:andle
button). Enter as many object names or handle values as
necessary to track messages for your windows.
Deleting a window Deleting a window selection from the Window Selection pane
selection works the same for both types of applications. To delete, move the
cursor to the item, then either bring up the local menu and choose
Remove or press the Delete, Ctrl-Y, or Ctrl-R key.
To delete all selections, choose Delete All from the local menu.
Specifying a message The top right pane is the Message Class pane. Its local menu,
class and action identical to that of the Window Selection pane, allows you to add
a message class, remove a message class, or delete all classes you
Add ••• have added.
Remove
Delete all You must specify a window procedure or handle in the Window
Selection pane before you can add a message class in this pane.
If you don't indicate a specific message or class of messages to
watch, TOW watches all messages sent to the window procedure
or handle.
The Set Message Filter dialog box prompts you both for a message
class to track and an action to be performed when a message in
that class is received.
TOW by default logs all messages starting with WM_. Because so
many messages come in, you'll probably want to narrow the focus
by selecting one of the classes in the Message Class list. You can
add only one class at a time, so if you need to track messages from
multiple classes, you have to use the Add option for each class
you want to set.
The following table describes the message classes:
Table 11.1
Windows message classes Message class Description
~~~~~~~~~~~~~~~~~~~~~~~~~~-
Viewing messages Window messages show up in the lower pane of the Windows
Messages window. This pane can hold up to 200 messages.
Send to log window No
Erase log If you want to save the messages to a file, you have to open a log
file for the Log window (use View I Log File, then choose Open
Log File from the local menu). Then switch back to the Messages
pane and change the Send To Log Window entry on the local
menu to Yes.
If you want to clear the pane of all messages, choose Erase Log
from the local menu. Any messages written to the Log window
will not be affected by this command.
If you select the Global Heap option, you can choose to display
the list from top to bottom, from bottom to top, or from a location
indicated by a starting handle.
A starting handle is the name of a global memory handle set in
your application by a call to a Windows memory allocation
routine like GlobalAlloc. Picking a starting handle causes TDW to
display the object at that handle as well as the next four objects
that follow it in the heap.
Listing the contents of The global heap is the global memory area Windows makes
the global heap available to all applications. If you allocate resources like icons,
bit maps, dialog boxes, and fonts, or if you allocate memory using
the GlobalAlloc function, your application is using the global heap.
To see a list of the data objects in the global heap, select the Global
Heap radio button in the Windows Information dialog box, then
choose OK. The data objects will be listed in the Log window.
¢ Because this list is likely to exceed the number of lines the Log
window can write (the default is 50 lines), you should either write
the contents to a log file (use the Log window local menu) or
increase the number of lines the Log window can use (use
TDWINST). The maximum number of lines you can set is 200.
Field Description
OECS Either a handle to the memory object, expressed
053E as a 4-digit hex value, or the word FREE,
indicating a free memory block.
(053D) A memory selector pointing to an entry in the
global descriptor table. The selector isn't displayed
if it's the same value as the memory handle.
00000040b A hexadecimal number representing the length of
000020COb the segment in bytes.
PDB The allocator of the segment, usually an
GDI application or library module. A PDB is a process
descriptor block, also known as a program
segment prefix (PSP).
(OFlD) A handle indicating the owner of a PDB.
DATA The type of memory object. The types are
DATA Data segment of an application or DLL
CODE Code segment of an application or DLL
PRIV Either a system object or global data for
an application or DLL
MOVEABLE A memory allocation attribute. An object can be
FIXED, MOVEABLE, or MOVEABLE
DISCARDABLE.
LOCKED=OOOOl For a moveable or moveable-discardable object,
the number of locks on the object that have been
set using either the GlobalLock or LockData function.
PGLOCKED=OOOl For 386 Enhanced mode, the number of page locks
on the object that have been set using the
GlobalPageLock function. With a page lock set on a
memory object, Windows can't swap to disk any of
the object's 4-kilobyte pages.
Obtaining a list of To see a list of the task and DLL modules that have been loaded
modules by Windows, select the Module List radio button in the Windows
Information dialog box, then choose OK. The modules will be
listed in the Log window.
The list can easily exceed the default length of the log window.
See the caution in the global heap section (page 166) about using a
log file or increasing the number of lines that can be written in the
Log window.
Debugging
dynamic link A DLL is a library of routines and resources that is linked to your
libraries (DLLs) Windows application at runtime instead of at compile time. This
runtime linking allows multiple applications to share a single
copy of routines, data, or device drivers, thus saving on memory
use. When an application that uses a DLL starts up, if the DLL is
not already loaded into memory, Windows loads it in so the
application can access the DLL's entry points.
TDW can load a DLL that When you load an application into TDW that has DLLs linked
doesn't have a symbol table,
into it, TDW determines which of these DLLs, if any, have symbol
but only into a CPU window.
tables (were compiled with the debugging option turned on) and
tracks these DLLs for you. If, during execution of your appli-
cation, TDW encounters a call to an entry point for one of these
DLLs, TDW loads the symbol table and source for that DLL and
positions the module line marker at the beginning of the DLL
routine called by your application. The DLL is then available in
the Module window just as your application source code was.
When the DLL routine exits, if possible, TDW reloads your
application's source code and positions the line marker on the
next statement after the call to the DLL entry point.
If you are tracing through the program using Fl or FB, it might not
be possible for TDW to return you to the calling routine in your
program because the DLL might return through a Windows
function call. In this case, your program just runs as though you
had pressed F9. This behavior is common in DLL startup code. To
Using the Load This dialog box enables you to do two things:
Modules or DLLs dialog
•Change to another source module of your application
box
•Perform operations on DLLs and .EXE files (such as loading in a
symbol file and source file)
Adding a DLL to the Before you can set debug options, debug OLL startup code, or
DLLs & Programs list prevent TOW from loading a OLL's symbol table and source, the
OLL must first be in the OLLs & Programs list. A OLL accessed by
your application might not be in this list because, just after your
application loads, TOW only knows about OLLs that are linked
into the startup code of your application. Your application can
also start a OLL explicitly by using the Windows Loadlibrary
function; TOW won't know about it until your application calls
Load library.
Setting debug options If you want to set breakpoints or watches or some other debug
in a DLL option for a OLL, bring up the Load Modules or OLLs dialog box
(press F3 or choose View I Modules), highlight the OLL on the
OLLs & Programs list, then choose Symbol Load to bring up the
OLL in a Module window. Once you're in the Module window,
you can perform your operations on the OLL.
Controlling TDW's By default, TOW loads in the symbol table and source of every
loading of DLL symbol OLLthat your application accesses, but only if the OLL has a
tables TOW-compatible symbol table. A OLL has a symbol table
compatible with TOW if it was compiled with debugging infor-
mation turned on and the compiler was a Borland language
compiler.
Because it takes time to load in a OLL's symbol table and then
load in the original application's symbol table once the OLL
routine has finished, you might want to disable TOW's default
operation for OLLs you don't want to debug. To prevent TOW
from loading a OLL's symbol table, bring up the Load Modules or
OLLs dialog box (press F3 or choose View I Modules), find the OLL
on the OLLs & Programs list, highlight it, and then push the Load
Symbols No button.
Debugging DLL startup By default, TOW does not debug OLL startup code and only loads
code a OLL's symbol table when your application makes a call to a OLL
entry point. TOW then brings up the Module or CPU window
with the current line marker at the beginning of the OLL routine
called by the application.
TOW debugs OLL startup code if you tell it to. You can use TOW
to debug either of two types of OLL startup code:
What kind of startup code •The initialization code immediately following LibMain (the
are you debugging? default)
Is your application already If you try to load your application and then set startup
loaded?
debugging, TDW might not behave as you expect, since some or
all of the DLLs might already have been loaded. Therefore, you
should set startup debugging either
•By setting the DLLs before you load your application
• By loading your application, indicating the DLLs for startup
debugging, and then restarting your application (Ctrl-F2 or Run I
Program Reset)
Doing startup code With all these preliminaries in mind, use the following steps to
debugging
specify startup debugging for one or more DLLs and to debug
those DLLs' startup code:
Be sure to run to the end of a DLL's startup code before reloading the
current application or loading a new one. If you don't, the partially
executed DLL startup code might cause Windows to hang, forcing
you to reboot.
Converting
memory handles Windows uses memory handles instead of addresses for memory
to addresses objects because it performs its own memory management and can
change the physical location in memory of an object. If you need
the actual address referred to by a memory handle, you can use
the TDW built-in typecast symbols lh2fp (for a local handle) and
gh2fp (for a global handle) to dereference the handle.
You use these typecasting symbols in TDW just as you use the
regular C++ typecasting symbols for pointers. For example, you
could cast the local memory handle hLocalMemory using two
methods:
•You could use the Data I Inspect window to evaluate the
expression (lh2fp) hLocalMemory.
•You could use the Type Cast command in the Inspector local
window and enter lh2fp as the type.
In either case, the expression evaluates to the first character of the
memory block pointed to by hLocalMemory.
12
Assembler-level debugging
For more information on This chapter is for programmers who need to take a lower-level
assembler-level debugging,
look at their code. It gives a brief introduction to the CPU window
see the file DOC\
ASMDEBUG. TOW in the and the six panes of that window. You can also get online Help
language compiler directory information about any pane of this window and its local menu by
on your hard disk. positioning the cursor in the pane and pressing F1.
I
in a number of formats, and change them
Figure 12.l F[•]=REMOTE CPU 8038 3=[t] [~]=
WINMAIN: int PASCAL Wi nMai n (HANDLE hlnstance,& ax FF15 c=O
The CPU window cs: 0158•55 push bp • bx 08DE z=l
cs:0159 88EC mov bp,sp ex 0015 s=O
cs:0158 83EC06 sub sp,0006 dx 08DE o=O
cs:015E 56 push si si OSCO p=l
cs:015F 57 push di di 08DE a=O
#TDDEM0#44: InitWinCrt(); bp 1E2A i=l
cs:0160 E88IlF call InitWinCrt sp lElE d=O
#TDDEM0#45: nlines = O; - ds 1285
cs:0163 33F6 xor si ,si ,. es 1285
;;05 oat~ Loa~ed 111!~ ~ms 11eM3rife,
1 up ~~ ~m
1280 Invalid ip 0158
ds:OOOO 00 00 00 00 00 00 50 lE P&
ds:0008 00 00 C2 OA 2C lE 2C lE :rl, .. ,..
ds:OOlO 00 00 08 00 00 00 95 12 C-- Ot SS: 1E20 0001
ds:0018 B6 12 00 00 80 00 01 00 11t o SS: 1ElE•OOA2 I
Open a CPU window by choosing View I CPU from the menu bar.
Depending on what you're viewing in the current window, the
new CPU window comes up positioned at the appropriate code,
data, or stack location, thus providing a convenient method for
taking a low-level look at the code, data, or stack location your
cursor is currently on.
The disassembler
The Code pane automatically disassembles and displays your
program instructions. If an address corresponds to either a global
symbol, static symbol, or a line number, the line before the dis-
assembled instruction displays the symbol if the Mixed display
mode is set to Yes. Also, if there is a line of source code that corre-
sponds to the symbol address, it is displayed after the symbol.
Global symbols appear simply as the symbol name. Static symbols
appear as the module name, followed by a cross hatch(#),
followed by the static symbol name. Line numbers appear as the
module name, followed by a cross hatch(#), followed by the
decimal line number.
When an immediate operand is displayed, you can infer its size
from the number of digits: A byte immediate has 2 digits, and a
word immediate has 4 digits.
You can use the local menu of the Register pane to increment or
decrement a register by l, to set the register to 0, to change the
register, or to toggle between displaying the register as 16-bit or
32-bit values (requires an 80386 processor or greater).
The local menu of the Flags pane allow you to toggle the flag
between 0 and 1.
The Selector
pane local menu At the Selector pane, press Alt-F10to pop up the local menu or, if
control-key shortcuts are enabled, use the Ctr/ key with the
highlighted letter of the desired command to access the
command.
You can use the local menu of the Selector pane to go to a new
selector (the Selector command) or see the contents of the selector
currently highlighted in the Selector pane (the Examine
command). The contents display in either the Code pane or the
Data pane, depending on their nature.
Selector
Examine •••
Selector Prompts you to type a selector to display in the pane. You can use
full expression syntax to enter the selector. If you enter a numeric
value, TDW assumes it is decimal unless you use the syntax of the
current language to indicate that the value is hexadecimal.
For example, if the current language were C, you could type the
hexadecimal selector value 7F as Ox7F. For Pascal, you'd type it as
$7F. You could also type the decimal value 127 in order to go to
selector 7F.
Another method of entering the selector value is to display the
CPU window and check the segment register values. If a register
holds the selector you're interested in, you can enter the name of
the register preceded by an underscore (_). For example, you
could type the data segment register as _DS.
You can perform the same functions from the local menu of the
Registers window as you can from the local menus of the
Registers pane and the Flags pane.
13
Command reference
Now that you've read about all the commands, here's a quick
summary. This chapter lists and describes
•all the single-keystroke commands available on the function
and other keys
• all the menu bar commands and the commands for the local
menu of each window type
•keystrokes used in the two types of panes (those in which you
enter text and those from which you select an item)
• keystrokes for moving and resizing windows
Hot keys
A hot key is a key that performs its action no matter where you
are in the Turbo Debugger environment. The following table lists
all the hot keys:
The =(System)
menu Repaint Desktop Redisplays entire screen
Restore Standard Restores standard window layout
About Displays information about Turbo
Debugger
The Breakpoints
menu Toggle Toggles breakpoint at cursor
At Sets breakpoint at specified address
Changed Memory Global Sets global breakpoint on memory
area
Expression True Global Sets global breakpoint on
expression
Hardware Breakpoint Sets a hardware breakpoint
Delete All Removes all breakpoints
The Options
menu Language Sets expression language
Macros
Create Defines a keystroke macro
Stop Recording Ends the recording session
The Window
menu Zoom Zooms window to full screen size
and back
Next Activates successive windows open
onscreen
Next Pane Goes to the next pane in a window
Size/Move Moves window or changes its size
lconize /Restore Reduces window to a small symbol
or restores it
Close Closes window
Undo Close Reopens the last window closed
Dump Pane to Log Writes current pane to Log window
User Screen Displays your program output
Numbered window list A numbered list of up to 9 open
windows to activate
Window Pick Displays a menu of open menus if
more than 9 are open onscreen
Breakpoints
window The Breakpoints window has two panes: the List pane on the left
and the Detail pane on the right. Only the List pane has a local
menu.
Code pane
Goto Displays code at new address
Origin Displays code at CS:IP
Follow Displays code at JMP or CALL target
Caller Displays code at calling procedure
Previous Displays code at last address
Search Searches for instruction or bytes
Selector pane
Selector Lets you enter a new selector to go to
Examine Displays contents of memory area
referenced by selector in code pane or
data pane, depending on type of contents
Data pane
Goto Displays data at new address
Search Searches for string or data bytes
Next Searches again for next occurrence
Change Changes data bytes at cursor address
Follow
Near Code Sets Code pane to the near address under
the cursor
Far Code Sets Code pane to the far address under
the cursor
Offset to Data Sets Data pane to the near address under
the cursor
Segment:Offset Sets Data pane to the far address under
to Data the cursor
Base Segment:O Sets Data pane to start of segment that
to Data contains the address under the cursor
Previous Displays data at last address
Display As
Byte Displays hex bytes
Word Displays hex words
Long Displays hex 32-bit long words
Comp Displays 8-byte Pascal comp integers
Float Displays short (4-byte) floating-point
numbers (float)
Flags pane
Toggle Sets or clears highlighted flag
Pressing Enter or Spacebaris a shortcut for the Toggle local menu
command in this pane.
Register pane
Increment Adds one to highlighted register
Decrement Subtracts one from highlighted register
Zero Clears highlighted register
Change Sets highlighted register to new value
Registers 32-bit Toggles 32-bit register display: No/Yes
Typing any character is a shortcut for the Change local menu
command in this pane.
Stack pane
Goto Displays stack at new address
Origin Displays data at SS:SP
Follow Displays code pointed to by current item
Previous Restores display to last address
Change Lets you edit information
Typing any character is a shortcut for the Change local menu
command in this pane.
The Execution
History window The Execution History window has two panes, each with a local
menus menu: the Instructions pane and the Keystroke Reording pane.
Instructions pane The Instructions pane shows instructions already executed that
you can examine or undo.
File window
The File window shows the contents of the disk file as hex bytes
or as an ASCII file.
Log window
menu The Log window shows messages sent to the log and allows you
to list Windows memory and module information.
Module window
The Module window shows the source file for the program
module.
Windows
Messages The Windows Messages window has three panes: the Window
window Selection pane, the Message Class pane, and the Messages pane.
Window Selection These are the local menu commands in this pane:
pane
Add Adds a window name or handle value
Remove Removes the selected window
Delete all Deletes all window selections
Typing any character is a shortcut for the Add local menu
command in this pane.
Message Class pane These are the local menu commands in this pane:
Messages pane These are the local menu commands in this pane:
Clipboard
window The Clipboard window shows you all the items you've copied
into the Clipboard. It has a single pane with the following local
menu commands:
Register pane These are the local menu commands in this pane:
Hierarchy window
The Hierarchy window has two panes, the Class pane and the
Hierarchy Tree pane.
Class pane
Inspect Shows contents of highlighted class
Tree Moves to the Hierarchy Tree pane
Registers window
menu The Registers window is identical to the Register and Flags panes
of the CPU window. Its local menus are identical to the Register
pane local menu and the Flags pane local menu.
Stack window
The Stack window shows the currently active procedures.
Variables window
The Variables window has two panes, each with a local menu:
The Global Symbol pane and the Local Symbol pane.
Watches window
The Watches window has a single pane that shows the names and
values of the variables you're watching.
Class Inspector
window Class Inspector windows have two panes that show the contents
(data members and member functions) of a class. Their local
menus, the same for both panes, are quite different from the local
menu of regular Inspector windows.
Object Inspector
window
Object Inspector windows contain three panes, of which only the
first two have local menus. (The third displays only the class to
which the object belongs). Both local menus are the same, and
contain the following commands:
Text panes
Text pane is the generic name for a pane that displays the contents
of a text file. The blinking cursor shows your current position in
the file. The following table lists all the commands:
Table 13.2
Text pane key commands Key Function
~~~~~~~~~~~~~~~~~~~~~~~~~~-
If you're not using the control-key shortcuts, you can also use the
WordStar-style control keys for moving around a text pane.
Table 13.3
List pane key commands Key Function
~~~~~~~~~~~~~~~~~~~~~~~~~-
If you're not using the control-key shortcuts, you can also use the
WordStar-style control keys for moving around a list pane.
=
•l
(System)
lmll
L_____,
... .. 111111
,--J
l
Run
1:mma•l•llilB m111 Blll·H~..
Options
I
ll!llil!D IDlil JI
·~
Trace into F7 Display options •••
About. .. Step over F8 Path for source •••
L .. _. --~- ~--------- ----- Exe:::..:te t::: •.• A1t.of9 Save opt~ o:-:s . ..
Until return
Animate ••.
Alt-F8
I Restore options •••
l Back trace Alt-F4
File Instruction trace Alt-F7 l
Create .•. Alt =
Open •.. Arguments ..• Stop recording Alt -
Change dir ... Program reset Ctrl-F2 Remove ...
Get info •.. Delete all
Symbol load ...
Quit Alt-X
l
Breakpoints Window
l
Toggle F2 Zoom F5
At .•. Alt-F2 Next F6
Changed memory global ... Next pane Tab
_[_ Expression true global ... Size/move Ctrl-F5
Edit Hardware breakpoint ... Iconi ze/restore
Delete all Close Al t-F3
Copy Shft-F3 Undo close Alt-F6
Paste Shft-F4
Copy to log User screen Al t-F5
Dump pane to 1og 1 (First open window)
(2-9 open windows)
Window pi ck •..
l
View
l
Data Help
l
Breakpoints Inspect. .. Index Sh ft-Fl
Stack Evaluate/modify ..• Ctrl-F4 Previous topic Alt-Fl
Log Add watch ..• Ctrl-F7 Help on help
Watches Function return
Variables
Module •.• F3
File .•.
CPU
Dump
Registers
Numeric processor
Execution hi story
Hierarchy
Windows messages
Clipboard
Another ..
Wi Module ...
Dump
File •.•
14
Debugging style
Everyone has their own style of writing a program, and everyone
develops their own style of debugging. The debugging sugges-
tions we give here are just starting points that you can build on to
mold your own personal approach. ·
Many times, the intended use of a program influences the
approach you take to debug it. If a program is for your own use or
will only be used once or twice to perform a specific task, a full-
scale testing of all its components is probably a waste of time,
particularly if you can determine that it is working correctly by
inspecting its output. If a program is to be distributed to other
people or performs a task of which the accuracy is hard to
determine by inspection, your testing must be far more rigorous.
Incremental
testing When you want to be very sure that a program is healthy, you
must test the individual routines, as well as checking that the
program works as expected for some test input data. You can do
this in a couple of ways: You can test each routine as you write it
by making it part of a test program that calls it with test data. Or
you can use TOW to step through the execution of each routine
when the whole program is finished.
Types of bugs
Bugs fall into two broad categories: those peculiar to the language
you're working in and those that are common to any program-
ming language or environment.
By making mental notes as you debug your programs, you learn
both the language-specific constructs you have trouble with, and
also the more general programming errors you make. You can
then use this knowledge to avoid making the same mistakes in
the future, and to give you a good starting point for debugging
future programs.
Understanding that each bug is an instance of a general family of
bugs or misunderstandings will improve your ability to write
errorless code. After all, it's better to write bug-free code than to
be really good at finding bugs.
Hidden effects If you are careless about using global variables in functions, a call
to a function can leave unexpected contents in a variable or data
structure:
char workbuf[20];
strcpy(workbuf,"all done\n");
convert("xyz");
printf (workbuf);
convert(char *p)
{
strcpy(workbuf, p);
while (*p)
Here, the correct thing to do would be to have the function use its
own private work buffer.
Assuming initialized Don't assume that another routine has already set a variable for
data you:
char *workbuf;
addworkstring(char *s)
{
strcpy{workbuf, s); I* oops */
Not cleaning up This sort of bug can crash your program by exhausting heap
space:
Fencepost errors Thest> bugs are named after the old brain teaser that goes "If I
want to put up a 100-foot fence with posts every 10 feet, how
many fenceposts do I need?" A quick but wrong answer is ten
(what about the final post at the far end?). Here's a simple
example:
for (n = 1; n < 10; n++)
{
/* oops--only 9 times */
Here you can easily see the numbers 1 and 10, and you think that
your loop goes from one to ten. (Better make that < into a <=.)
C-specific bugs
Turbo C++ for Windows is very good at finding C-specific bugs
that other compilers don't warn you about. You can save yourself
some debugging time by turning on all the warnings that the
compiler is capable of generating. (See the Turbo C++ for
Windows manuals for information on setting these warnings.)
What follows is by no means an exhaustive list of ways you can
get in trouble with C. For some of these errors, Turbo C++ for
Windows issues a warning message. Remember to examine the
cause of any warning messages; they may be telling you about a
bug in the making.
n++;
Confusing = and == C lets you both assign a value (=) and test for equality <==) within
an expression; for example,
if (x = y)
Confusing operator C has so many operators that it is hard to remember which ones
precedence are applied first when an expression is evaluated. One combi-
nation that often causes grief is the mixture of shift operators with
addition or subtraction. For example,
x=3«1+1
evaluates to 12, not 7, as you might expect if you thought << took
effect before the +.
Bad pointer arithmetic When you use a pointer to step through an array, be careful how
you increment and decrement it. For example,
int *intp;
intp += sizeof(int);
does not increment intp to point to the next element of an integer
array. Instead, intp is advanced by two array elements because in
adding to or subtracting from a pointer, C takes into account the
size of the item the pointer is pointing to. All you have to do to
move the pointer to the next element is
intp++
One of C's strong ooints can cause vou trouble if vou are not
........ .... J ,J
Misplaced semicolons The following code fragment may appear to be fine at first glance:
for (x = O; x < 10; x++);
{
/* only executed once */
Why does the code between the braces execute only once? Closer
inspection reveals a semicolon (;) at the end of the for expression.
This hard-to-find bug causes the loop to execute ten times, but
does nothing. The subsequent block is then executed once. This is
a nasty problem because you can't find it with the usual technique
of examining the formatting and indenting of code blocks in your
program.
if (n == 0)
The trouble is that by the time the function returns, the automatic
variable is no longer valid and is likely to have been overwritten
by other stack data.
Misuse of break The break keyword exits from only a single level of do, for,
keyword switch, or while loops:
for ( ... )
{
while ( ... )
if ( ... )
break; /* we want to exit for loop */
Here, the break exits only from the while loop. This is one of the
few cases where it is excusable to use the goto statement.
Code has no effect Sometimes a typo results in source code that compiles, but doesn't
do what you want it to. It may not do anything at all.
a + b;
Accuracy testing
Making a program work with valid input is only part of the job of
testing. The following sections discuss some important test cases
Testing boundary
conditions Once you think a routine works with a range of data values, you
should subject it to data at the limits of the range of valid input.
For example, if you have a routine to display a list from 1 to 20
items long, you should make sure it behaves correctly both when
there is exactly 1 item and exactly 20 items in the list. This can
flush out the one-too-few and one-too-many "fencepost" errors
(described on page 211).
Deciding your
plan of attack Your first task is to decide which problem to attack first. A good
rule of thumb is to start with the problem that appears to be
happening first. In this program, each input line is broken down
into words, then analyzed, and finally, after all the lines have been
entered, the tables are displayed. Since the word and letter counts
are off as well as the tables, it's a good bet that something is
wrong during the initial breaking down and counting phase.
Now is the time to start debugging, after you've thought about the
problem for a moment and decided on a rough plan of attack.
Here, the strategy is to examine the routine makeintowords, to see if
it is correctly chopping the line into null-terminated words, and
then see if analyzewords is correctly counting the analyzed line.
Starting Turbo
Debugger To start the sample debugging session, make sure the Turbo C++
edit window with TDDEMOB is current, then use the Run I
Debugger command.
TOW loads the buggy demo program and displays the startup
screen. If you want to exit from the tutorial session and return to
Turbo C++, press Alt-X at any time. If you get hopelessly lost, you
can always reload the demonstration program and start from the
Inspecting
You are now stopped at the source line after the call to
makeintowords. Look at the contents of buffer to see if the right
thing happened. Move the cursor up a line, place it under the
word buffer, and press Alt-F10 I (for Inspector) to open an Inspector
window to show the contents of buffer. Use the arrow keys to
scroll through the elements in the array. Notice that makeintowords
has indeed put a single null character (0) at the end of each word
as it is meant to. This means that you should execute more of the
program and see if analyzewords is doing the right thing. First,
remove the Inspector window by pressing Esc. Then, press F7
twice to execute to the start of analyzewords.
Breakpoints
Check that analyzewords has been called with the correct pointer to
the buffer by moving the cursor under bufp and pressing Alt-F10 I.
You can see that bufp indeed points to the null-terminated string
'one'. Press Escto remove the Inspector window. Since there
seems to be a problem with counting characters and words, let's
put a breakpoint at the places where a character and a word are
counted:
The Watches
window Run the program by pressing F9. The program stops when it
reaches the breakpoint on line 93. Now you want to look at the
value of charcount. Since you'll want to check it each time you hit
a breakpoint, this is an ideal time to use the Watch command to
place it in the Watches window. Move the cursor under charcount
and press Alt-F10 W. The Watches window at the bottom of the
screen now displays the current value of 0. To make sure that the
character is being counted properly, execute a single line by pres-
sing F7. The Watches window now shows that charcount is 1.
The
Evaluate/Modify Run the program again by pressing F9. You are now back at line
dialog box 93 for another character. Press F9 again twice to read the last letter
on the word and the terminating null. charcount now correctly
shows 3, and the wordcounts array is about to be updated to count
a word. Everything is fine so far. Press F9 again to start processing
the next word in the buffer. AHA! Something is wrong.
You expected the program to stop again on line 93 as it processed
the next word, but it didn't. It went straight to the statement that
returns from the function. The only way to end up on line 99 is if
the while loop that started on line 83 no longer has a true test
value. This means that *bufp != 0 must evaluate to false (that is, 0).
To check this, move back to line 83 and mark the entire expression
*bufp != 0 by putting the cursor under the*, pressing Ins, and
moving the cursor to the final '0' before the ' ) '. Now evaluate
this expression by opening the Data I Evaluate Modify dialog box
and either pressing Enter or choosing the Eval button to accept the
marked expression. The value is indeed 0. Press Esc to return to
the Module window.
Now run the program. Enter the usual two input lines.
one two three
four five six
Press Enter at the third prompt, and when the program terminates,
look at your output on the User screen.
You'll notice that things have improved considerably. The total
number of words and lines seem to be wrong, but the tables are
correct. Close the application window to get back to the Module
window.
15
Debugging an ObjectWindows
application
The sample Windows programs in this chapter were written
using the ObjectWindows application framework that makes
Windows programming so much easier.
The programs are TDODEMO and TDODEMOB (the B stands for
buggy). TDODEMOB has several bugs in it that you'll discover by
working through this chapter.
If there are no .EXE files for Before continuing, it might be helpful if you start TDODEMO
TDODEMO and TDODEMOB, from Windows and play with it a bit to get an idea of how it
you'll have to open their
project files and compile works. You can either use the Program Manager File IRun
them with debug information command to start TDODEMO.EXE or add it to a program group
included. as an icon.
public:
HDC HandleDC; II Display context for drawing.
BOOL ButtonDown; II left-button-down flag
HPEN ThePen; II Pen that is used for drawing in color
ScribbleWindow(PTWindowsObject AParent, LPSTR ATitle);
~ScribbleWindow();
void GetWindowClass(WNDCLASS &AWndClass);
WMLButtonUp When the user finishes scribbling and releases the mouse button,
the window receives a WM_LBUTTONUP message, which in turn
causes ObjectWindows to call WMLButtonUp. The program marks
the ButtonDown variable FALSE and releases the device context
associated with the window.
WMRButtonDown When the user presses the right button to clear the screen,
ObjectWindows calls the function WMRButtonDown, which calls
the Windows function UpdateWindow. Calling this function is
supposed to clear the window.
WMMouseMove Once the user starts moving the mouse over the window, the
window begins receiving WM_MOUSEMOVE messages, which
cause ObjectWindows to call the function WMMouseMove. If the
user has pressed the left inouse button, the program draws a line
each time the mouse is moved. If the user hasn't pressed a mouse
button, nothing at all happens.
The pen-color routines There are four functions that set the pen color by deleting the
current pen and creating a new one of the correct color. These
functions differ only in the color each one sets.
Creating the
application To create an application that uses the Color Scribble window, it's
necessary to derive a class based on the ObjectWindows class
TApplication. The purposes of this class, CScribbleApplication, are
• to redeclare the lnitMainWindow function so the application can
create a main window with the properties of ScribbleWindow
Finding the function Since the program failed when you pressed the left mouse button,
that called Windows it's likely that the problem is in the WMLButtonDown function.
However, there's another technique you can use to see where your
program was, a stack trace.
To do a stack trace, display the Stack window (choose View I
Stack), then scroll down the list of hexadecimal instructions until
you come to a line indicating a routine in your program (you'll see
the name of the routine in ASCII characters). That line is the one
that called the Windows kernel.
As you can see in the Stack window, the routine you need to look
at is, indeed, WMLButtonDown. To go to this routine in the Module
Debugging MoveTo The parameters of MoveTo are the handle of the pen and the X and
Y coordinates of the current cursor location. The coordinates come
from the Msg parameter, which gets them from Windows. Unless
the program picks up the wrong part of this message (it doesn't),
these two parameters should be OK.
The culprit must be HandleDC, the pen's device context handle.
At this point, since you've had two UAEs, the safest course of
action is to exit TDW and close Windows before continuing.
Testing the fix Open Windows and Turbo C++ for Windows and reload the
TDODEMO project and source file. Add the context initialization
statement to ScribbleWindow::WMLButtonDown, then compile the
project with debug information included (choose Compile I Build
All).
Just in case there are more bugs, run the program program under
TOW again (choose Run I Debugger, then press F9 when the
Module window comes up).
Now if you draw with the pen, you see the drawing appear in the
default color, black. Try different colors by selecting pen colors
from the menu. Red, green, and blue all work fine; however, when
you try to change the pen color back to black, the pen won't change
color. It looks like you've found another bug.
The program will now return control to TOW whenever you make
a menu selection, because doing so generates a WM_COMMAND
message.
The program will now return control to TOW whenever you make
a menu selection, because doing so generates a WM_COMMAND
message.
Inspecting wParam You can now resume execution of the program by pressing F9.
Choose Pen I Black Pen from the menu. Once you have selected a
black pen, TOW stops execution and displays the CPU Window,
indicating that the program was executing Windows kernel code at
the time the break occurred. Close the CPU window by pressing
Alt-F3.
If necessary, bring up the Windows Messages window again.
Zoom the window to full size so you can see the entire message in
the lower pane. You can see that the window received a
WM_COMMAND message with 204 (OxCC) in the wParam
parameter. But the constant CM_BLACK is 104, not 204. The reason
the virtual function was not getting called was that the application
was looking for an identifier of CM_FIRST+204, but its value was
actually CM_FIRST+104.
The value 204 was specified in the menu definition in the
TDODEMO.RC file. This error could have been avoided by using
the same identifiers for the menu as are in the header file and
putting an #INCLUDE statement for that header file at the start of
the .RC file. Instead, integers were used in this menu definition,
which left the responsibility for cross-checking the values to the
programmer.
If you edit TDODEMOB.H and change CM_BLACK to 204,
selecting a black pen should work correctly. When you've made
this change, the constant declarations in TDODEMOB.H will be as
follows:
#define PenWidth
#define MenuID 100
#define IconID 100
#define CM RED 101
#define CM GREEN 102
#define CM BLUE 103
#define CM_BLACK 204
Logging the window Depending on whether or not you have ObjectWindows window
messages message support set, use one of the two methods described
starting on page 231 to initialize the window. Then indicate in the
Windows Messages window's top left pane (either by window
object or handle) which window to track messages for.
Next, move the cursor to the top right pane and add
WM_LBUTTONUP as a message breakpoint, to allow TOW to
regain control after you finish drawing.
You also want to look at all the messages that come back, but
setting WM_LBUTTONUP erased the Log All Messages setting. To
restore this setting, press Ctrl-A to display the Set Message Filter
dialog box, then select the Log All Messages class.
Discovering the bug Resume execution of TDODEMOB by pressing F9. Begin drawing,
then move the mouse off the client area, move it around a bit, and
then move it back on again at another place and release the left
mouse button so control returns to TOW.
Before looking at the Window Messages window, make sure to
zoom it to full size (press F5) so you can see more messages. When
Fixing the bug One possible solution would be to determine when the mouse is
off the client area, so the program can ignore the last mouse
position and begin drawing again when the mouse reenters the
client area. That would require some fancy logic to determine
when the mouse was leaving the client area of the window and
when it moves back over the client area. Fortunately, there is an
easier way.
The Windows function SetCapture does exactly what's needed.
This function tells Windows to send all mouse-related messages to
the specified window until the program calls ReleaseCapture, thus
causing the window to receive WM_MOUSEMOVE messages
when the mouse is off the client area instead of
WM_NCMOUSEMOVE messages.
If you put SetCapture in ScribbleWindow::WMLButtonDown and
ReleaseCapture in WMLButtonUp, WMMouseMove will actually
draw outside the window when the mouse is scribbling outside the
window. However, Windows will clip all the lines drawn outside
the client area, thus producing the desired effect.
void ScribbleWindow::WMLButtonUp(RTMessage)
{
if ( ButtonDown )
{
ReleaseCapture();
ReleaseDC(HWindow, HandleDC);
ButtonDown ; FALSE;
Testing the fix Exit Color Scribble, then exit TDW. When you're back in Turbo
C++ for Windows, enter the changes to the two routines, then
recompile the program and run it. Now when you draw on the
window, everything works fine, but when you try to erase the
screen by using the right-hand mouse button, nothing happens.
You've found another bug.
Finding the
erase-screen bug Since WMRButtonDown is the function that handles the right-hand
mouse button, the bug probably has something to do with that
routine. Either WMRButtonDown isn't getting called, or there's a
bug in it.
Analyzing the cause of This bug requires a little understanding of how Windows handles
the bug the UpdateWindow function. When a program calls this function,
Windows checks to see if any part of the window is invalid and
needs repainting. If so, Windows sends a WM_PAINT message to
the window. If not, there's no reason to waste system resources
with an unnecessary message, so Windows does nothing. But how
does Windows know that the window needs updating?
An application notifies Windows that at least part of the Window
is invalid by calling either lnvalidateRect or lnvalidateRgn. These
two functions put an update area in the window and notify
Fixing the bug Adding a call to lnvalldateRect in WMRButtonDown will fix the
problem. lnvalidateRect takes three parameters, a window handle
that identifies the window, a pointer to a rectangle that marks the
rectangle to be added to the update rectangle, and a Boolean
parameter that specifies if the rectangle should be erased. You can
pass in NULL for the pointer to the rectangle, telling Windows that
the entire window should be added to the update rectangle. The
following code listing shows how WMRButtonDown should look
with the new function call added:
void ScribbleWindow::WMRButtonDown(RTMessage)
{
InvalidateRect(HWindow, NULL, TRUE);
UpdateWindow(HWindow);
Testing the fix Run Color Scribble and exit it, then exit TOW. When you are back
in Turbo C++ for Windows, enter the changes to
WMRButtonDown, then recompile the program and run it. Now
when you draw on the window, then press the right-hand mouse
button to erase it, the window does get erased. You've found all the
bugs, and the program now works perfectly.
Error messages
TOW uses error messages to tell you about things you haven't
quite expected. Sometimes the command you have issued cannot
be processed. At other times the message warns that things didn't
go exactly as you wanted.
You can easily tell an error message from a prompt if you turn on
Error Message Beeps in TOINST.
Fatal errors
All fatal errors cause TOW to quit and return to Windows. Some
fatal errors are the result of trying to start TOW from the
command line. A few others occur if something fatal happens
while you are using the debugger. In either case, after having
solved the problem, your only remedy is to restart TOW.
Bad or missing configuration file
The configuration file is either corrupted or not a TOW
configuration file.
Invalid switch:
You supplied an invalid option switch on the command line.
Appendix A has an abbreviated list of all command-line
switches, and Chapter 4 discusses each one in detail.
Not enough memory
TOW ran out of working memory while loading.
Old configuration file
You have attempted to start TOW with a configuration file for
a previous version. You must create new configuration files for
this version of TOW.
Unsupported video adapter
TOW can't determine which display adapter you are using.
TOW supports EGA, VGA, Hercules, and Super-VGA.
':'expected
While evaluating a C expression, a question mark (?)
separating the first two expressions of the ternary?: operator
was encountered; however, no matching : (colon) to separate
the second and third expressions was found. For example,
x<0?46
should have been
x<0?4:6
']' expected
While evaluating an expression, a left bracket ([) starting an
array index expression was encountered without a matching
right bracket (]) to end the index expression. For example,
table[4
or
mov ax, [1]
mov es: [bx], ax
Index 263
assembler See also inline assembler bottom line See reference line
built-in 178, See also Code pane boundary errors 211
problems with 249 testing for 216
code29 Break option (breakpoints) 113
tracking 30 Breakpoint Detail pane 106
data, formatting 183 Breakpoint List pane 106
inline, keywords breakpoints 26, 103-113, See also Breakpoints
problems with 256 window
instructions See also instructions actions 104, 113
back tracing and unexpected side effects 83 setsof 115
breakpoints and 107 At command 105
executing single 78, 79 Boolean 112
execution history and 83 Changed Memory 117
multiple, treated as single 79 Changed Memory Global command 105
recording 83 condition sets 114
watching 28, See also CPU window conditional 118
memory dumps 183, 184 conditions for triggering 103, 112
mode, starting TDW in 62 adding actions 111
registers See CPU, registers customizing 111, 116
stack See Stack window defined 103
symbols 180 Delete All command 105
Assembler option (language convention) 132 disabling/ enabling 110
assembly code, debugging 10 Expression True Global command 105
assignment operators See also operators Get Info message about 76
language-specific 72, 94 global 110, 116
Turbo C++ for Windows 143 memory variables and 117
expressions with side effects and 90, 144 where occurred in program 77
At command (breakpoints) 105, 116 groups
Add command 108
B defined 107
delete 109
Back Trace command 80
disable 109, 113
backward trace 17, 83, See also Back Trace
enable 109, 113
command; reversing program execution
Group ID text box 110
assembler instructions 83
List dialog box 108
interrupts and 82
hardware 112, 118
binary operators See also operators
hardware-assisted
Turbo C++ for Windows 143
device drivers and 117, 251
bits 178
problems with 251, 257
blinking cursor 34
Hardware Breakpoint command 105
blocks
inspecting 107
memory See memory, blocks
local variables 118
moving246
location 103
reading from, problems with 252
logging values 119
writing to files, problems with 252
pass counts 104, 118, See also pass counts
books, reference 7
setting 115
Borland, contacting 5
reloading programs and 85
Both option (integer display) 66
Index 265
class member functions 74 raw 148
debugging, this parameter and 89 value of 95
multiple inheritance 151 check boxes 21, See also dialog boxes
stepping through 79 Breakpoint Disabled 110
tracing into 78 Save Configuration 67
-c option (load configuration file) 61 Class List pane 150
problems with 250 local menu 150
C programming language See Turbo C Class pane, local menu 197
calculator 91 classes, nested, scope of 137
calculator, using Watches window as 131 clearing a window, TDODEMO program 237
capturing WM_MOUSEMOVE messages 235 Clipboard 36
case sensitivity, overriding 62 local menu commands 39
casting See type conversion tips for using 40
central processing unit See CPU watching expressions 39
CGA See graphics adapters; video adapters Clipboard window
Change command local menu 196
Data Member pane local menu 155 clipping items from windows 36
Global pane local menu 72 close box 33
Inspector window local menu 101 Close command 31, 36, 101
Static pane local menu 72 Close Log File command 122
Watches window local menu 94 code See also specific language application
Change dialog box breakpoints and 107, 110, 118
global symbols and 72 checking onscreen 30
local symbols and 72 current segment See programs, current
Changed Memory Global command location
(breakpoints) 105 debugging See debugging
Changed Memory option (breakpoints) 112 disassembled, problems with 71
character constants 254 editing 123-124
character devices, problems with 242 exit, returned to Windows 77
character strings inspecting 82, See also Inspector windows
null-terminated 95, 99 splicing in (breakpoints) 113
quoted 129 stepping through 79, See also Step Over
arrays as 148 command
problems with 262 tracing into 78, See also Trace Into command
searching for execution history and 81
File window, in 129 viewing 178
Module window, in 126 execution history and 29
responding to prompt 246 in multiple files 126, 130
searching for next watching See also Watches window
File window, in 130 in slow motion 80
Module window, in 127 Code pane
Turbo C++ for Windows 142 current program location 180
characters disassembler and 180
display (ASCII vs. hex) 130 immediate operands and 180
escape (Turbo C++ for Windows) 142 instruction addresses 180
invalid 262 local menu 191
problems with scalar variables and 95 color graphics adapters See graphics adapters
Index 267
running programs to 78 Data pane
tutorial 48 local menu 192
cursor-movement keys See keys memory addresses in 183
customer assistance 5 Debug Information command 57
customizing TOW 63, 64 debugging 15-19, 177, See also programs,
debugging
D assembly code 10
.COM files 11
data 88-91, See also Data pane
continuous trace 80
accessing 132 control 69-86, 133
bashing, global breakpoints and 116
memory use and 75
formatting 89
returning to TOW 78, 84
input216, 217
defined 15
inspecting 8 7-102, See also Inspector demo programs See demo programs
windows
dynamic link libraries 169
in recursive functions 74
startup code 173
manipulating 29
features 1, 18
modifying 54 functions 144
objects
recursive 74
complex 92 message logs and 27
compound 91, 93
multi-language programs 10
inspecting 88, 184 multiple components 53
pointing at 91
object-oriented programs See object-oriented
watching 92
programs, debugging
raw ObjectWindows programs 223
displaying 183 required files 2
examining 94 restrictions 16
inspecting 184 routines 123, 210
viewing 28, 184, 244 recursive 71
structures, inspecting 22, 156 sessions 69
testing, invalid input and 216 preparing programs for 57-67, 216
truncated 89
starting 85
types 87
simple programs 209
complex 87 source files and 2
converting See type conversion
steps 15
inspecting 31, 94-100
strategies 218
problems with 71, 89, 147
terminology 3
tracking 117
tips
variables and 258
DLL Startup buttons 172
values 216 Load Symbols reset 172
setting breakpoints for 117 window messages 165
viewing 178
tools 17
in recursive routines 71
tutorial 43
incorrect values shown 77
Helpwith45
watching See Watches window TOODEMOB 227-238
Data Member pane 152 variables 210
local menu 153, 155
uninitialized 210
Data menu 88-91, 189
Index 269
distribution disks 9 errors
copying 9 boundary See boundary errors
DLL See dynamic link libraries Exception 13 77
-do option (run on secondary display) 61 fatal 248
DOS messages 248-262
versions 75 escape sequences, Turbo C++ for Windows 142
wildcards, choosing files and 127 Evaluate input box 89
double colon(::) operator 143, 145 Evaluate/Modify command 88-91, 131
drawing, cursor off-screen, with TDODEMOB Evaluate/Modify dialog box 89, 131
235 using220
drives See disk drives Exception 13 error message 77, 227
-ds option (swap screens) 61 exception codes 77
Dump Pane to Log command 121 13 77
Dump window 28, 184 executable program files See files
local menu 194 Execute option (breakpoints) 113
duplicate windows, opening 30 Execute To command 79
Dynamic Link Libraries execution history 81
expressions, accessing 138 backward trace and 82
scope considerations 138 deleting 82
dynamic link libraries losing 83
debugging 169 recovering 83
startup code 173 Execution History command 82
reverse execution, and 80 Execution History window 29
dynamic virtual member functions 223 opening 82
exit code, returned to Windows 77
E exiting, TOW 67
exiting, TOW, tutorial 44
EasyWin module 43
expanded memory specification See EMS
Edit command, Watches window local menu 93
Expression Language dialog box 132
Edit menu 188
Expression True Global command (breakpoints)
editing
105
expressions 93
Expression True option (breakpoints) 112
history lists 24
expressions 131-148
EGA See also graphics adapters; video adapters
Clipboard, watching in 39
line display 66
complex 88
EMS
editing 93
execution history and 82
entering, problems with
information about 75
character constants 254
end of lines, problems with 261
inactive scope 250
Enhanced Graphics Adapters See EGA
invalid characters 262
Enter Program Name to Load dialog box 85
invalid variables 261, 262
Erase Log command
memory areas 259
Log window local menu 122
no record name for field 257, 258
Windows Messages window 165
not routine name 258
Erase Log File command 122
operators 252, 253, 255
erasing a window, TDODEMO program 237
too complex 253
evaluating 88-91, 220
Index 271
filled arrow 48 disassembler and 180
Flags pane 181 global variables See also variables
floating point changing 72
constants debugging, in subroutines 210
Turbo Assembler 146 inspecting 71, See also Inspector windows
Turbo C++ for Windows 142 same name as local 71
numbers viewing 27, 70
formatting 148, 183 instack27
problems with 29 Watches window, adding to 72
registers 244 GlobalAlloc function 166
problems with 255 GlobalLock function 167
format specifiers 89, 148 GlobalPageLock function 167
problems with Go to Cursor command 78
invalid string 254 Goto command
Full History command 83 File window local menu 129
function keys 42, See also hot keys; keys Module window local menu 127
summary of 185-187 graphics adapters See also hardware
Function Return command 91 EGA66
functions problems with 262
calling 91 supported 248
debugging 144 VGA66
inspecting See Inspector windows Group command (breakpoints) 107
recursive, local data and 74
return values and current 91 H
returning from 79
-h option (help) 61
stepping through 80
handle
variables and inactive 250
memory
Windows See Windows, functions
functions, member, dynamic virtual 223 casting to far pointer 175
listing global memory, and 166
window
G accessing in ObjectWindows programs 231
Get Info command 75 HWindow in MainWindow 232
GetWindowClass function (TDODEMO) messages
Scribble Window 225 and 159, 162
gh2fp (type-cast symbol) 175 hardware
global breakpoints See also breakpoints, global adapters See graphics adapters; video
where occurred in program 77 adapters
global memory, Windows breakpoints 118
information about 75 memory variables and 117
listing 166 debugging 13
global menus 19, See also menus problems with 251, 257
local vs. 23 setting breakpoints 105
reference 187-190 TDDEBUG.386 file required for 12
Global pane 70 primary and secondary displays 61
local menu 71 requirements 2
Global Symbol pane local menu 198 Hardware Breakpoint command 105
global symbols 198 Hardware option (breakpoints) 112
Index 273
inline assembler See also assembler closing 31
arrays, inspecting 99 compound data objects and 88, 102
constants 146 functions 9 7
data, inspecting 98-100 global symbols and 71
expressions 146-147 language-specific programs and 94
INCLUDE compiler directive 123 local menus 100-102
instructions See also instructions class 200
keywords, problems with 256 object 200
operators, precedence 147 local symbols and 72
pointers, inspecting 98 member functions 152
scalars, inspecting 98 objects 156
structures, inspecting 100 opening 26
symbols 146 additional 31
unions, inspecting 100 panes
input See I/O class 152
input boxes 21, See also dialog boxes object 155
Action Expression 113 pointers 95, 98
Address (breakpoints) 106, 110 problems with
Condition Expression 112 character values in 95
entering text in 24, 25 multiple lines and 96, 99
Evaluate 89 pointers to arrays 96
Group ID (breakpoints) 110 reducing number onscreen 102
history lists and 24-25 scalars 95, 98
moving around in 202 structures 96, 100
NewValue89 unions 96, 100
Pass Count 115 using
Result 89 C tutorial 51
Save To 67 in demo programs 219
Tab Size, TDW 66 variables in 71
Inspect command 51 viewing contents as raw data bytes 94
Breakpoints window local menu 107 INSTALL.EXE 9
Class List pane local menu 150 installation 12
Data Member pane local menu 152, 153, 156 TDDEBUG.386 12
Data menu 31, 88 TDW9
Global pane local menu 71 instruction opcodes, illegal 77
Hierarchy Tree pane local menu 151 Instruction Trace command 80
Inspector window local menu 101 execution history and 82
Instructions pane local menu 82 instructions See also Instructions pane
Member Functions pane local menu 154 assembling 178
• I
Module window local menu 125 problems with 254, 255, 256
Parent Tree pane local menu 152 base and index registers 256, 260
Stack window local menu 74 instruction mnemonics 255
Static pane local menu 72 invalid registers 256
Watches window local menu 93 size indicators 259
Inspector windows 17, 22, 31, 94-102 target addresses 251
arrays 97, 99 back tracing into 83
classes 154 breakpoints and 116
Index 275
global memory 166 Local Symbol pane local menu 199
local heap 168 local variables See also variables
modules, Windows 168 breakpoints and 118
Load Modules or DLLs dialog box 170 changing 72
LoadLibrary function 172 global values and 71
local and static variables inspecting 72, See also Inspector windows
selecting for Variables window 73 problems with 262
watching 73 viewing 27
local heap 168 in stack 27
local memory, Windows, listing 168 specific instances of 71, 74
local menus 22-24, See also menus LocalAlloc function 168
accessing 23 Locals command 71, 74
Breakpoints window 106-10 7, 191 location, breakpoints 103
Class List pane 150 LockData function 167
Class pane 19 7 Log command (breakpoints) 120
Code pane 191 log files 243
Control pane 197 opening, problems with 250, 252
Data Member pane 153, 155 writing to, problems with 252
Data pane 192 Log option (breakpoints) 113
Dump window 194 Log To File command 252
File window 194 Log window 27, 120-122
Global pane 71 adding comments to 243
Global Symbol pane 198 local menu 121, 194
Hierarchy Tree pane 151, 198 opening 120
Inspector windows 100-102, 200 window messages, sending to 165
Instructions pane 82, 194 Logging command 122
Local Symbol pane 199
Log window 121, 194 M
Member Function pane 154
machine instructions 178
Message Class pane 196
executing 78, 79, 80
Messages pane 196
macros 26
Modulewindow 125-127, 195
recording
Object Member function pane 156
keystrokes as 64
Parent Tree pane 152, 198
problems with 246, 260
Register pane
removing 65
CPU window 193
restoring to previous 65
Numeric Processor window 197
saving 67
Registers window 198
Macros command 64
Selector pane 192
Macros option (save configuration) 67
Stack pane 193
MainWindow object, inspecting 231
Stack window 74, 198
MANUAL.TDW 10
Static pane 72
math coprocessor See numeric coprocessors
Status pane 197
Member Function pane 152
Varibles window 198
local menu 154
viewing hot keys in 42
memory
Watches window 93, 199
addresses 131
Window Selection pane 195
disassembler and 180
Index 277
scope override and 93 problems with 253
CandC++ 134 Turbo Assembler 147
Pascal 137 Turbo C++ for Windows 142
setting breakpoints in other 118 hexadecimal 66
tracing into 80 scalar 139
tracking 30 numeric coprocessors See also 80x87
viewing 28, 124-127 .coprocessors
duplicate 126 current state, viewing 29
problems with 257, 261 registers, entering new values for 244
source code in 244 numeric exit code 77
Windows, listing 168 Numeric Processor window 29
modulus operator, problems with 252 opening, problems with 257
monitors See also hardware; screens panes 197
display swapping 61
monochrome 61 0
mouse
Object Member function pane
choosing menu commands 19-20
local menu 156
moving around in dialog boxes 21
object modules 123
setting breakpoints 49, 104
object-oriented programs
support
classes, inspecting 154
disabling/ enabling 62
compatibility with Turbo Debugger 149
online help 41
debugging 17, 156
windows and 32-33
nested object structures 152
multi-language programs 10
multiple inheritance 151 this parameter and 93
expressions, problems with 250
member functions
N problems with viewing 251
nested classes, scope of 137 member functions, inspecting 152
New Expression command objects
Data Member pane local menu 156 formatting 89
Inspector window local menu 102 hierarchy tree 150
new features for version 3.0 1 inspecting 156
New Value input box 89 scope override 137
Next command See also Search command objects, data See data, objects
File window local menu 130 ObjectWindows
Module window local menu 127 applications, debugging 223
problems with 257 TApplication object 226
Next Pane command 34 online help See also help
Next Window command 34 dialog boxes 21
nonprinting characters 95 OOP See object-oriented programs
return value 148 opcodes, illegal instruction 77
null-terminated character string 95, 99 Open command 85
numbering system, windows 33 Open Log File command 121
numbers 91 operands 91, 253
decimal 66 instruction, memory pointers and 180
floating-point See floating point, numbers problems with 259
formatting 148 invalid 255
Index 279
returning to 75, 127, 139 running 29, 69, 86, See also programs,
scope 139 execution
overriding mechanism and 92 to breakpoints 50
verifying 30 command-line options and 86
watching 72, 80, 123, See also Watches to cursor 48, 78
window at full speed 78
current state 70 to labels 49, 79
inspecting 70-77, See also Inspector returning information on 75
windows in slow motion 80
debugging 16, 17, 57-60, 207-208, See also Windows, from 60
debugging scope See scope
current scope and 139 source code See code
dynamic link libraries 169 source files and 124
planning for 67, 216 stepping through
returning information on 75-77 problems with 76
starting TDW 58 tutorial 48
with no debug information 80, 260 stopping 84, See also breakpoints
with out-of-date debug information 260 stopping (breakpoints) 118
demo See demo programs watching See Watches window
execution See also programs, running Windows
controlling 69-86 debugging 157
menu options 78 not loaded, problems with debugging 76
reversing 80, 82 stopping, messages about 76
problems with 83 unexecuted, problems with examining values
terminating See programs, stopping 77
fatal errors and 248 protected mode, selectors, accessing 181
full output screen 30 pseudovariables (Turbo C++ for Windows) 140
incremental testing 209 pull-down menus 19
inspecting 22, See also Inspector windows
language options, overriding 132 Q
loading 245, See also files, opening
Quit command, TDW 67
dynamic link libraries 169
new85
problems with 257, 260 R
symbol tables and 258 radio buttons 21, See also dialog boxes
message logs and 27 Action 113
modifying See programs, altering Changed Memory 117
multi-language 10 changing settings 21
opening See programs, loading Condition 112
patching, temporarily 178 Display Swapping 65
recompiling 18 Expression Language 132
recovering 83 Integer Format 66
reloading 81, 85 Log 119
Windows and Ctrl-Alt-SysRq 84 Screen Lines 66
restarting a debugging session 85 Range command
returning from 48 Data Member pane local menu 155
returning to 75, 126 Inspector window local menu 101
Index 281
implied, evaluating expressions and 139 Selector command
nested classes 137 Selector pane local menu 182
overriding 134-138 Selector pane 181
tips local menu 182, 192
C, C++, Turbo Assembler 136 memory segments in 181
Pascal 138 Send to Log Window command (Windows
problems with, inactive 250 Messages window) 165
templates 136 Set Message Filter dialog box 163
this parameter 89 Set Options command (breakpoints) 106
Screen Lines radio buttons 66 SetCapture function 235
screens See also hardware; monitors SetupWindow function, redeclaring 231
display modes See display, modes shortcuts See hot keys
layouts, restoring 36 Show command 73
lines per, setting 66 Show Inherited command
problems with Data Member pane local menu 153, 156
graphics display 36 Member Functions pane local menu 154
writing to 65 side effects
startup, TDDEMO 44 changing variable values with 90
swapping 65 splicing code (breakpoints) 113
User See User screen Size/Move command 35
ScribbleWindow type (TDODEMO) 225 Smart option (display swapping) 65
scroll bars 32 software, requirements 2
scrolling 31 sort order, international 2
dialog boxes 203 source code See code
Help screens 41 source files 3, See also files
Inspector windows 52 language conventions and 132
menus20 loading 124, 247
text boxes 202 problems with 261
text panes 201 search paths for 2
-sd option {set source directories) 62 Source option {language convention) 132
Search command See also Next command stack 84, 178, See also Stack pane; Stack
File window local menu 129 window
history lists and 24 current state 27, 73-74
Module window local menu 126 pointer, current location 183
search paths, source files, for 2 Stack command 71, 73
search templates 204 Stack pane
secondary display 61, See also display, current stack pointer 183
swapping local menu 193
segment stack trace 227
overrides, problems with 250 Stack window 27, 73-74
pointers to register 148 local menu 74, 198
registers, program termination and 84 opening 71, 73
select by typing 25 stack trace 227
SelectBlackPen function (TDODEMO) Standalone Debugging command 57
bugs starting directory, changing 63
finding 230 starting TDW 58
fixing 233 in assembler mode 62
Index 283
SelectBlackPen function Trace Into command 78
bug, finding 230 continuous. tracing 80
bug, fixing 233 execution history and 82
SetupWindow function 231 programs executing in ROM and 251
stack trace 227 tracepoints 103, See breakpoints
UpdateWindow function 237 tracing 17, See also Trace Into command
WMLButtonDown function backward See backward trace
bug, finding 234 continuous (animation) 80, 242
bug, fixing 229, 235 execution history and 81
ScribbleWindow 226 into interrupts 80
WMLButtonUp function 226 into functions 48
WMMouseMove function 226 program termination, and, information about
bug, finding 227 76
WMRButtonDown function 226 this parameter and 89, 93
bug, finding 236 Tree command 151
bug, fixing 238 Turbo C++, versions compatible with TOW 2
.TDS files, creating 11 Turbo C++ for Windows
TOW arrays 212
logging window messages 158 inspecting 97
window object, adding 161 problems with 96
window selection automatic variables (autovariables) 214
adding 159 scope 214
deleting 162 uninitialized 211
technical support 5 bugs specific to 211-215
templates character strings 142
breakpoint behavior 119 compiler 211
scopeof 136 constants 142
ternary operators 143 data
text 66 inspecting 95-98
entering types, converting 145
active windows and 31 demo programs, debugging 217
in input boxes 24, 25 dynamic virtual member functions 223
incremental matching 25 escape sequences 142
in log 243 expressions 140-146, 212
searching for 204, 261 with side effects 90, 144
strings, searching for 24 #define macros and 214
text files 128, 201 functions 144
text modes See display, modes inspecting 97
text panes 201, 243, 246 problems with 90
moving around in 201 returning from 214
this parameter 89 integer assignment 213
watching 93 keywords 145
tiled windows 46 keywords, problems with 256
time delays, setting 80, 242 loops, exiting 215
Toggle command operators 212
Breakpoints menu 116 expressions with side effects and 90, 144
Toggle command 105 precedence 143, 212
Index 285
w exit code returned to 77
functions
Watch command
GlobalAlloc 166
Global pane local menu 72
GlobalLock 167
Module window local menu 125
GlobalPageLock 167
Static/Local pane local menu 73
lnvalidateRect, in TOODEMO 237
Watches window local menu 93
InvalidateRgn 237
Watch dialog box, global symbols and 72
LoadLibrary 172
Watches command 92
LocalAlloc 168
Watches window 27, 92-94
LockData 167
local and static symbols and 73
ReleaseCapture 235
local menu 93, 199
SetCapture 235
opening 92
UpdateWindow 237
using220
Languages setting 2
C tutorial 50
reference books 7
watchpoints 17, 103, See also breakpoints
returning to 6 7
C tutorial 50
running programs from 60
Clipboard, and 39
selectors, accessing 181
reloading programs and 85
switching applications, TDW and 60
wildcards
Task List, TDW and 60
DOS 127,261
TDW,and 157
searching with 126, 204
tips, debugging tips 83
window handle
window messages
accessing in ObjectWindows programs 231
TOODEMO
HWindow in MainWindow 232
WM_LBUTTONOOWN 234
Window menu 47, 190
WM_LBUTTONUP 234
opening 33
WM_MOUSEMOVE 234
window management and 33
WM_NCMOUSEMOVE 234
window messages
WM_PAINT 237
breakpoints
Windows Messages command 158
Get Info message about 76
windows 17, 26-36
setting 164
active 31
setting in TDODEMO 230
returning to 20
logging
bottom line in 42
to a file 165
Breakpoints 26, 105-107
to the TDW window 158
Clipboard 30, 196
window object
closing 36
adding to TDW Windows Messages window
temporarily 35
161
CPU See CPU window
Window Pick command 34
Dump 28, 184, 194
window selection
Execution History 29
adding to TDW Windows Messages window
opening 82
159
File 28, 194
deleting from TDW Windows Messages
opening 126
window 162
Hierarchy 149, 197
Window Selection pane, local menu 195
Inspector See Inspector windows
Windows
layout, saving 36, 67
Display Windows Info command 166
Index 287
TURBO
DEBUGGER®3.0
FOR WINDOWS
BORLAND
CORPORATE HEAOOUARTERS: 1800 GREEN HILLS ROAO, P.O. BOX 660001. SCOTTS VALLEY, CA 95067-0001 . (408) 438-5300. OFFICES IN: AUSTRALIA.
DENMARK, FRANCE. GERMANY, ITALY, JAPAN. NEW ZEALAND, SINGAPORE. SWEDEN ANO THE UNITED KINGDOM • PART #14MN-TCW03-10 • BOA 2883