Wednesday, June 2, 2010

Printpoints : Debugging by writing to console

There are two ways of debugging
  • Breakpoints - I typically use breakpoints when
    • I do not have much idea of the code and need to inspect variables and expressions at a number of places to gain an understanding of what is happening.
    • I am making some changes and want to see how these changes affect a particular variable/expression, also I am confident that one or two iterations of this change-test process will suffice
  • Printpoints - There are scenarios when the breakpoints fail or are inefficient, in these cases I just use System.out.println(). This is typically when
    • the breakpoint hits too often, for example keypress, focus, mouse events
    • I want to see the order of thread execution
    • I am making some changes and want to see how these changes affect a 'few' variables/expressions, also I am confident that it will take 'a number' of iterations of this change-test process to fix the bug. Printing everything to console in this case proves to be much more efficient than stepping through the code.
Most developers (including me till recently) insert the print statements in their code and the problem with that is that you have to take them out later. I know you can sometimes leave them in the source as tracing statements, but most of the time they have to be taken out. But there is a solution...

The conditional breakpoint editor in Eclipse can be 'tricked' to create what I like to call as Printpoint - and define as a 'point' in code where the debugger does not 'break' but only 'prints' to console. Essentially a Printpoint is a conditional breakpoint that never suspends execution but only prints to console. To set a printpoint, set a conditional breakpoint with Suspend when 'true' option and a condition which is always false. e.g.


Code templates are available in the condition editor, so you can create a template under 'Java statements' context and use it here. Bug 315404 has been filed to have this available in JDT by default.

11 comments:

  1. Wow, I really like this Deepak. I wonder if there is any value is making PinPoints first class citizens in the IDE (insert Breakpoint, insert PintPoint). If there was explicit PinPoint tooling, I wonder what else would be possible.

    ReplyDelete
  2. Ian, I did attempt to do that but the UI in breakpoints view got a bit cluttered with what I tried. However this was before I knew the trick :)

    If I get some better ideas for the UI I will give it another try as the trick is not obvious.

    ReplyDelete
  3. So cool trick :)
    Thanks to share it.

    ReplyDelete
  4. Great idea. Especially when you think that you can micromanage the breakpoints (enable/disable, import/export - to create "tracing profiles").

    ReplyDelete
  5. Quick question. To where does the output go, the osgi console? I have tried this at times, but there were times when I did not have the output show up anywhere (at least that was my recollection. I assume the return could also do simthing like return (i++%10)== 0; to stop every tenth time after the print?

    ReplyDelete
  6. @lhasadad The output goes to the same place as when the sysout is placed in the code. and yes you can do return (i++%10)== 0;

    ReplyDelete
  7. That's quite clever. Certainly beats littering my code w/ sysouts or traces. And I do think this would be a neat addition as "first class" IDE feature.

    ReplyDelete
  8. I'm not clear on how when this would be preferable to standard logging facilities such as log4j or the java.util.logging package. Why would anyone want their logging setup tied to a specific developer's specific IDE?

    ReplyDelete
    Replies
    1. You should use this only when you want to debug something and remove the debug statements in the end.

      Delete
  9. This trick works in NetBeans, too. I needed to debug a piece of code where the breakpoints were just too slow and caused the protocol to fail.

    ReplyDelete