[comp.cog-eng] Debug techniques. What's your favorite?

aarons@syma.sussex.ac.uk (Aaron Sloman) (04/09/89)

u-dmfloy%ug.utah.edu@wasatch.UUCP (Daniel M Floyd)

> Reply-To: u-dmfloy%ug.utah.edu.UUCP@wasatch.UUCP (Daniel M Floyd)
> Organization: University of Utah CS Dept
 writes:
> I am writing a debuger for a Common LISP software package.
    .....
> if I should happen to have extra time, I could build the
> best lisp debugger in the world ... assuming I knew what
> a 'best lisp debugger' was. :-))

> Also, if you have a wish (or wish list) now would be a good time
> for me to hear about that too.

I'll also be interested to see what people think they need: we would
like to improve the debugging aids in our development system too!

The question asked is potentially very deep. Here are just a few
semi-random reflections on the problem.

One way to think about this is to ask what is needed to help less able
programmers perform more like the best ones. This takes us straight into
problems of cognitive science/cognitive engineering, usually ignored
by computer scientists and language designers.

I believe that the ability to track down program bugs and design flaws
(relatively) quickly is one of the things that distinguish the very best
software developers from the mediocre.

How do they do it? If we had good answers to that, we might be able to
begin to design tools to help lesser mortals improve their productivity.

One important characteristic that some people have to a greater extent
than others is the ability to discern when the level of description
given in a bug-report is spurious: it describes conditions and behaviour
that distract from the real problem. Put another way, the expert faced
with a bug knows how to find the right way to describe the bug. This is
important because if you get the description wrong you can get the fix
wrong - and e.g. just cope with a special case of a general problem,
or simultaneously fix your bug and introduce new ones.

The inexpert programmer varies conditions and observes behaviour at a
low level of detail to explore the problem. The expert varies them at a
higher level of abstraction, ruling out larger search spaces at a time.
Eventually the right description is found, and identifying the relevant
portion of the source code is easy.

The fix may or may not be easy. Again, the expert will have access to
knowledge about many ways of altering programs to change their
behaviour, and will be very good at homing in rapidly on the right kind
of change (even if the fixing isn't right first time, it may be in the
right ball-park, requiring only small subsequent alterations to get the
final fix). The less expert programmer will know about fewer ways of
transforming programs and will have less accurate, less general, or less
complete descriptions of what can be achieved by such transformations.

So the main debugging aids required will include tools to help one
narrow down the right description of the bug, and tools to help one
narrow down the right way to change a program (or a design, or
specification) to produce the desired result.

What would such tools be like? It's clear that very sophisticated
pattern recognition and associative memory capapbilities will be
required. But prior to this is needed a good language (or set of
languages) for describing different kinds of bugs, different kinds of
program alterations, and different kinds of effects of such alterations.
What else? I think that's a hard research problem.

In the meantime, a minimum requirement is the ability rapidly to explore
a variety of different inputs to a program and a variety of different
modifications, and to record the results conveniently. In that way we can
collect evidence as to what the problem is.

This rules out systems where every little change requires a very slow
edit -> compile -> link -> run -> edit cycle.

AI languages and development environments typically provide these rapid
exploration abilities, though they vary in the ease with which they
allow switching between editing, running, examining datastructures,
recording and comparing output, turning different kinds of tracing on
and off, changing the tracer to display new kinds of information,
creating new temporary procedures or modifying old ones, to bring out
normally hidden aspects of what a program has done, finding
documentation on the facilities used, etc. etc.

For example if you use a low level language like lisp or Pop-11 to
implement something like prolog or a production system, you should have
tools that make it easy to extend the debugging and tracing tools to
operate at a level that is suitable for the new higher level language.

More generally, user programs will have their own level at which they
need debugging aids: so ideally it should be easy for the user to
implement them.

What kinds of tools make this possible? I'd include macro facilities and
more generally the ability to extend the syntax of the programming
language to meet the requirements of the problem. Similarly the syntax
of the instructions to print out helpful information or interactively
modify behaviour during debugging may need to be tailored to the problem
domain: if you are debugging a music synthesising program you want to be
able to give debugging instructions using a syntax appropriate for
music, not just procedure calls in the implementation language.

Of course, for each such new level of abstraction and each application
domain, designing good debugging aids is itself a hard problem requiring
considerable ingenuity and creativity.

Oh, and there are also the trivial bugs for which it is convenient to be
able to do things like single step through a program, examining
variables and the control flow. Is it possible that providing that sort
of facility stops people thinking about the really hard problems?

Aaron Sloman,
School of Cognitive and Computing Sciences,
Univ of Sussex, Brighton, BN1 9QN, England
    ARPANET : aarons%uk.ac.sussex.cogs@nss.cs.ucl.ac.uk
              aarons%uk.ac.sussex.cogs%nss.cs.ucl.ac.uk@relay.cs.net
    JANET     aarons@cogs.sussex.ac.uk
    BITNET:   aarons%uk.ac.sussex.cogs@uk.ac
        or    aarons%uk.ac.sussex.cogs%ukacrl.bitnet@cunyvm.cuny.edu

    UUCP:     ...mcvax!ukc!cogs!aarons
            or aarons@cogs.uucp

arie@zippy.eecs.umich.edu (Arie Covrigaru) (04/11/89)

I ahve a question about the compiler directives in Allegro CL on a Mac IIx.
I am using version 1.2.2 of Allegro CL, Mac OS version 6.0.3, 4 megabytes
or RAM and an internal 80M HD.

I am compiling a very big file and I want to get some info on the compiler's
progress.  I called the function compile-file with :verbose t but I get
nothing printed in the listener window.  Am I doing something wrong?
Please email me with any advise.

Thanks.

=============================================================================
Arie Covrigaru
Cognitive Science and Machine Intelligence Laboratory, University of Michigan
=============================================================================

csm@violet.berkeley.edu (04/11/89)

There are certain classes of bugs for which fancy debuggers
are terrific.  In C the best example is a segmentation violation.
All you have to do is start up the debugger and there you are,
positioned at the exact offending statement.

However, more other sorts of  bugs, like omitting an '=' to yield
	if ( x = y ) /* Assignment */
instead of
	if ( x == y ) /* Test for equality */
are not found quite so quickly.

I have no data, but I would suspect that given a corpus of
differing bugs, debugging time is directly proportional
to the skill of the programmer with only slight gains to be had
from sophistication of tools.

The most important element of the debugging tool is probably the
amount of time it takes from hypothesis to rerun.

The most important skill is learning how to develop the hypothesis.
(Unless tenacity is considered a skill.)

I have seen programmers (particularly novices) hypnotized by 
single stepping through a program.  Fancy debuggers are 
therfore extraordinarily useful as a pedagogical tool!

	Brad Sherman (bks@ALFA.Berkeley.Edu)

throopw@agarn.dg.com (Wayne A. Throop) (04/25/89)

> (In the header: From: csm@violet.berkeley.edu)
> (In body of article: Brad Sherman (bks@ALFA.Berkeley.Edu))

> There are certain classes of bugs for which fancy debuggers
> are terrific.  [... such as segmentation violation ...]
> However, more other sorts of  bugs, like omitting an '=' to yield
> 	if ( x = y ) /* Assignment */
> [... where a test was intended ...] are not found quite so quickly.

There is a small kernel of truth here, but the situation is not as
"binary" as suggested above.  That is, the model of considering that
there are two categories into which bugs fall, "debuggers useful in
diagnosing", and "debuggers not useful in diagnosing", (and the
majority of bugs in the latter categories) is a poor model.

A better model is that bugs manifest themselves in ways increasingly
separated from their ultimate cause, and the more powerful a debugger,
the more separation from cause to manifestation can be "backtracked"
without resorting to the inclusion of special-purpose traceing or
self-checking code.

For example, take a debugger that can walk back stacks, and position
to stack frames other than the most recent.  It can trace back the
origin of improper arguments, while a debugger lacking this feature
can do it clumsily at best.  Trust me that this is true: I've used
both types of debuggers.

And, to address directly the "if ( x = y )" type of bug, there are
many fancy features that would help ferret this out.  Such as
selective variable value tracing (if the bug manifestation pointed to
x as a trashed variable), or by-source-line stepping (if the bug
manifestation pointed to the failing routine's flow of control), and
so on.  The point here is that the example of accidental assignment is
NOT an example that fits cleanly into the "fancy debuggers are
useless" category.

The more general point is, the "fancier" the debugger, the larger the
class of bugs that become trivial to diagnose.  "Trivial", in this
case, implies a saving in the developer-diagnostician's time.

> I have no data, but I would suspect that given a corpus of
> differing bugs, debugging time is directly proportional
> to the skill of the programmer with only slight gains to be had
> from sophistication of tools.

My personal experience is directly contrary to this assertion, so I
suspect it is incorrect.  In particular, I can find problems many
times as fast using a gdb-class or better debugger than I can using
an sdb-class or worse debugger.  I don't keep formal statistics on
this point, but a measure of bugs-diagnosed-per-day is definitely
improved by better debugging tools.

> The most important element of the debugging tool is probably the
> amount of time it takes from hypothesis to rerun.

That may well be.  And with a sufficiently powerful debugger, this can
be reduced to (about) zero.  For example, debuggers which allow the
insertion of interpreted code into compiled code allow checking of
hypothesis with no compile/link process to slow things down.

> The most important skill is learning how to develop the hypothesis.
> (Unless tenacity is considered a skill.)

Yes, that is the most important *skill*.  But the most impotant *tool*
is one that allows the verification of the hypothesis at least cost.
This is what debuggers are all about, and the "fancier" they are, the
more classes of hypothesis they can verify at low cost.

To directly answer the question in the "subject" line, I don't really
have any one "favorite" debugger technique.  I think that the various
methods of forming the hypothesis of the nature of the bug is the hard
part, and I only vaguely understand how I do this myself.  But even a
genius at this is handicapped if this genius lacks adequate tools to
explore the buggy process to test the hypotheses as they are thought
of.

--
And you may find yourself in a beautiful house, with a beautiful wife
And you may ask yourself -- Well ... how did I get here?
                    --- "Once in a Lifetime" by Talking Heads
--
Wayne Throop      <the-known-world>!mcnc!rti!xyzzy!throopw

rang@cpsin3.cps.msu.edu (Anton Rang) (04/25/89)

In article <5338@xyzzy.UUCP> throopw@agarn.dg.com (Wayne A. Throop) writes:

   > (In the header: From: csm@violet.berkeley.edu)
   > (In body of article: Brad Sherman (bks@ALFA.Berkeley.Edu))

   > There are certain classes of bugs for which fancy debuggers
   > are terrific.  [... such as segmentation violation ...]
   > However, more other sorts of  bugs, like omitting an '=' to yield
   > 	if ( x = y ) /* Assignment */
   > [... where a test was intended ...] are not found quite so quickly.

Part of the problem here is the overloading of "assignment statement"
with "expression" in C, in my opinion.  The language should catch
this.  But on to the debugging discussion....

   A better model is that bugs manifest themselves in ways increasingly
   separated from their ultimate cause, and the more powerful a debugger,
   the more separation from cause to manifestation can be "backtracked"
   without resorting to the inclusion of special-purpose traceing or
   self-checking code.

Nice model.  I'd add that debuggers which can execute "larger"
commands also seem more powerful to me.  For instance, being able to
evaluate a complex expression involving records, pointers, etc. is
invaluable for saving time over a debugger which can only print
variable values.

   > I have no data, but I would suspect that given a corpus of
   > differing bugs, debugging time is directly proportional
   > to the skill of the programmer with only slight gains to be had
   > from sophistication of tools.

   My personal experience is directly contrary to this assertion, so I
   suspect it is incorrect. [...]

I'd say it's closer to half and half; if I'm working with MacsBug,
bugs take me quite a lot longer to find than with, say, VAX DEBUG.
But in both cases I'm faster than some others would be (or than I
would have been 5 years ago).

+---------------------------+------------------------+---------------------+
| Anton Rang (grad student) | "VMS Forever!"         | rec.music.newage is |
| Michigan State University | rang@cpswh.cps.msu.edu | under discussion... |
+---------------------------+------------------------+---------------------+