Is printing to console/stdout a good debugging strategy

debugging

Let's say we have a function like this:

public void myStart()
{
    for (int i = 0; i<10; i++) myFunction(i); 
}


private int myFunction(int a)
{

    a = foo(a);
    a = bar(a);
    return a; 
}

private int foo(int a)
{
    //do something here

    //something gnarly here

    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Now for whatever reason, our code isn't working. Perhaps it's throwing an error, perhaps it's returning the wrong value, perhaps it's got stuck in an infinite loop.

The first thing any first year programmer, is print to console/std out, (having learned how to print Hello World before learning to use a debugger).

For example to debug this code they might do the following:

private int myFunction(int a)
{
    print("before foo: a=" + a); 
    a = foo(a);
    print("before bar: a=" + a);
    a = bar(a);

    return a; 
}

private int foo(int a)
{
    //do something here
    print ("foo step1: a=" + a); 

    //something gnarly here
    print ("foo step2: a=" + a + " someOtherValue="+ someOtherValue + " array.length= " + someArray.length()); 
    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Now they run the code, they get a big console print out, which they can go through to trace where things are going wrong.

An alternative of course, is to set breakpoints and step through the code at each point.

One major advantage of printing to console, is that the developer can see the flow of the values in one go, without having to click through steps etc.

But the disadvantage is, your code is then riddled with all these print statements that then need to be removed.

(Is it possible perhaps to tell the debugger to print only certain values out to a log?, the breakpoints can then easily be added or removed without actually modifying the code.)

I do still use console printing as a primary debugging method, I'm wondering how common/effective this is in comparison to something else out there.

Best Answer

Print statements and debugger are not mutually exclusive. They are just different tools available to you in order to locate/identify bugs. There are those who will claim how they never touch a debugger and there are those who do not have a single logging/print statement anywhere in the code that they write. My advice is that you do not want to be in either one of those groups.

Instead learn to use logging and learn to use a debugger. With experience you will (almost without having to think about it) pick the right tool and get the job done accurately and efficiently. Without experience, sometimes you'll pick one over the other, and maybe it'll take you a bit longer poking around at the variables or sifting through log files, but that's all part of the learning process.

So, to answer your specific question. Yes. Using prints to trace execution is good and widely used debugging strategy. However...

Instead of using print statements, consider using a logging framework. Logging frameworks have a concept of logging levels so you can add a whole bunch of log messages but pick a level for each one. When your application is running under normal conditions, your level would be ERROR or WARNING so that only important stuff gets reported. However when you are tracing through the code and need to understand execution flow, you can change the logger to INFO or DEBUG and now all those "print" statements that you already have in the code will report additional info.

Using a logging framework...

  1. you won't need to delete all the prints after you are done.
  2. the prints you leave in the code, can help you or any other developer debug that same code in the future
  3. you'll be able to debug this code in the field without having to rebuild it every time just to add the prints that you deleted.
  4. you'll be able to redirect logging messages anywhere you want, not just a console. They could go to a file, syslog, DB, socket... etc

Update: I just noticed at the end you were asking, "Is it possible perhaps to tell the debugger to print only certain values out to a log". Depending on which debugger you use. Many modern debuggers allow you to define an action to invoke when a breakpoint is hit. In some (I've done this in VS and WinDbg), it is possible to specify "print this and resume". Visual Studio calls them "tracepoints" instead of "breakpoints"

Related Topic