I started by breaking down the code into a few major sections and isolating them into their own modules. This helped me focus on one section of the code at a time without having to understand the whole thing. Then I made as much of the code as possible private. As long as the interfaces were clean, I could fix up the internals at my leisure - or hand them out for others to fix. Then I tried to get it to compile. Then whenever I ran into a runtime problem, I was cleanup that section of code while I fixed the bug.
tl;dr - Divide and conquer. Julius Caesar for the win!