User forums > Using Code::Blocks
GDB question and linked static libs...
gerard:
So it's gcc that's the problem then. C::B is looking and feeling real good to me, but I hate this compiler/debugger issue. C::B looks sweet to work in on XP. :) Win2K on a 15" LCD at work is tedious. :D
I've done the nightly build install and got MinGW 3.4.4 and MinGW's GDB 6.3 now here at home on WinXP. Same story, always gets messed up in constructors defined in headers (virtual constructors, inline in class definitions). It's not really that I need a breakpoint in a constructor, it's just that it gets bogged down in constructors in header files where I don't even call them or don't even use them.
Anyone ever tried the Borland compilers, etc? Then again, the debugger there is different. Could run with the free compilers and debuggers from Visual Studio 2005, but I'm looking at near 800MB of download just to build a win32 app with their compilers. 300-odd MB of that just for the SDK to make the native win32 apps. Don't need the whole .NET thing. :P
thomas:
I think it should be possible to even implement proper breakpoints in constructors from inside Code::Blocks without actually hacking gdb.
However, it won't be easy at all, and it would require us to include kind of a "micro-codeparser" into the debugger plugin.
First of all, one can use the rbreak command (as pointed out by Yiannis a couple of months back) on the constructor. rbreak sets breakpoints on all functions matching a regular expression. Thus, given the constructor with its exact signature, it should reliably set a breakpoint exactly where it belongs.
The problem with this is that you have to do it by hand. Also, it breaks only a the constructor's entry point, not at a specific line.
Using a "micro-codeparser", one could however count how many lines we are from the entry and call next that many times. The problem with this is that calling next for every souce line is probably the most inefficient way to execute a program, so this must only be done if it is really necessary. Therefore, we would need to be able to determine whether or not a given line is inside a constructor (here goes the micro-codeparser again).
Alternatively (to avoid the confusion about BPs being silently ignored), we could forbid setting line breakpoints in certain places (constructors) and instead introduce a special "break at function entry" feature which takes the function name/signature from the current line, does a rbreak on that one and nothing more. Not perfect, but better than nothing. It would still require kind of a micro-codeparser to decide where to allow "break at function" and where not to allow "break at line".
As a different approach, instead of using rbreak, one could extract the mangled constructor names using objdump and filter out the correct ones by unmangling them again via c++filt.
While this is quite expensive, it might be doable when run only once at startup.
Functions (non-Constructors) will have exactly one version with precisely the same signature, but constructors will have several versions with precisely the same signature. Drop everything that has only one version, cache the rest. This leaves us with a list of all constructor source names and mangled names (fits neatly into a std::multimap).
Now, to set a breakpoint, find each one with the correct source name and signature, and set a breakpoint using the respective mangled name. Setting and clearing breakpoints should be less overhead this way, once the data is in our cache.
I guess, rbreak works in a similar way, too, but it is probably less error-prone...
Yiannis?
thomas:
Actually.... no!
We don't need a microparser!
Here goes:
1. Set a breakpoint at the designated line using the break command.
2. Call info break to get a listing of all breakpoints, including the line and the corresponding function name for each breakpoint. Since we know the line already, we now know the function name too. It is trivial to guess whether it is a constructor or not (ClassName::ClassName).
3. If it is not a constructor, we're done. It will work anyway.
4. If it is a constructor, remove the breakpoint, but break on the constructor's name, gdb will return the source line of the constructor ("breakpoint at line....").
We now have the entry point's line and the target line, so we know how often we have to call next after hitting the breakpoint!
5. Now, either use rbreak on the constructor name or or unmangle all symbols to find the ones that match exactly -- whatever.
6. When the breakpoint is hit, call next for as many times as we need to.
mandrav:
--- Quote ---Yiannis?
--- End quote ---
The only viable solution (which was once implemented, before the redesign of the debugger plugin), is to use rbreak. Period. Everything else is a hack. Well, rbreak is a hack too, but less hack than the others ;).
Read on:
--- Quote ---4. If it is a constructor, remove the breakpoint, but break on the constructor's name, gdb will return the source line of the constructor ("breakpoint at line....").
We now have the entry point's line and the target line, so we know how often we have to call next after hitting the breakpoint!
--- End quote ---
(emphasis mine)
Guess what: this isn't going to work. You can't just count lines! What if these lines contain conditional blocks, like if-else? There's your micro-codeparser again ;).
All in all, this is too much work for nothing. We will (re)implement the rbreak method (and move the breakpoint at the start of the ctor function for visual feedback) and that's about it.
<rant>
A constructor should rarely ever need to be debugged anyway. Constructors should be as small as possible. If you need to add lots of initialization code in the constructor, put it in a different function, like Init() or something, and call this instead. It makes for cleaner code too :).
</rant>
marfig:
--- Quote from: mandrav on July 30, 2006, 05:42:28 pm ---The only viable solution (which was once implemented, before the redesign of the debugger plugin), is to use rbreak. Period. Everything else is a hack. Well, rbreak is a hack too, but less hack than the others ;).
--- End quote ---
Definitely. It's the most correct choice debugger-wise, since it is implemented by GDB itself. It works, it's much cleaner than to set dummy functions in your code, and supports any breakpoints set after that.
I'm sorry to hijack this thread to ask something else, slightly related... Where should I do suggestions to the debugger plugin? after two threads and no replies to my posts I fear I'm using the wrong forums...
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version