On Trouble-Shooting

I sit on a few channels in IRC which deal primarily (or a lot) with giving help to people with all kinds of technologies. I have also read various technical mailing lists (linux-newbies, comp.lang.perl.misc, python-list and others) for a while. While helping people through problems, I noticed people often do not take steps which would optimize the resources of the people helping.

While ESR's Asking Smart Questions<sup>1</sup> has many useful suggestions, one of the things missing from it is how to generate those smart questions. For the most part, it is not needed -- most suggestions are common sense. But when getting to how you should ask for help when getting stuck on debugging, the HOWTO is silent. I want to publish my advice here for two reasons.

One reason is that many people who are new to free software read this site, and it would help me, personally, if they took these things to heart before asking questions on various forums. The other reason is that I would like to solicit feedback from most experienced developers on this issue.

[1] Note that ESR and the maintainers of the HOWTO are not affiliated with this paper, and will not answer questions about it. (This comment is requested from all linkers to the HOWTO).

If you have been programming for more than one minute, you know that
most programming time is debugging -- trying to understand which
mistake in the program is responsible for the symptoms of
unintentional behaviour your program exhibits (i.e., bugs). The
problem is often made harder by using languages you are not
experienced with or, more commonly, using libraries with which you are
not experienced. In those cases, especially, it is important to know
if the bug is in your program or in the underlying platform.

Your program is probably intended to solve some interesting problem.
Thus, it is complicated with a lot of so-called business logic -- code
related to the problem itself. This code will make it harder to find
and diagnose problem related to the platform. Therefore, when
attempting to understand such problems, and especially when asking for
help on various internet forums like mailing lists or chat rooms, you
will need to reduce your problem to a minimal example.

This will help everyone. On one hand, you may find out it is not the
platform that had a problem at all, but some oversight of yours. On
the other hand, if it is a problem with the platform, or a
misunderstanding of yours, it will be easier to discuss over a
concrete example. Fortunately, getting such examples, while sometimes
time consuming, is not hard. Not hard, that is, as long as you are
willing to forget everything you were ever taught.

The key words here are minimal, self-contained and non-working
example.

You should go over those in reverse order. Hopefully, your example
already does not work, so you should be ok with the last requirement.
However, if you properly architected your code, it will not be
self-contained. It will call out to external methods, read
configuration files and so on. Now is the time to forget everything
you learned about proper software engineering. Put all relevant code
in one file. Instead of reading configuration files or the
environment, hardcode constants. If your program is reading a data from
a file, see if you can put the data as a static string inside your code.
Hopefully, you should arrive at one big file which exhibits the same
problem when it runs as standalone. If that fails, for example because
reading the file is exactly the problem you are having, generate an
archive with all relevant files -- and even then, try to make sure to
do it only when absolutely necessary.

Now, you have a big file exhibiting the problem. Your next order of
business is minimizing it. Here, too, hardcoding constants, replacing
calls to functions by their results when appropriate and similar
techniques can serve to reduce size. Instead of defining a function,
see if you can inline it. If you can delete lines which give otherwise
useful result but are not related to the problem, do so. However, make
sure that all those changes result in a file that exhibits the same
problem. This is hard work, and might take a while. Be sure to keep
revisions of the file, since a one-line change here may change the
exhibited problem. Repeat that until each line is absolutely necessary
to exhibit the same problem. Outside of things like imports and
includes, your program should be extremely short -- less than five
lines is the norm, and often one line or two is possible.

Usually, in the course of working on the minimization, you will see
what the problem is. If not, you will at least have something short to
show on whichever help forum you chooose -- or you will have few
enough suspect operations that you can carefully read their
documentation and, if relevant, even their implementation.

Another thing to consider is TDD (test-driven development). The xprogramming.com web site has links to downloads and Beck's early paper on the subject. A good reference is Beck's book, "Test-Driven Development: By Example" (ISBN: 0-321-14653-0).

Another thing to consider is TDD (test-driven development) for automated unit testing. The xprogramming.com web site has links to downloads and Beck's early paper on the subject. A good reference is Beck's book, "Test-Driven Development: By Example" (ISBN: 0-321-14653-0). The testability of a system reflects the architecture and implementation.

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser
code is live. It needs further work but already handles most
markup better than the original parser.