The underlying problem with breakpoints in constructors was that gcc generates two distinct function bodies for a constructor. One is a regular one that constructs the entire object, including all bases. Another one constructs everything except for virtual base classes. As it happens, gcc emits both constructors even for classes that have no virtual bases at all. GDB was not prepared that a given function name or source line corresponds to several addresses in program, so it picks one. And usually it picked the wrong one.
Constructor is the most common case, but is not the only one. If you set a breakpoint in a function template, you can have multiple template instantiations that correspond to a source line. An inline function can be inlined in multiple places, and lead to exactly the same problem.
The solution, obviously, is to teach GDB that a breakpoint can correspond to several addresses, and then create multiple-location breakpoints when needed. Now, whenever a user creates a breakpoint that resolves to a source line, GDB traverses line tables for all modules, and if it finds another address for the same line, that address is added to breakpoint. For a template or inline function, you can end up with quite a lot of locations, so you can review list of locations, and disable the unwanted ones.
The nicest bit of this is interaction with shared libraries. Say, you've set a breakpoint inside function template. If you load a new shared library, and it contains an instantiation of that function template, a new location will be added to the breakpoint, transparently. If a library is unloaded, the location will become 'pending', until you load the library back.
The side effect of this work was a serious improvement in the way breakpoints in shared libraries work, but that's a topic for another post.
8 comments:
Yay! Can't wait for the new gdb. Awesome work!
You're like my hero for the whole month now. Just want you to know that. :)
The patch has been backported to the GDB in Rawhide (future Fedora 9) on November 3.
That's like kinda wow! :D
Unless I'm mistaken, this has been a problem for GDB since GCC 3.0. Fantastic news!
Really great! Does this maybe also solve some of the general problems while debugging within constructors? For example, it seems like gdb sometimes is not aware of local variables within constructors.
David, I don't think any other bugs with debugging constructors were fixed, at least intentionally. In fact, I don't know any other problem specific to constructors, in GDB. Can you give some more details?
i don't know if you'll get this message, but here is an excellent bug report of exactly the problem i believe zwabel was referring to.
I am also having this problem in a constructor that is very complicated and long. Hard to debug with no info about local variables.
check this link
Great. That would have spared me a lot of workarounds. I use MinGW GDB 6.6. So I will change to 6.8 as soon as possible and do a lot of cleanup. Thanks very much.
Post a Comment