CDB(1) HP-UX 5.0 CDB(1) NAME cdb, fdb, pdb - C, FORTRAN, Pascal symbolic debugger SYNOPSIS cdb [-d dir] [-r file] [-p file] [-S num] [objectfile [corefile]] fdb [ cdb options ] pdb [ cdb options ] HP-UX COMPATIBILITY Level: HP-UX/DEVELOPMENT Origin: HP Remarks: This debugger is currently implemented on the Series 200 and the Series 500. DESCRIPTION Cdb, fdb, and pdb are alternate names for a source level debugger for C that provides a controlled execution environment for HP FORTRAN, and HP Pascal programs. Objectfile is an executable program file having one or more of its component modules compiled with the -g option. The support module /usr/lib/end.o must be included as the last object file in the list of those linked, except for libraries included with the -l option to ld(1). (Some systems automate this; see the Hardware Dependencies section below.) The default for objectfile is a.out. Corefile is a core image from a failed execution of objectfile. The default corefile is core (Series 500 does not support corefiles). The options are: -d dir names an alternate directory where source files are located. -r file names a record file which is invoked immediately (for overwrite, not for append). Used with Record/Playback Commands. -p file names a playback file which is invoked immediately. Used with Record/Playback Commands. -S num sets string cache size to num bytes (default num varies with symbol table format; not available for all formats). String cache holds data read from objectfile. Only one objectfile and one corefile is allowed per debugging session. The program (objectfile) is not invoked as a child process until an appropriate Job Control Command command is given. The same program can be restarted many times (as different child processes) during a single debugging session. COMMANDS The debugger has a various commands for viewing and manipulating the program being debugged. File Viewing Commands May change current viewing position, but do not affect the next statement (if any) to be executed in the child process. dir "directory" Add directory to the list of alternate source directories. Same as using -d invocation option. Main procedure file must reside in the current directory or be specified with the -d option. e Show current file, procedure, line number, and source line e (file | proc) Enter (view) file or proc and print its first executable line. File can be any file, but must not be object code. [depth] E Like "e", but sets viewing location to the current location in proc on the stack at depth depth (not necessarily first executable line in the procedure). Default Depth is zero (where program is currently stopped). L Synonym for 0E. line Print source line number line in current file. [line] p [count] Print one (or count) lines starting at current line (or line number line). If multiple lines are printed, current line is marked with "=" in leftmost column. +[lines] Move to lines (default one) lines after current line. -[lines] Move to lines (default one) lines before current line. [line] w [size] Print window of text containing size (default 11) lines centered around current line (or line). Target line is marked with "=" in leftmost column if more than one line is printed. [line] W [size] Same as "w", but size defaults to 21 lines. +w [size] +W [size] Print window of text of given or default size, beginning at end of previous window if the previous command was a window command; otherwise at current line. -w [size] -W [size] Print window of text of given or default size, ending at beginning of previous window if previous command was a window command; otherwise at current line. /[string] Search forward through the current file for string, starting at the line after the current line. ?[string] Search backward for string, starting with the line before the current line. n Repeat previous "/" or "?" command using same string as before. N Same as "n", but search goes in opposite direction from that specified by previous "/" or "?" command. Display Formats A format is of form "[*][count]formchar[size]". Display formats apply only to Data Viewing Commands, described in the next sub-section. "*" means "use alternate address map" (if maps are supported). Count is the number of times to apply the format style formchar (must be a number). Size is number of bytes to be formatted for each count (overrides default size for the format style); must be positive decimal number (except short hand notations). Size is disallowed with formchars where it makes no sense. Uppercase characters can be used with formats that print numbers to obtain same results as appending "l" (useful on systems where integer is shorter than long). Available formats include: n Print in "normal" format, based on type. char arrays and pointers to char are interpreted as strings, and structures are fully dumped. (d | D) Print in decimal (as integer or long). (u | U) Print in unsigned decimal (as integer or long). (o | O) Print in octal (as integer or long). (x | X) Print in hexadecimal (as integer or long). (b | B) Print a byte in decimal (either way). (c | C) Print a character (either way). (e | E) Print in "e" floating point notation (as float or double) (see printf(3)) (floating point constants are always doubles). (f | F) Print in "f" floating point notation (as float or double). (g | G) Print in "g" floating point notation (as float or double). a Print a string using expr as the address of the first byte. s Print a string using expr as the address of a pointer to the first byte (same as "*expr/a", except for arrays). t Show type of expr (usually a variable or procedure name). For true procedure types you must actually call the procedure, e.g. "def (2)/t". p Print the name of the procedure containing address expr. S Do a formatted dump of a structure. expr must be address of a structure, not address of pointer to a structure. Shorthand notations for size can be appended to formchar instead of a numeric size: b 1 byte (char). s 2 bytes (short). l 4 bytes (long). If you view an object with size (explicitly or implicitly) less than or equal to size of a long, debugger changes basetype appropriately for that size so "." (dot) can work correctly for assignments (may reduce accuracy or produce wrong value). Data Viewing Commands expr If expr does not resemble anything else (such as a command), it is handled as "expr/n" (print expression in normal format), unless followed by ";" or "}", in which case nothing is printed. expr/format Print the contents (value) of expr using format. expr?format Print address of expr using format. ^[[/]format] Back up to preceding memory location (based on the size of last thing displayed). Uses format if supplied, or the previous format if not. No "/" is needed after "^". To reverse direction again (e.g. start going forward), enter "." or dot (always an alias for current location) followed by carriage return. l [proc[.depth]] List all parameters and local variables for current procedure (or proc, if given, at the specified depth, if any). Datadisplay uses "/n" format, except arrays and pointers are shown as addresses; only the first word of a structure is shown. l (a | b | d | z) List all assertions, breakpoints, directories, or zignals. l (f | g | l | p | r | s) [string] List all files (source files which built objectfile), global variables, labels (program entry points known to the linker), procedure names, registers, or special variables (except registers). If string is present, only those things with the same initial characters are listed. Stack Viewing Commands [depth] t Trace stack for the first depth (default 20) levels. [depth] T Same as "t", but local variables are also displayed using "/n" format (except that arrays and pointers are shown as addresses; structures show first word only). Job Control Commands Parent (debugger) and child (objectfile) processes take turns running. Debugger is active only while child process is stopped due to a signal (reaching a breakpoint, or terminated for whatever reason). r [arguments] Run a new child process with given argument list, if any (existing child process, if any, is terminated first). If no arguments are given, those used with last "r" command are used again (none if "R" was used last). Arguments may contain "<" and ">" for redirecting standard input and standard output. ("<" does open(2) on file descriptor 0 for read-only; ">" does creat(2) on file descriptor 1 with mode 0666). Arguments may contain shell variables, metacharacters, quote marks, or other special syntax (expanded by a Bourne shell). "{}" are shell metacharacters, so "r" cannot be safely saved in a breakpoint or assertion command list. R Run new child process with no argument list. k Terminate (kill) current child process, if any. [count] c [line] Continue after breakpoint or signal, ignoring the signal, if any. If count is given, current breakpoint, if any, has its count set to that value. If line is given, a temporary breakpoint is set at that line number, with count of -1 (see Breakpoint Commands). [count] C [line] Continue like "c", but allow signal (if any) to be received. [count] s Single step 1 (or count) statements (successive carriage-returns repeat with count of 1). If count less than one, child process is not stepped. Child process continues with the current signal, if any (set "$signal = 0" to prevent). [count] S Single step like "s", but treat procedure calls as single statements (don't follow them down). If a breakpoint is hit in such a procedure, or in one that it calls, its commands are executed. (usually all right unless there is a "c" command in that breakpoint's command list). Debugger has no knowledge about or control over child processes forked in turn by the process being debugged. Process being debugged should not execute a different program via exec(2). Child process output may be buffered, so it may not appear immediately after you step through an output statement such as printf(3). It may not appear at all if you kill the process. Breakpoint Commands A breakpoint has three associated attributes: address Commands to set breakpoints are alternate ways to specify the breakpoint address. The breakpoint is encountered whenever address is about to be executed, regardless of the path taken to get there. Only one breakpoint at a time (of any type or count) can be set at a given address. Setting a new breakpoint at address replaces the old one, if any. count The number of times the breakpoint is encountered prior to recognition. If count is positive, the breakpoint is "permanent", and count decrements with each encounter. Each time count goes to zero, the breakpoint is recognized and count is reset to one (so it stays there until explicitly set to a different value by "c" or "C"). If count is negative, the breakpoint is "temporary" and count increments with each encounter. When count goes to zero, the breakpoint is recognized then deleted. commands These are actions to be taken upon recognition of a breakpoint before waiting for command input. Separated by ";"; may be enclosed in "{}" to delimit the list, saved with the breakpoint, from other commands on the same line. Results of expressions followed by ";" or "}" are not printed unless you specify print format. Saved commands are not parsed until breakpoint is recognized. If commands are nil at recognition of breakpoint, debugger waits for command input. Breakpoint commands: l b B list all breakpoints in the format "num: count: nnn proc: ln: contents", followed by "{commands}". Leftmost number is an index number for use with "d" (delete) command. [line] b [commands] Set permanent breakpoint at current line (or at line in the current procedure). For immediate continuation, finish the command list with "c". [expr] d Delete breakpoint number expr. If expr is absent, delete the breakpoint at the current line, if any. If there is none, the debugger executes a "B" command instead. bp [commands] Set permanent breakpoints at the beginning (first executable line) of every debuggable procedure. When any procedure breakpoint is hit, commands are executed. D [b] Delete all breakpoints (including "procedure" breakpoints). "b" is optional. D p Delete all "procedure" breakpoints. All breakpoints set by commands other than "bp" remain set. For the following commands, if the second character is upper case (for example,"bU" instead of "bu") the breakpoint is temporary (count is -1), not permanent (count is 1). [depth] bb [commands] [depth] bB [commands] Set breakpoint at beginning (first executable line) of procedure at specified stack depth. If depth not specified, current procedure is used (may not be same as stack depth zero). [depth] bx [commands] [depth] bX [commands] Set a breakpoint at exit (last executable line) of procedure at the given stack depth. If depth is not specified, current procedure is used (may not be same as stack depth zero. The breakpoint is set such that all returns of any kind go through it. [depth] bu [commands] [depth] bU [commands] Set an up-level breakpoint. Breakpoint is set immediately after return to the procedure at specified stack depth (default one, not zero). Zero depth means "current location". [depth] bt [proc] [commands] [depth] bT [proc] [commands] Trace current procedure (or procedure at depth, or proc). Sets breakpoints at entrance and exit of a procedure. Default entry breakpoint commands are "Q;2t;c", (shows the top two procedures on the stack and continues). The exit breakpoint executes "Q;L;c" (prints the current location and continues). If depth is given, proc must be absent or it is taken as part of commands. If depth is missing but proc is specified, the named procedure is traced. If both depth and proc are omitted, the current procedure is traced, which might not be the same as the one at depth zero. If commands are present, they are used for the entrance breakpoint, instead of the default shown above. address ba [commands] address bA [commands] Set breakpoint at given code address. address can be the name of a procedure or an expression containing such a name. If the child process is stopped in a non-debuggable procedure, or in prologue code (before the first executable line of a procedure), results may seem a little strange. The next few commands, are not strictly part of the breakpoint group, but are used almost exclusively as arguments to breakpoints (or assertions). if [expr] {commands}[{commands}] If expr evaluates to a non-zero value, the first group of commands (the first "{}" block) is executed; otherwise it (and the following "{", if any) is skipped. All other "{}" blocks are always ignored (skipped), except when given as an argument to an "a", "b", or "!" command. The "if" command is nestable, and can be abbreviated to "i". Q If the "quiet" command appears as the first command in a breakpoint's command list, the normal announcement of "proc: line: text" is not made. This allows quiet checks of variables, etc. to be made without cluttering up the screen with unwanted output. The "Q" command is ignored if it appears anywhere else. "any string you like" Print the given string. Accepts standard backslashed character escapes, including "\n" for newline. Useful for labelling output from breakpoint commands. Assertion Control Commands Assertions are command lists that are executed before every statement. Thus, if there is even one active assertion, the program is single stepped at the machine instruction level (runs very slowly). They are primarily used for tracking down nasty bugs (such as a corrupt global variable). Assertions can be activated or suspended individually (cdb also supports overall assertions mode). a commands Create new assertion with given command list. List is parsed at execution time. Command list can be enclosed in "{}" to delimit it from other commands on the same line. "l a" command lists all current assertions and the overall mode. expr a (a | d | s) Modify the assertion numbered expr: activate it, delete it, or suspend it. Suspended assertions continue to exist, but do nothing until reactivated. A Toggle overall state of assertions mechanism between active and suspended. D a Delete all assertions. [flag] x Force exit from assertions mode. If flag is absent or evaluates to zero, exit immediately. Otherwise, finish executing current assertion first. If an assertion executes an "x" command, the child process stops and the assertion doing the "x" is identified. Debugger has only one active command line at a time. When assertion command begins execution, any remaining debugger command line is lost. Signal Control Commands Debugger catches all signals bound for a child process before the child process sees them (a function of ptrace(2) mechanism). [signal] z [i][r][s][Q] Maintains the "zignal" (signal) handling table. Signal is a valid signal number (default is current signal). Options (which must be all one word) toggle the state of the appropriate flag: ignore, report, or stop. If Q is present, the new signal state is not printed. "l z" lists current handling of all signals (z with no options shows the state of the current or selected signal. When a child process stops or terminates on a signal it is always reported, unless the breakpoint signal command starts with "Q". When debugger ignores a signal, "c" does not know about it. The signal is never ignored when a child process terminates; only when it stops. Record and Playback Commands Debugger supports a record/playback feature to help recreate program states and record all debugger output. Commands are: >file Set or change recordfile to file and turn recording on. Rewrites file from the start. Only commands are recorded to this file. >>file Same as >file but appends to file instead of overwriting. >@file >>@file Set or change record-all file to file, for overwriting or appending. Record-all file can be opened or closed, independent of recordfile. All debugger standard output is copied to the record-all file, including prompts, commands entered, and command output (does not capture child process output. >(t | f | c) Turn recording on (t) or off (f), or close the recording file (c). When recording is resumed, new commands are appended to previous file contents. In this context, >> is equivalent to >. >@(t | f | c) Turn record-all on, off, or close the record-all file. In this context, >>@ is the same as >@. > Tell current recording status (same as >>). >@ Tell current record-all status. (same as >>@). ", "<", or "!" are not copied to current recordfile (they are copied to record-all file). To override this, begin such lines with blanks. NOTE: Debugger can be invoked with standard input, standard output, and/or standard error redirected, independent of record and playback. If debugger encounters end-of-file while standard input is redirected from anything other than a terminal, it prints a message to standard output and exits, returning zero. Miscellaneous Commands ~ An empty line or a "~" command causes the debugger to repeat the last command, if possible, with an appropriate increment, if any. Repeatable commands are those which print a line, print a window of lines, print a data value, single step, and single step over procedures. is saved in record file as a "~" command, to distinguish from ^D. ^D Control-D is like , but repeats the previous command ten times. Note that this command is saved in a record file as an empty line. ! [command-line] This shell escape invokes a shell program. If command-line is present, it is executed via system(3). Otherwise, the environment variable SHELL gives the name of the shell program to invoke with a -i option, also using system(3). If SHELL is not found, the debugger executes "/bin/sh -i". In any case, the debugger then waits for the shell or command-line to complete. As with breakpoints, command-line can be enclosed in "{}" to delimit it from other (debugger) commands on the same line. f ["printf-style-format"] Set address printing format, using printf(3) format specifications (not debugger format styles). Only the first 19 characters are used. If there is no argument, the format is set to a system-dependent default. All addresses are assumed to be of type long, so you should handle all four bytes to get something meaningful. F Find and fix bug (a useless but humorous command). g line Go to an address in the procedure on the stack at depth zero (not necessarily the current procedure). Changes the program counter so line is the next line to be executed. h help Print debugger help file (command summary) using more(1). I Print information (inquire) about the state of the debugger. M Print current text (objectfile) and core (corefile) address maps. M (t | c) [expr; [expr;...]] Set text (objectfile) or core (corefile) address map. The first zero to six map values are set to the exprs given. q Quit the debugger. Requests confirmation to prevent losing a valuable environment. Z Toggle case sensitivity in searches. This affects everything: file names, procedure names, variables, and string searches! The debugger starts out as not case sensitive. HARDWARE DEPENDENCIES The "bx" (break on exit) command requires that compilers support it by funneling all exits through one point. The breakpoint is always set at the last line of the procedure, which should be, but may not be, the sole exit point. Series 200 and Series 500: When a C parameter is declared as an array of anything, the highest type qualifier (array) shows up as a pointer instead. For example, "int x[]" looks like "int *x", and "char (*x)[]" looks like "char **x", but "char *x[]" is treated correctly as "pointer to array of char". There is limited support for command-line calls of functions which return structures. The debugger interprets the start of heap as a structure of the return type. However, a call such as "abc()/t" displays the return type correctly. $short and $long are available in addition to $result. However, $result is only set to (valid as) the return value from the last procedure called from the command line. If the procedure returns a double, $result is set to the value cast to long. The source file end.c is not supported, so you can't customize /usr/lib/end.o. The buffer size is fixed at 200 bytes. To force linking of library routines not otherwise referenced, use -u option to ld(1). All compiler front ends (cc(1), fc(1), and pc(1)) automatically tell the linker to include /usr/lib/end.o for you if you give the -g (debug) option (compiler front end cannot detect debug options when they are placed in source code instead). Series 200 only: Series 200 supports two types of string formats in addition to null-terminated C strings. FORTRAN character variables consist of a string of bytes (no null terminator). Pascal string variables consist of a length byte, followed by the string characters. The "\s" and "\a" formats will display these types correctly, only if the current language is FORTRAN or Pascal. Series 500 only: "bx" works, except for FORTRAN multiple returns. The compilers emit a special source line symbol for this exit point, after the last "visible" source line. Series 500 supports two types of string formats in addition to null-terminated C strings. FORTRAN character variables consist of four-word (16-byte) string markers, where the second word plus the third word plus three is the byte address of the string itself, and the fourth word is the length of the string. Pascal string variables consist of a four- byte, word-aligned length word followed by the string characters. If the current language is FORTRAN, or if you use "/s" format with fdb or pdb, the debugger interprets the variable (or expression) as a string marker (or address thereof), which is a null pointer if the second word of the marker is zero. Multiple-count formats show a series of fixed-length strings, beginning with the first one pointed to by the marker. Using "" or "^" to go forward or backward in memory uses the four words after or before the current string marker as the new marker. If the current language is Pascal, or if you use "/a" format with fdb or pdb, the debugger interprets the variable (or expression) as a Pascal string (or address thereof). Multiple-count formats show a series of random-length strings, using successive length words, skipping any wasted bytes in the last word of the previous string. Likewise, using "" or "^" to go through memory skips the total bytes consumed in the last display. There is never a corefile, so all features which depend on it don't work. Also, there are no address maps in the usual sense, so the "M" command is not supported. If a child process receives a signal and you then step with the "s" command (or run with assertions active), the process free-runs through the signal handler procedure (if any) before pausing (or doing assertions). Code and data pointers in objectfile both contain segment numbers. At exec(2) time, all such pointers are mapped from ld(1) pseudo-values to real values based on actual segment numbers allocated. The debugger operates in "pseudo-address-space", so you won't notice anything unusual most of the time. All addresses look the same each time you invoke a new child process. For example, the heap always begins at "broken" address zero (0). WARNING: The debugger's interaction with a child process is somewhat complicated, due to the "fixing" of pointer values written to the child and the "breaking" of pointers read from the child. If you tell the debugger to treat a pointer as a non-pointer, it may get confused, with unpredictable results. In particular, if you set a debugger special variable equal to a pointer value, then attempt to dereference that special variable, you will either get garbage or cause an access error. In the rare case where maxheap is set very large (greater than ~70Mb) and your program uses shared EMS segments (from memallc(2)), the debugger may confuse pointers into the EMS segments with large addresses in the heap. Addresses of unknown (non-debuggable) procedures are shown as call-type pointers, not data pointers. They can be distinguished because the high bit is set (e.g., the decimal value looks negative). Pointers of this form are not usable for anything; you can't dereference them nor set breakpoints based on them. SYMBOL TABLE DEPENDENCIES Series 200 and Series 500 compilers use the HP9000 Symbol Table Format. HP9000 Symbol Table Format: Procedures in FORTRAN and Pascal may have alias names in addition to normal names. Aliases are shown by the "l p" (list procedures) command. They can be used in place of the normal name, as desired. The procedure name "_MAIN_" is used as the alias name for the main program (main procedure) in all supported languages. Do not use it for any debuggable procedures. FORTRAN ENTRY points are flagged "ENTRY" by the "l p" command. When a compiler does not know array dimensions, such as for some C and FORTRAN array parameters, it uses 0:MAXINT or 1:MAXINT, as appropriate. The "/t" format shows such cases with "[]" (no bounds specified), and subscripts from 0 (or 1) to MAXINT are allowed in expressions. Even though the symbol table supports C structure, union, and enumeration tags, C typedefs, and Pascal types, the debugger does not know how to search for them, even for the "/t" format. They are "invisible". Some variables are indirect, so a child process must exist in order for the debugger to know their addresses. When there is no child process, the address of any such variable is shown as 0xfffffffe. The optional pattern given with the "l g" (list globals) command must be an exact match, not just a leading pattern. The string cache (see the -S option) defaults to 1Kbyte in size. This cache holds data read from the Value Table. Symbol names in the Value Table are never preceded by underscores, so the debugger never bothers to search for names of that form. The only time a prefixed underscore is expected is when searching the Linker Symbol Table for names of non-debuggable procedures. FILES a.out Default objectfile to debug. core Default corefile to debug. /usr/lib/cdb.help Text file listed by the "help" command. /usr/lib/cdb.errors Text file which explains debugger error and warning messages. /usr/lib/end.o Object file to link with all debuggable programs. SEE ALSO cc(1), echo(1), ld(1), more(1), creat(2), exec(2), fork(2), open(2), printf(3), system(3), a.out(5), and the cdb Debugger tutorial in HP-UX Concepts and Tutorials. On some systems any of the following may exist: adb(1), fc(1), pc(1), ptrace(2), core(5), symtab(5), user(5). DIAGNOSTICS Most errors cause a reasonably accurate message to be given. Normal debugger exits return zero and error exits return one. All debugger output goes to standard output except error messages given just before non-zero exits, which go to standard error. Debugger errors are preceded by "panic: ", while user errors are not. If any error occurs during initialization, the debugger then prints "cannot continue" and quits. If any error happens after initialization, the debugger attempts to reset itself to an idle state, waiting for command input. If any error occurs while executing a procedure call from the command line, the context is reset to that of the normal program. Child process (program) errors result in signals which are communicated to the debugger via the ptrace(2) mechanism. If a program error occurs while executing a procedure call from the command line, it is handled like any other error (i.e. you can investigate the called procedure). To recover from this, or to abort a procedure call from the command line, type DEL, BREAK, ^C, or whatever your interrupt character is. For more information, see the text file /usr/lib/cdb.errors. WARNINGS Code that is not debuggable or does not have a corresponding source file is dealt with in a half-hearted manner. The debugger shows "unknown" for unknown file and procedure names, cannot show code locations or interpret parameter lists, etc. However, the linker symbol table provides procedure names for most procedures, even if not debuggable. The main procedure (main program) must be debuggable and have a corresponding source file. If the address given to a "ba" command is a not a code address in the child process, strange results or errors may ensue. If you set the address printing format to something printf(3) doesn't like, you may get an error (usually memory fault) each time you try to print an address, until you fix the format with another "f" command. Do not use the "z" command to manipulate the SIGTRAP signal. If you change its state you had better know what you are doing or be a very good sport! If you single step or run with assertions through a call to longjmp(3), the child process will probably take off free- running as the debugger sets but never hits an up-level breakpoint. Do not modify any file while the debugger has it open. If you do, the debugger gets confused and may display garbage. Although the debugger tries to do things reasonably, it is possible to confuse the recording mechanism. Be careful about trying to playback from a file currently open for recording, or vice versa; strange things can happen. Many compilers only issue source line symbols at the end of each logical statement or physical line, whichever is greater. This means that, if you are in the habit of saying "a = 0; b = 1;" on one line, there is no way to put a breakpoint after the assignment to "a" but before the assignment to "b". Some statements do not emit code where you would expect it. For example, assume: 99: for (i = 0; i < 9; i++) { 100: xyz (i); 101: } A breakpoint placed on line 99 will be hit only once in some cases. The code for incrementing is placed at line 101. Each compiler is a little different; you must get used to what your particular compiler does. A good way of finding out is to use single stepping to see in what order the source lines are executed. The output of some program generators, such as yacc(1), have compiler line number directives in them that can confuse the debugger. It expects source line entries in the symbol table to appear in sorted order. Removal of line directives fixes the problem, but makes it more difficult to find error locations in the original source file. The following script, run after yacc(1) and before cc(1), comments out line number changes in C programs: sed "/# *line/s/^.*$/\/*&*\//" y.tab.c >temp.c yacc(1) will leave out line directives if invoked with the -l option. In general, line number directives (or compiler options) are only safe so long as they never set the number backwards. BUGS The C operators "++", "--", and "?:" are not available. The debugger always understands all the other C operators, except "sizeof", if the default language is FORTRAN or Pascal. For FORTRAN, only the additional operators ".NE.", ".EQ.", ".LT.", ".LE.", ".GT.", and ".GE." are supported. For Pascal, only the operators ":=", "<>", "^", "^." (as in "x^.y"), "and", "or", "not", "div", "mod", "addr", and "sizeof" are added. There is no support for FORTRAN complex variables, except as a series of two separate floats or doubles. The debugger doesn't understand C type casts. The C operators "&&" and "||" aren't short circuit evaluated as in the compiler. All parts of expressions involving them are evaluated, with any side-effects, even if it's not necessary. The debugger doesn't understand C pointer arithmetic. "*(a+n)" is not the same as "a[n]" unless "a" has an element size of 1. There is no support for C local variables declared in nested blocks, nor for any local overriding a parameter with the same name. When looking up a local by name, parameters come first, then locals in the order of the "}"s of the blocks in which they are declared. When listing all locals, they are shown in the same order. When there is a name overlap, the address or data shown is that of the first variable with that name. CDB does not support identically-named procedures (legal in Pascal if the procedures are in different scopes). CDB will always use the first procedure with the given name. Pascal WITH statements are not understood. To access any variable you must specify the complete "path" to it. The debugger supports call-by-reference only for known parameters of known (debuggable) procedures. If the object to pass lives in the child process, you can fake such a call by passing "& object", i.e. the address of the object. Array parameters are always passed to command-line procedure calls by address. This is correct except for Pascal call- by-value parameters. Structure parameters are passed by address or value, as appropriate, but only a maximum of eight bytes is passed, which can totally confuse the called procedure. Series 500 FORTRAN string markers are never passed correctly. Only the first number of a complex pair is passed as a parameter. Functions which return complex numbers are are not called correctly; insufficient stack space is allocated for the return area, which can lead to overwriting the parameter values. Assignments into objects greater than four bytes in size, from debugger special variables, result in errors or invalid results. Command lines longer than 1024 bytes are broken into pieces of that size. This may be relevant if you run the debugger with playback or with input redirected from a file.