TURBO DEBUGGER TIPS AND HINTS ============================= CONTENTS: 1. Answers to common questions 2. Turbo Debugger for Windows (TDW), Windows debugging hints 3. TDW mouse support 4. TD mouse support 1. Answers to common questions ------------------------------ Following is a list of the most commonly asked questions about Turbo Debugger. 1. How does Turbo Debugger handle screen output for graphics- and text-based programs? There are a number of strategies that can be used to control how and when the screen gets refreshed. You should review the following tips if you are debugging a program that uses a graphics display mode and you want to do either of the following: - use a Borland pop-up utility such as SideKick or Sidekick Plus while inside Turbo Debugger - run programs from Turbo Debugger's DOS Shell that write directly to video memory The default screen-updating mode, "Swap," causes Turbo Debugger to use a single display adapter and display page and swap the contents of the user and Turbo Debugger screens in software. "Swap" is the slowest method of display swapping, but is the most protective and least disruptive. Pop-up utilities might not appear on the screen if your screen updating is set to "Flip," even though they are active and proces- sing your keystrokes. You must select "Swap" mode for display updating in order for these programs to work properly. Use Turbo Debugger's -ds command-line option to do this or use the TDINST utility to permanently set this mode. "Swap" mode makes screen updating slower, but it ensures that Turbo Debugger's screen doesn't interfere with either your program's or any other program's display. You might also need to use "Swap" when you use the DOS Shell command or run an editor from within Turbo Debugger. Most programs expect to run on video page 0 and don't check to see what the current video page is. Turbo Debugger's DOS Shell and any editors that Turbo Debugger runs in "Flip" mode don't run from video page 0, and the programs might appear to hang, even though you will be able to type in keystrokes normally. If this happens, use the -ds command-line option when you run Turbo Debugger or reinstall Turbo Debugger to use "Swap" instead of "Flip." If you are debugging a graphics mode application, you must specify the -ds command-line option ("Swap" contents), and you might want to use Turbo Debugger's -vg command-line option (Graphics Save). This option causes additional memory to be set aside for saving the entire graphics image your program produces. If you don't use this option, a "red cloud" may appear on your program's screen. These options can also be set permanently by using the TDINST program. The Graphics Save option takes an additional 8K of memory and slows screen-swapping. If you're running a graphics program that changes the EGA or VGA palette, make sure you use the -vp command-line option to save the palette. 2. Can Turbo Debugger execute other programs while you're still debugging? The DOS Shell and Edit commands in the Module and File windows can swap to disk the program you are debugging in order to make room to run DOS or your editor. The default amount of memory to swap is 128K. You can use TDINST to set a different amount if that's not enough memory to run your editor or other programs. Setting the swap size to 0K tells Turbo Debugger to swap the entire user program to disk before running the DOS command processor. Only your program gets swapped to disk; Turbo Debugger remains in memory. 3. How can I break out of a program even though interrupts are disabled? If you have an 80386 computer and are using TD386, the -B option allows a break even when interrupts are disabled. For example, this option enables a break from CLI JMP $ 4. Why can't I press Ctrl-Break to get out of a program running on a remote machine? The program running on the remote machine has taken control of Interrupt 1B (Ctrl-Break). TDREMOTE and WREMOTE don't take back control of Interrupt 1B until you stop execution of the running program. To stop execution, run the program to completion or press Ctrl-F2 (Program Reset) on the local machine. 5. What are some of the syntactic and parsing differences between Turbo Debugger's built-in assembler and the standalone Turbo Assembler? A discussion follows this short example program: .model small .data abc struc mem1 dd ? mem2 db ? mem3 db " " abc ends align 16 a abc <1,2,"xyz"> msg1 db "testing 1 2 3", 0 msg2 db "hello world", 0 nmptr dw msg1 fmptr dd msg1,msg2 nfmptr dw fmptr xx dw seg a .code push cs pop ds mov bx,offset a mov bx,nmptr les si,fmptr mov ah,4ch int 21h end Because the assembler expression parser does not accept all legal TASM instruction operands, Turbo Debugger assembler expressions can be more general than those of TASM and can use multiple levels of memory-referencing, much like C and Pascal. However, there are a few constructs that you may be used to that you'll have to specify differently for the TD assembler expression parser to accept them: a. Size overrides should always appear inside the brackets; PTR is optional after the size. Also, when referring to a structure, you must use the name of the struc, not the name of the variable: OK: [byte ptr bx] [dword si] [abc bx] BAD: byte ptr[bx] [struc abc bx] [a bx] b. You must specify a structure name when accessing the members of a structure with a register pointer. OK: [abc ptr bx].mem1 [abc bx].mem3 + 1 BAD: [bx].mem1 c. You can't use multiple instances of brackets ([]) unless they are adjacent, and you can only follow a bracketed expression with a dot and a structure member name or another bracketed expression: OK: 4[bx][si] [abc bx].mem2 BAD: [bx]4[si] [bx]+4 d. If you use a register as part of a memory expression and you don't specify a size, WORD is assumed: [bx] is the same as [word bx] e. You can use any register you want between brackets ([]), not just the combinations of BX, BP, SI, and DI allowed in instruction operands. For example, [ax+bx] [bx+sp] f. You can use multiple levels of brackets to follow chains of pointers. For example, [byte [[nfmptr]+4]] g. Be careful with using registers to access memory locations. You might get unexpected results if your segment registers are not set up properly. If you don't explicitly specify a segment register, Turbo Debugger uses the DS register to reference memory. h. When you do specify a segment register, make sure you follow the same rule for size overrides: put it INSIDE the brackets, as follows: OK: [byte es:di] [es:fmptr] BAD: es:[byte di] i. Use the OFFSET operator to get the address of a variable or structure. Turbo Debugger automatically supplies the brackets around a variable name if you just type the variable name alone. a contents of structure a [a] contents of structure a offset a address of structure a j. You can use the type overrides and the format control count to examine any area of memory displayed as you wish. [byte es:bx],10 10 bytes pointed to by es:bx [dword ds:si],4 4 dwords pointed to by ds:si This is very useful when specifying watch expressions. k. Sometimes you use a word memory location or register to point to a paragraph in memory that contains a data structure. Access the structure with expressions like [abc [xx]:0].mem1 [abc es:0].mem3 6. Are there any syntactic or parsing differences between Turbo Debugger's Pascal expression evaluation and Borland Pascal's? a. Turbo Debugger doesn't support expressions for set constructors: OK: [4..7] BAD: [myvar1..myvar2] [3+4..7+8] b. You can't pass constant-string arguments when evaluating functions or procedures. OK: MyFunc(123) MyFunc(StringVariable) BAD: MyFunc('Constant') MyFunc(StringConstant), where StringConstant is defined with a "const" declaration and is not a typed constant. c. You can't evaluate procedures or functions that have structure VALUE parameters. You can evaluate procedures or functions that have structure VARIABLE parameters, though. 7. What should I be aware of when I'm debugging multilanguage programs with Turbo Debugger? Turbo Debugger's default source language is "Source," which means it chooses the expression language based on the current source module. This can cause some confusion if your program has source modules written in different languages (like Pascal and assembler). Since you are actually entering a language expression any time Turbo Debugger prompts you for a value or an address, you can encounter unexpected results. a. Even if you are in a CPU window or a Dump window, you must still enter addresses in the source language, despite the fact that the window displays in hex. For example, to display the contents of memory address 1234:5678, you must type one of the following expressions, depending on your current source language: C 0x1234:0x5678 Pascal $1234:$5678 Assembler 1234H:5678H b. When your current language is assembler, you must be careful when entering hex numbers, since they are interpreted EXACTLY as they would be in an assembler source file. This means that if you want to enter a number that starts with one of the hex digits A - F, you must first precede the letter with a 0 so Turbo Debugger knows you are entering a number. Likewise, if your number ends in B or D (indicating a binary or decimal number), you must add an H to indicate that you really want a hex number. For example, OK: 0aaaa 123dh 89abh BAD: aaaa 123d 89ab 7. Why does the text "Cannot be changed" come up when I do an assignment in the Data|Evaluate|Modify "New value" pane? If you use the Data|Evaluate|Modify command (Ctrl-F4) to change a variable by direct assignment, the "New value" pane will say "Cannot be changed." This doesn't mean the assignment didn't take effect. What it does mean is that the assignment expression as a whole is not a memory-referencing expression whose value you can change by moving to the bottom pane. Here are some examples of direct assignment expressions: C x = 4 Pascal ratio := 1.234 Assembler wval = 4 shl 2 If you had typed just "x", "ratio", or "wval" into the top pane, you would be able to move to the bottom pane and enter a new value. The direct assignment method using the "=" or ":=" assignment operator is quicker and more convenient if you don't care about examining the value of the variable before modifying it. 8. What is the most likely reason for Turbo Debugger to hang when starting up on a PC-compatible computer? If your computer is a Tandy 1000A, IBM PC Convertible, or NEC MultiSpeed, or if Turbo Debugger hangs when loading on your system, run TDINST and change an item in the Options|Miscellaneous menu so that NMI Intercept isn't set. Some computers use the NMI (Non-Maskable Interrupt) in ways that conflict with Turbo Debugger, so you must disable Turbo Debugger's use of this interrupt in order to run the program. Also, if you're using an 80386-based machine and have the SuperKey utility loaded, be careful not to press a key when TD386 is loading, since SuperKey might capture the keystroke and cause unexpected results. 9. What could happen when global breakpoints are set on local variables? When you set global breakpoints using local variables, make sure the breakpoints are cleared before you exit the procedure or function that the variables are defined in. The best way to do this is to put a breakpoint on the last line of the procedure or function. If you do not clear the breakpoints, your program will break unexpectedly and may even hang on some machines because the breakpoints are being set in memory that is not currently being used by the procedure or function. 10. How can I save options set in TDINST to TD286.EXE? If you have a configuration file (tdconfig.td) already made for TD.EXE, TD286.EXE will automatically use this configuration file. You can save a configuration made in TDINST to TD286.EXE directly if you state this on the command line. For instance, TDINST TD286.EXE When you want to save this configuration in TDINST, just select Save\Modify td.exe. 11. Why is execution slower when tracing (F7) than when stepping (F8) through my programs? Turbo Debugger can do reverse execution. When you're tracing through your program, Turbo Debugger is saving all the information about the source line you just traced over. If you want faster execution you can (F8) step over the instruction or toggle the Full History option to "No" in the Execution History window. (Although reverse execution is always available in the CPU viewer this option must be toggled to "Yes" to work in the Module viewer. The default setting is "No".) 12. What are some of the issues I should be aware of with TD386? TD386.EXE is a small kernel program that puts the processor into virtual-86 mode, maps one chunk of extended memory into the low 640K area, and loads TD.EXE into it. It communicates with TD.EXE through the TDH386.SYS device driver. When instructed to, TD386 maps a different chunk of extended memory into the low 640K area. It then loads the program to be debugged, into that same area. The debugging process continues with TD's telling TD386 what to do through TDH386. When any exceptions occur, they are vectored off to the resident TD386 code which handles them. TD386 either switches back to TD's area and informs TD that an exception occurred or, if TD386 can't figure out what happened, it simply dumps the registers to the screen and halts the CPU (since something bad could have happened to cause the exception) Because TD386 uses the virtual-86 mode of the 80386, it cannot coexist with any other programs that put the processor into v-86 mode. Programs that simulate EMS memory on a 386 or 486 machine usually use virtual-86 mode to do so. These programs (such as QEMM, 386^MAX, CEMM, EMM386,...) are not compatible with TD386. If you need to use one of these EMS simulators for your program, then you should consider using TD286.EXE, which uses a different aspect of protected mode and IS compatible with these other programs. Note: HIMEM.SYS does not use virtual-86 mode and behaves just fine with TD386. As well as providing a communication path between TD386 and TD, TDH386 (the device driver) allows for the use of hardware breakpoints. You can use the hardware breakpoints on any 386 or 486 machine that has the device driver loaded and is running TD.EXE, TD286.EXE, or TD386.EXE. The only real difference between TD386 and the other two debuggers is that TD386 allows some extra breakpoints that the other debuggers do not (I/O access breaks, ranges greater than 16 bytes, and so on). A typical setup would be to load QEMM and then load TDH386.SYS into high memory. With this setup, both TD.EXE and TD286.EXE will support hardware breakpoints and will take up the same amount of memory as they do without the device driver loaded. If you are using a SCSI device in your machine and TD386 gives you unexpected interrupt reports, make sure that the SCSI device driver is protected-mode-aware. Adaptech SCSI cards come with a driver that should work just fine. IBM PS/2's usually have a driver called DISK386.SYS that works in this situation. 13. Why does TD286INS tell me that my A20 line is already enabled? If you are using a version of DOS that allows you to specify the "DOS=HIGH" command in CONFIG.SYS, you won't be able to run TD286INS. What you should do is remove the 'DOS=HIGH' line, then run TD286INS, and then replace the "DOS=HIGH" line in CONFIG.SYS. 14. Why do I have mouse problems when debugging Windows programs? When debugging, the first time you execute a Windows program, the mouse will work normally. For the second and subsequent runs, you must press any key before the mouse will function. This is a known problem with Windows. When the mouse driver is disabled for Windows, it will be disabled for TDW as well. Starting TDW with the mouse support option (-p) has no effect. 2. Turbo Debugger for Windows (TDW), Windows debugging hints ------------------------------------------------------------ View|Windows Messages If you set up View|Windows Messages to display messages for more than one procedure or handle or both, do not log all messages. Instead, log specific messages for each procedure or handle. If you log all messages, the system might hang, in which case you will have to reboot to continue. This behavior is due to the large number of messages being transferred between Windows and TDW. When setting a break on the Mouse class of messages, note that a "mouse down" message must be followed by a "mouse up" message before the keyboard will become active again. When you return to the application, you might have to press the mouse button several times to get Windows to receive a "mouse up" message. You'll know Windows has received the message when you see it in the bottom pane of the Windows Message window after the program breaks. If you enter a handle name but indicate that it's a procedure, TDW will accept your input and will not complain. However, when you run your program, TDW will not log any messages. If TDW is not logging messages when you think you've set a handle, check the Add Window dialog box of the top left pane of the Windows Messages window to see if you've pressed the Handle button. View|Module The Debug Startup radio buttons are used for DLLs only. To debug EXE startup, begin TDW with the Assembler-mode Startup command-line option (-l). When a program loaded into TDW is reset, the Load symbols radio buttons default to YES for all DLLs and applications with symbols, even if you specified NO for a given DLL or application prior to resetting the program. 3. TDW mouse support -------------------- TDW provides mouse support that allows you to manipulate elements of the user interface. Most TDW mouse operations are similar to Windows mouse operations. In the material that follows, we discuss tips for using a mouse under Windows and some uses of the mouse under TDW that are different from Windows mouse usage. o When the mouse driver is disabled for Windows, it will be disabled for TDW as well. Starting TDW with the mouse support option (-p) has no effect unless you enable the Windows mouse driver. o If you have a mouse driver installed by default, TDW and the installation utilities will try to use your mouse. If you don't want to use your mouse during a debugging session, you can use the command-line switch '-p-' to turn the mouse off. You can also set this option in TDWINST in the Options\Input & Prompting dialog box. o When you're debugging a Windows application that uses the mouse and you reset the application and then run the program, it won't accept mouse clicks until you make a keyboard entry. o Using the mouse - Most mice provide two or three buttons that allow for various functions inside an application. With TDW you can, among other things, use the left mouse button to select options, move items around on the screen, and set breakpoints. - Double-clicking the mouse on an item in a list chooses the item. For instance, in the File|Open dialog box clicking the mouse once just highlights a file. Double-clicking loads the file. - The right mouse button has some of the same functionality as the left mouse button, but you can also open local menus within TDW windows by using this button. o You can also choose the commands shown at the bottom of the screen, like F1-Help, by using the mouse. 4. TD mouse support ------------------- You use the mouse with TD just as you do with TDW. However, with TD you must install a mouse driver, which makes your mouse active with TD and other programs. Most mouse drivers will work with TD, but might have to be updated to a newer version if you're having problems using your current version. If you have problems with the mouse after you've loaded TD or TDINST, you might try using the Display Swap option that you can specify either in TDINST or on the command-line with the -ds switch. Consult your mouse manual to ensure proper use of the mouse and its driver. Early versions of mouse drivers don't support screen display modes larger than 80 columns by 24 lines. As a result, your mouse driver might not work correctly when you use TD's enhanced display modes (EGA 80x43, VGA 80x50, or EGA/VGA graphics modes).