Ad-hoc instrumented "printf" debugging involves:

  • Editing the application's source code to log application state at appropriate points, either through print statements, or a logging framework
  • Compiling and running the application
  • Viewing the debugging statements emitted by the application at runtime (e.g. "The value of X is now 14" or "compute(): given a null argument!")

Debugging by print statements is crude, but fast and easy. One downside is that the addition of print statements inherently alters program flow, which may or may not be significant. Additionally, an individual print statement does not inherently give any indication of where in the code it was emitted. With a small number of debugging print statements, this may not be a problem. With a large number of print statements (especially if they are not yours), they can be difficult to sort out and understand.

A logging framework provides several advantages over print statements. Logging frameworks typically provide some sort of log(message, priority) routine, used for emitting a message with an associated priority (e.g. "debug", "info", "warning", "error"). The framework itself directs the output to some destination, along with a configurable set of useful information such as a timestamp, the name of the class or source file containing the log statement, and even the line code line number. Likewise, logging frameworks may filter logged messages based upon priority or logging level, or even disable logging completely. For this reason, unlike the transient nature of printf statements, logging statements are typically kept in the codebase indefinitely, making it a deploy-time decision whether to log them to a file or not.

 
©   Cornell University  |  Center for Advanced Computing  |  Copyright Statement  |  Inclusivity Statement