The best way to find out what the code does is to look at the source. That's the only thing that never fails. Documentation gets out of sync, comments lie, and colleagues forget, but The Source is eternal.
Actually, the best way to find out what the code does is to watch it doing it inside a debugger.
True... if your code isn't time sensitive... and your debugger (or monitoring system) is perfect. Debuggers can tell you very little about complex software, and often lead you to looking in the wrong place anyways. Especially in languages with poor debugger support, like c/c++, this can lead to a horrible style of band-aid debugging that uniformly decreases the maintainability of the software.
The scenario goes something like this. A (rushed/confused/incompetent) coder is staring at the symptom in the debugger, say an array overrun in c code. The software as a whole lacks the analytical framework (test suite, invariant analysis, etc.) to help discover the *root* cause of this problem, and after minutes->hours of messing about in the debugger, the coder still doesn't really understand what is going on. However, he sees a local fix, and patches in some test that keeps the overrun from occurring and smashing the stack. Result? The code no longer fails. Great, right? Fundamentally misguided is more like it. The failure mode still exists, and is silently corrected local to where the problem showed up. What is likely to happen is that a further change in the code later one will re-expose the problem in a different way. But now some (perhaps unrelated) function has this hacked in logic (perhaps un- or poorly documented) which no longer really applies and didn't really make sense in the first place. Propagate this sort of 'fix' through an Mloc system over a few years and what you end up with is a travesty.
The best way to find out what the code does is
a) understand what it is trying to do b) understand what the implementation *should* do c) test this understanding (with test code (do you have several years to waste stepping through code?)) .... n) as a last resort, if nothing is making sense, fire up the debugger *on the right piece of code* (which you can only describe if you actually understand what is going on) and see what you have misunderstood. n+1) see if the compiler is lying to you ...
That's the only thing that never fails
That can fail too. The famous login.c hack (http://www.acm.org/classics/sep95/) is an example of this. Even if you looked at the source for login.c and cc.c you wouldn't have seen it.
If you really need to worry about this, you're better off with an IntrusionDetectionSystem? than a debugger!
Luke? What's "Luke" got to do with anything here?
It's a pun on the famous "Use the Force, Luke" mantra from the movie StarWars.
See Also: StudyTheSourceWithaDebugger, ReadItLikeaComputer, TipsForReadingCode