Annotation of 43BSDReno/share/doc/ps1/11.dbx/dbx.ms, revision 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.