------------------------------- Page    i -------------------------------

                             A Dcon Tutorial

------------------------------- Page   ii -------------------------------

                            TABLE OF CONTENTS


1.    Introduction  . . . . . . . . . . . . . . . . . . . . . . . . .   1

2.    Getting Started . . . . . . . . . . . . . . . . . . . . . . . .   1

3.    Running a program . . . . . . . . . . . . . . . . . . . . . . .   1

4.    Program termination . . . . . . . . . . . . . . . . . . . . . .   2

5.    Examining memory  . . . . . . . . . . . . . . . . . . . . . . .   2

6.    Break points  . . . . . . . . . . . . . . . . . . . . . . . . .   4

7.    Where to go from here . . . . . . . . . . . . . . . . . . . . .   6

8.    References  . . . . . . . . . . . . . . . . . . . . . . . . . .   6


                                                            Last Page   6

-------------------------------- Page  1 --------------------------------

1.    INTRODUCTION

Dcon is the UTS debugger, that is,  a program helpful in debugging  other
programs under the UTS operating system.  This tutorial explains how dcon
can be helpful in debugging.  Although it is  not directly tied to the  C
programming language, some dcon features can only be used when  debugging
a C (or "object compatible"*) program.  We assume that the reader is fam-
iliar with UTS and C.

This tutorial  is not  meant to  be a  complete reference  for dcon,  see
dcon(1) if that is desired.




2.    GETTING STARTED

Dcon is a machine-level debugger in the sense that it works on executable
object files produced  from compilation.   We'll assume a.out  is such  a
file.  To debug a.out, we type

        dcon a.out


Now the debugger is waiting for a command.




3.    RUNNING A PROGRAM

The simplest thing to do is start a.out executing by typing

        ;go


This is similar to typing a.out to the shell, but now dcon is in control.
As with the shell, arguments can be passed to a.out by typing

        ;go arg1 arg2 ...


Unfortunately, dcon does not understand special characters, so
_______________
  *"Object compatible" means in a.out(3)  format and using the same  cal-
  ling sequence as C.

-------------------------------- Page  2 --------------------------------

        ;go arg1 arg2 ... > outfile


does not redirect the output.   The ;go command causes  dcon to create  a
process that begins executing a.out.  While running, a.out can read  from
or write to the user's terminal.




4.    PROGRAM TERMINATION

There are two ways a.out can stop executing:  by terminating normally, or
by receiving a signal from UTS.  When a process terminates normally, dcon
displays

        process terminated, returns NNN


where NNN is the return code from  the process.  The argument to  exit(2)
determines the process' return code.  At this point, dcon is  waiting for
a command just as before the ;go command was given.

When a process receives a signal, it is for one of 2 reasons: the process
encountered a non-recoverable error  (e.g. tried to access a  nonexistent
memory location) or was interrupted by the user (e.g. hitting a PA1 on  a
3270 terminal).   Dcon  displays the  signal  name and  the  location  it
occurred at, such as

        Page translation exception at location peek+148


With the process stopped, dcon can examine the program state and contents
of variables.




5.    EXAMINING MEMORY

When the process stops, it is usually desirable to know what routines are
active and what their arguments  are.  This information can be  displayed
by typing

        ?

-------------------------------- Page  3 --------------------------------

For example, the following might be produced:

        stack trace:
                peek(35)
                yyparse()
                main(2, FFFFEE)

Note the routines are listed from most recently called to the first  rou-
tine called, and that the  arguments are by default displayed in  hexade-
cimal.  This "stack trace"  can be useful  to detect that  a routine  has
been called  with either  an obviously  incorrect argument  or the  wrong
number of arguments.

It is also useful to be able to look at the contents of variables in  the
program.  For example, suppose our a.out had been compiled from  a C pro-
gram containing the declaration

        int fildes;


To print the value of fildes in decimal, we type

        fildes/d


The / separates what's to be printed from how it's to be printed.  To the
left can  be any  expression  consisting of  names, numbers,  the  binary
operators +,  -, *,  and //  (division),  and the  unary operator  *  for
indirection.  The value of the  expression is the address whose  contents
are to be printed.  To the right is an optional length specifier followed
by an optional mode specifier.  Lengths are specified as follows:

          b     for byte
          h     for half-word
          w     for word
          l     for double-word


Modes are specified by:

          d     for decimal
          o     for octal
          x     for hexadecimal
          c     for a character
          s     for a string of characters (not a pointer)

If no length or mode  is specified the previous  one is used.   Initially
the length is w and the mode x.  If neither the length nor mode is speci-
fied then the / becomes  optional.  If nothing  is specified (input  con-
sists of only a newline) then the "next" address (defined  as the current

-------------------------------- Page  4 --------------------------------

address plus the last specified length)  is displayed.  No length may  be
specified for the s mode.

As further example, suppose our C program contained the declaration

        char *p;


To print the value of p we'd probably type

        p/x


because it's a pointer.   If we wanted  to look at  the character that  p
points at, we type

        *p/bc


In this case the bc is more than we have  to say since the c implies  the
b.  If we want to look at the next character, we type

        *(p+1)


We don't need to specify any print information since we want to print  it
the same way it was previously printed.




6.    BREAK POINTS

Frequently the actual cause of a  problem occurs well before the  program
receives a signal, so  dcon allows the user  to stop the program when  it
reaches a certain place, examine memory as above, and continue execution.
The places where the  user wishes to  stop the program are called  "break
points".  To set a break point, we type

        ;bp <location>


prior to starting execution with the  ;go command.  When the location  is
reached dcon displays

        Break point at location <location>

Unfortunately, it  is  not  currently  possible  to  set  a  break  point

-------------------------------- Page  5 --------------------------------

corresponding to a line from the program source.  Furthermore, setting  a
break point at the address of a routine does not do what is desired since
space for local variables has not been allocated at the very beginning of
a routine.  To the rescue there is  a built-in function enter, which  has
as value the address where its argument (a routine name) "really" begins.
So it is common to type

        ;bp enter(routine)


To distinguish this function from  user symbols, dcon  requires the (  to
immediately follow enter  (i.e. no  space in between).   There is also  a
built-in function exit,  with the  same syntax,  which has  as value  the
address where its argument "really" ends.

After displaying information or setting more break points we can continue
the process by typing

        ;cont


Execution will continue until another break point is reached or the  pro-
cess otherwise stops.  There  is no limit  to the number of break  points
that can be set at one  time and once a break  point is set it stays  set
until explicitly unset.

The two commands ;brks  and ;clr help  keep track of  break points.   The
;brks command displays all currently  set break points while ;clr  <loca-
tion> unsets the break point  at <location>.  If  given no argument  ;clr
unsets all break points.

Sometimes it is cumbersome  to keep typing  ;cont to get  to the  desired
instance of a break point, so there are a few  more features that come in
handy.  These are:

 1.  When setting  a break  point, a  compound command  may be  specified
     which is to be executed  when the break point is actual reached.   A
     compound command is  a list  of one  or more  commands separated  by
     semicolons and enclosed in braces.   A compound command may also  be
     used wherever a command may.

 2.  The request

        ;if (expression) command


     evaluates expression and then executes command if the value is logi-
     cally true (or non-zero).  The  operators <, >, <=, >=, ==, ~=  (not
     equal), and ~ (logical not) are allowed in the expression along with
     +, -, *, //, and unary *.  The parentheses are required.

-------------------------------- Page  6 --------------------------------

Now if we want a.out to stop only if the variable blah is greater than 10
upon entry to the routine push, we type

        ;bp enter(push) { ;if (blah <= 10) ;cont }
        ;go

If we want  to print  the value  of blah  in decimal  when entering  push
without stopping, we could say

        ;bp enter(push) { blah/d; ;cont }


If we want to change the value of blah after a break point is reached, we
use = assignment as in

        blah = 3 ;cont

Now the program will continue execution with the value of blah being 3.




7.    WHERE TO GO FROM HERE

We've covered  the basics,  there  are plenty  more features.   The  best
teacher is experience, and as you learn, rely on the  manual page dcon(1)
which fully (but briefly) describes the capabilities of the debugger.




8.    REFERENCES


[1] UTS Programmer's Manual
