Annotation of 43BSDReno/share/doc/ps1/11.dbx/dbx.ms, revision 1.1.1.1

1.1       root        1: .\"    @(#)dbx.ms      6.4 (Berkeley) 5/10/86
                      2: .\"
                      3: .\" modified by mark seiden in cosmetic ways.
                      4: .\" examples VAXinated by Kevin Dunlap
                      5: .\" dtbl | ditroff -ms
                      6: .OH 'Debugging with dbx''PS1:11-%'
                      7: .EH 'PS1:11-%''Debugging with dbx'
                      8: .de BE
                      9: .DS
                     10: .ft CW
                     11: .ps -1
                     12: ..
                     13: .de EE
                     14: .ft P
                     15: .ps +1
                     16: .DE
                     17: ..
                     18: .de UL
                     19: \f(CW\s-1\\$1\fP\s0
                     20: ..
                     21: .TL
                     22: Debugging with dbx
                     23: .AU
                     24: Bill Tuthill
                     25: .AI
                     26: Sun Microsystems, Inc.
                     27: 2550 Garcia Avenue
                     28: .AU
                     29: Kevin J. Dunlap
                     30: .AI
                     31: Computer Systems Research Group
                     32: University of California
                     33: Berkeley, CA 94720
                     34: .SH
                     35: Introduction
                     36: .PP
                     37: This short paper discusses
                     38: .I dbx ,
                     39: a symbolic debugger that is vastly superior to
                     40: .I adb .
                     41: It may be as good as the debuggers you remember from those
                     42: non-
                     43: .UX 
                     44: systems you worked on before.
                     45: The advantage of symbolic debuggers is that they allow you
                     46: to work with the same names (symbols) as in your source code.
                     47: .PP
                     48: Like
                     49: .I adb ,
                     50: .I dbx
                     51: is interactive and line-oriented, but
                     52: .I dbx
                     53: is a source-level rather than an assembly-level debugger.
                     54: It allows you to determine where a program crashed,
                     55: to view the values of variables and expressions,
                     56: to set breakpoints in the code, and to run and trace a program.
                     57: Source code may be in C, Fortran, or Pascal.
                     58: .PP
                     59: Mark Linton wrote
                     60: .I dbx
                     61: as his master's thesis at UC Berkeley.
                     62: Along with Eric Schmidt's Berknet,
                     63: .I dbx
                     64: is among the most successful master's theses done on UNIX.  Since
                     65: .I dbx
                     66: required changes to the symbol tables
                     67: generated by the various compilers,
                     68: you need to compile programs for debugging with the
                     69: .I \-g
                     70: flag.  For example,
                     71: C programs should be compiled as follows:
                     72: .DS
                     73: % cc \-g \fIprogram\fP.c \-o \fIprogram\fP
                     74: .DE
                     75: Programs compiled with the
                     76: .I \-g
                     77: option have good symbol tables,
                     78: while programs compiled without
                     79: .I \-g
                     80: have old-style symbol tables intended for
                     81: .I adb .
                     82: Stripped programs have no symbol tables at all.
                     83: Invoke the debugger as follows, where
                     84: .I program
                     85: is the pathname of the executable file that dumped core:
                     86: .DS
                     87: % dbx \fIprogram\fP
                     88: .DE
                     89: The core image should be in the working directory;
                     90: if it isn't, specify its pathname in the argument after the program name.
                     91: Among the great advances of
                     92: .I dbx
                     93: is that it has a help facility; type the
                     94: .I help
                     95: request to see a list of possible requests.
                     96: You can obtain help on any
                     97: .I dbx
                     98: request by giving its name as an argument to
                     99: .I help .
                    100: .bp
                    101: .SH
                    102: Examining Core Dumps
                    103: .PP
                    104: Much of the time, programmers use
                    105: .I dbx
                    106: to find out why a program dumped core.
                    107: As an example, consider the following program
                    108: .I dumpcore.c ,
                    109: which dereferences a NULL pointer.
                    110: This is a legal operation on VAX/UNIX,
                    111: but not on VAX/VMS or on MC68000-based UNIX systems, on one of
                    112: which this example was run:
                    113: .BE
                    114: #include <stdio.h> 
                    115: .sp.5
                    116: #define LIMIT 5
                    117: .sp.5
                    118: main()                 /* print messages and die */
                    119: {
                    120:        int i;
                    121: .sp.5
                    122:        for (i = 1; i <= 10 ; i++) {
                    123:                printf("Goodbye world! (%d)\en", i);
                    124:                dumpcore(i);
                    125:        }
                    126:        exit(0);
                    127: }
                    128: .sp.5
                    129: int *ip;
                    130: .sp.5
                    131: dumpcore(lim)          /* dereference NULL pointer */
                    132: int lim;
                    133: {
                    134:        if (lim >= LIMIT)
                    135:                *ip = lim;
                    136: } 
                    137: .EE
                    138: The program core dumps because of a
                    139: segmentation violation or memory fault \(em
                    140: on most machines it is illegal to assign to address zero.
                    141: Once the program has produced a core dump,
                    142: here's how you can find out why the program died:
                    143: .DS
                    144: %\c
                    145: .UL " dbx dumpcore"
                    146: dbx version 3.17 of 4/24/86 15:04 (monet.Berkeley.EDU).
                    147: Type 'help' for help.
                    148: reading symbolic information ...
                    149: [using memory image in core]
                    150: (dbx)\c
                    151: .UL " where"
                    152: dumpcore.dumpcore(lim = 5), line 22 in "dumpcore.c"
                    153: main(0x1, 0x7fffe904, 0x7fffe90c), line 11 in "dumpcore.c"
                    154: .DE
                    155: The
                    156: .I where
                    157: request yields a stack trace.
                    158: As you can see, the
                    159: .I dumpcore()
                    160: routine was called from line 11 of the program, with the argument
                    161: .I lim
                    162: equal to 5.
                    163: You can look at the
                    164: .I dumpcore()
                    165: procedure by invoking the
                    166: .I list
                    167: request as follows:
                    168: .DS
                    169: (dbx)\c
                    170: .UL " list dumpcore"
                    171:    18   dumpcore(lim)           /* dereference NULL pointer */
                    172:    19   int lim;
                    173:    20   {
                    174:    21           if (lim >= LIMIT)
                    175:    22                   *ip = lim;
                    176:    23   }
                    177: .DE
                    178: We immediately suspect that the program's failure had something to do with
                    179: .I *ip ,
                    180: so we use the
                    181: .I print
                    182: request to retrieve the value of the pointer and what it points to:
                    183: .DS
                    184: (dbx)\c
                    185: .UL " print *ip"
                    186: reference through nil pointer
                    187: (dbx)\c
                    188: .UL " print ip"
                    189: (nil)
                    190: .DE
                    191: This tells us the program has dereferenced a null pointer.
                    192: It is possible to run the program again from inside the debugger.
                    193: The first line tells you name of the running program,
                    194: and successive lines give output from the program:
                    195: .DS
                    196: (dbx)\c
                    197: .UL " run"
                    198: Goodbye world! (1)
                    199: Goodbye world! (2)
                    200: Goodbye world! (3)
                    201: Goodbye world! (4)
                    202: Goodbye world! (5)
                    203: .sp.5
                    204: Bus error in dumpcore.dumpcore at line 22
                    205:    22          *ip = lim;
                    206: (dbx)\c
                    207: .UL " quit"
                    208: .DE
                    209: In this example the program dies with a Bus error at line 22. 
                    210: This method of running the program
                    211: does not produce a core dump, but the
                    212: .I where
                    213: request will still behave properly,
                    214: because the debugger is in the same state
                    215: as if it had just read the core file.
                    216: .SH
                    217: Setting Breakpoints
                    218: .PP
                    219: With
                    220: .I dbx
                    221: you can set breakpoints before each line of a program,
                    222: not just at function and procedure boundaries, as with
                    223: .I adb .
                    224: The
                    225: .I stop
                    226: request sets a breakpoint.
                    227: After setting a breakpoint, use the
                    228: .I run
                    229: request to execute the program.  The
                    230: .I cont
                    231: request continues execution from the current stopping point
                    232: until the program finishes or another breakpoint is encountered.  The
                    233: .I step
                    234: request executes one source statement,
                    235: following any function calls.  The
                    236: .I next
                    237: request executes one source statement,
                    238: but does not stop inside any function calls.  The
                    239: .I status
                    240: request lists active breakpoints, while the
                    241: .I delete
                    242: request removes them if required.
                    243: .PP
                    244: The
                    245: .I stop
                    246: request can take a conditional expression
                    247: to avoid needless single-stepping.
                    248: We will use a conditional in our example to make things simpler.
                    249: Of course you can use
                    250: .I print
                    251: and
                    252: .I list
                    253: requests at any time during statement stepping
                    254: if you want to print the value of variables
                    255: or list lines of source code.
                    256: This sample session shows a mixture of requests
                    257: as we verify that the program fails when it tries to assign to
                    258: .I *ip :
                    259: .DS
                    260: (dbx)\c
                    261: .UL " stop at 10 if (i == 5)"
                    262: [1] if i = 5 { stop } at 10
                    263: (dbx)\c
                    264: .UL " run"
                    265: Goodbye world! (1)
                    266: Goodbye world! (2)
                    267: Goodbye world! (3)
                    268: Goodbye world! (4)
                    269: [1] stopped in main at line 10
                    270:    10                   printf("Goodbye world! (%d)\en", i);
                    271: (dbx)\c
                    272: .UL " next"
                    273: Goodbye world! (5)
                    274: stopped in main at line 11
                    275:    11                   dumpcore(i);
                    276: (dbx)\c
                    277: .UL " step"
                    278: stopped in dumpcore at line 21
                    279:    21           if (lim >= LIMIT)
                    280: (dbx)\c
                    281: .UL " step"
                    282: stopped in dumpcore at line 22
                    283:    22                   *ip = lim;
                    284: (dbx)\c
                    285: .UL " step"
                    286: Bus error in dumpcore.dumpcore at line 22
                    287:    22          *ip = lim;
                    288: .DE
                    289: Running the program with breakpoints assures us
                    290: that our intuition was correct.
                    291: We shouldn't be assigning anything to a null pointer \(em
                    292: .I ip
                    293: should have been initialized to point at an object of the proper type.
                    294: To exit from the debugger, use the
                    295: .I quit
                    296: request.
                    297: .PP
                    298: It is possible to set variables from inside
                    299: .I dbx .
                    300: The previous breakpoint session, for example,
                    301: could have gone like this:
                    302: .DS
                    303: %\c
                    304: .UL " dbx dumpcore"
                    305: dbx version 3.17 of 4/24/86 15:04 (monet.Berkeley.EDU).
                    306: Type 'help' for help.
                    307: reading symbolic information ...
                    308: [using memory image in core]
                    309: (dbx)\c
                    310: .UL " stop at 10"
                    311: [1] stop at 10
                    312: (dbx)\c
                    313: .UL " run"
                    314: Running: dumpcore 
                    315: stopped in main at line 10
                    316:    10                   printf("Goodbye world! (%d)\en", i);
                    317: (dbx)\c
                    318: .UL " assign i = 5"
                    319: (dbx)\c
                    320: .UL " next"
                    321: Goodbye world! (5)
                    322: stopped in main at line 11
                    323:    11                   dumpcore(i);
                    324: (dbx)\c
                    325: .UL " next"
                    326: Bus error in dumpcore.dumpcore at line 22
                    327:    22          *ip = lim;
                    328: .DE
                    329: It is often useful to assign new values to variables
                    330: to draw conclusions about alternative conditions.
                    331: We can't fix the bug in this program, however,
                    332: because there is no declared variable to which
                    333: .I ip
                    334: should point.
                    335: .SH
                    336: Conclusion
                    337: .PP
                    338: Expressions in
                    339: .I dbx
                    340: are similar to those in C,
                    341: except that there is a distinction between
                    342: .I /
                    343: (floating-point division) and
                    344: .I div
                    345: (integer division), as in Pascal.
                    346: The table on the following page shows
                    347: .I dbx
                    348: requests organized by function:
                    349: .PP
                    350: Like
                    351: .I adb ,
                    352: .I dbx
                    353: can disassemble object code.
                    354: It can also examine object files
                    355: and print output in various formats; but
                    356: .I dbx
                    357: requires the proper symbol tables, so
                    358: .I adb
                    359: is more useful to examine arbitrary binary files.
                    360: The most important thing
                    361: .I adb
                    362: can do that
                    363: .I dbx
                    364: cannot is to patch binary files \(em
                    365: .I dbx
                    366: has no write option.
                    367: Despite these shortcomings,
                    368: .I dbx
                    369: is much easier to use than
                    370: .I adb ,
                    371: so it contributes much more to individual programmer productivity.
                    372: .SH
                    373: Acknowledgements
                    374: .PP
                    375: Material presented in this document was first presented in
                    376: ``C Advisor'', \fIUnix Review 4\fP, 1, pp 78\-85.
                    377: The Regents of the University California expresses their
                    378: gratitude to Unix Review
                    379: for allowing them to reprint this document.
                    380: .PP
                    381: This document is a good starting point for a more thorough tutorial.
                    382: Those with the ambition to expand on this document are encouraged
                    383: to contact the Computer Systems Research Group at ``[email protected].''
                    384: .KF
                    385: .TS
                    386: center box;
                    387: cf s.
                    388: .sp.2
                    389: \s+2Groups of \&\fIdbx\fP Requests\s-2
                    390: .sp.2
                    391: _
                    392: .T&
                    393: l lfI
                    394: lp-1fCW l.
                    395:        execution and tracing
                    396: _
                    397: run    execute object file
                    398: cont   continue execution from where it stopped
                    399: trace  display tracing information at specified place
                    400: stop   stop execution at specified place
                    401: status display active \&\fItrace\fP and \&\fIstop\fP requests
                    402: delete delete specific \&\fItrace\fP or \&\fIstop\fP requests
                    403: catch  start trapping specified signals
                    404: ignore stop trapping specified signals
                    405: step   execute the next source line, stepping into functions
                    406: next   execute the next source line, even if it's a function
                    407: .T&
                    408: l lfI
                    409: lp-1fCW l.
                    410: _
                    411:        displaying data
                    412: _
                    413: print  print the value of an expression
                    414: whatis print the declaration of a given identifier or type
                    415: which  print outer block associated with identifier
                    416: whereis        print all symbols matching identifier
                    417: assign set the value of a variable
                    418: .T&
                    419: l lfI
                    420: lp-1fCW l.
                    421: _
                    422:        function and procedure handling
                    423: _
                    424: where  display active procedures and functions on stack
                    425: down   move down the stack towards stopping point
                    426: up     move up the stack towards \&\fImain\fP
                    427: call   call the named function or procedure
                    428: dump   display names and values of all local variables
                    429: .T&
                    430: l lfI
                    431: lp-1fCW l.
                    432: _
                    433:        accessing source files and directories
                    434: _
                    435: edit   invoke an editor on current source file
                    436: file   change current source file
                    437: func   change the current function or procedure
                    438: list   display lines of source code
                    439: use    set directory list to search for source files
                    440: /.../  search down in file to match regular expression
                    441: ?...?  search up in file to match regular expression
                    442: .T&
                    443: l lfI
                    444: lp-1fCW l.
                    445: _
                    446:        miscellaneous commands
                    447: _
                    448: sh     pass command line to the shell
                    449: alias  change \&\fIdbx\fP command name
                    450: help   explain commands
                    451: source read commands from external file
                    452: quit   exit the debugger
                    453: .TE
                    454: .KE
                    455: .bp

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.