How to approach debugging a huge not so familiar code base?

Use a pen and paper, or images/graphs/charts in general, to figure out which parts belong where and draw some arrows and so on.

This helps you build and see the image that will then be refined in your mind as you become more comfortable with it.

I used a similar approach attacking a hellish system that had 10 singletons all #including each other. I had to redraw it a few times in order to fit everything, but seeing it in front of you helps.

It might also be useful to use Graphviz when constructing dependency graphs. That way you only have to list everything (in a text file) and then the tool will draw the (often unsightly) picture. (This is what I did for the #include dependencies in above syste,)


Some pointers:

  1. Debug from the part which seems more relevant to the workflow.
  2. Use debug strings
  3. Get appropriate .pdb and attach the core dump in debuggers like Windbg or debugdiag to analyze it.
  4. Get a person's help in your organization who is good at debugging. Even if he is new to your codebase, he could be very helpful. I had prior experience. They would give you valuable pointers.
  5. Per Assaf Lavie's advice, you could use static code analyzers.
  6. The most important thing: as you explore and debug, document everything as you progress. At least the person succeeding you would suffer less.

As others have already suggested, writing unit-tests is a great way to get into the codebase. There are a number of advantages to this approach:

  1. It allows you to test your assumptions about how the code works. Adding a passing test proves that your assumptions about that small piece of code that you are testing are correct. The more passing tests you write, the better you understand the code.

  2. A failing unit test that reproduces the bug you want to fix will pass when you fix the bug and you know that you have succeeded.

  3. The unit tests that you write act as documentation for the future.

  4. The unit tests you write act as regression tests as more bugs are fixed.

Of course adding unit tests to legacy code is not always an easy task. Happily, a gentleman by the name of Michael Feathers has written an excellent book on the subject, which includes some great 'recipes' on adding tests to code bases without unit tests.

WELC


If possible, step through it from main() to the problematic area, and follow the execution path. Along the way you'll get a good idea of how the different parts play together.

It could also be helpful to use a static code analysis tool, like CppDepends or even Doxygen, to figure out the relations between modules and be able to view them graphically.

Tags:

C++

C

Debugging