views:

36

answers:

2

I'm considering how to do automatic bug tracking and as part of that I'm wondering what is available to match source code line numbers (or more accurate numbers mapped from instruction pointers via something like addr2line) in one version of a program to the same line in another. (Assume everything is in some kind of source control and is available to my code)

The simplest approach would be to use a diff tool/lib on the files and do some math on the line number spans, however this has some limitations:

  • It doesn't handle cross file motion.
  • It might not play well with lines that get changed
  • It doesn't look at the information available in the intermediate versions.
  • It provides no way to manually patch up lines when the diff tool gets things wrong.
  • It's kinda clunky

Before I start diving into developing something better:

  • What already exists to do this?
  • What features do similar system have that I've not thought of?
A: 

Why do you need to do this? If you use decent source version control, you should have access to old versions of the code, you can simply provide a link to that so people can see the bug in its original place. In fact the main problem I see with this system is that the bug may have already been fixed, but your automatic line tracking code will point to a line and say there's a bug there. Seems this system would be a pain to build, and not provide a whole lot of help in practice.

davr
What I'm thinking of wouldn't so much track specific bugs by line number (how often do tricky bugs *have* a single line number) but but is more along the lines of keeping track of stats about where things get detected. For instance; what assert gets hit most often? What lines of code are most commonly on the stack when an assert trips? That kind of things. Being able to combine that kind of things from one version to another would be very nice.
BCS
A: 

My suggestion is: instead of trying to track line numbers, which as you observed can quickly get out of sync as software changes, you should decorate each assertion (or other line of interest) with a unique identifier.

Assuming you're using C, in the case of assertions, this could be as simple as changing something like assert(x == 42); to assert(("check_x", x == 42)); -- this is functionally identical, due to the semantics of the comma operator in C and the fact that a string literal will always evaluate to true.

Of course this means that you need to identify a priori those items that you wish to track. But given that there's no generally reliable way to match up source line numbers across versions (by which I mean that for any mechanism you could propose, I believe I could propose a situation in which that mechanism does the wrong thing) I would argue that this is the best you can do.

Another idea: If you're using C++, you can make use of RAII to track dynamic scopes very elegantly. Basically, you have a Track class whose constructor takes a string describing the scope and adds this to a global stack of currently active scopes. The Track destructor pops the top element off the stack. The final ingredient is a static function Track::getState(), which simply returns a list of all currently active scopes -- this can be called from an exception handler or other error-handling mechanism.

j_random_hacker