Author Topic: GDB question and linked static libs...  (Read 7123 times)

Offline gerard

  • Single posting newcomer
  • *
  • Posts: 3
GDB question and linked static libs...
« on: July 28, 2006, 05:01:47 pm »
I installed C::B today after trying things like Dev-C++, Eclipse & CDT, Vs2005 C++ Express, etc, etc., for use as a C++ IDE with debugging.

None of the other IDEs had any decent GDB or other debugger support, so C::B is looking promising. Otherwise I'm going to opt for using Visuall C++ IDE from Microsoft. :P

Problem I am having is getting GDB (6.3) to stop at break points. In C::B I have a main project (Windows GUI) and I have created another project in the same workspace where I place common libraries in a static library (.a file). All paths, etc, are sorted out properly so the library builds with debugging support (-g3 option) and so does the main GUI application.

I place a breakpoint in the main application where it creates an object from a class defined in the static library. I then have a breakpoint in that classes constructor.

When I do a "step into" from the main application, or do a continue, I am expecting it to hit the breakpoint in the class constructor. The continue however skips all that and the application runs and never hits the break point. The step-into hits some arb blank line in a header file used in the static library. It's just a blank line, there are no inline methods defined in that header either. It reports "no line xxx in file yyy.h".

I have tried various versions of GDB and tried to build version 6.5 as well without much success.

I have used the mingw that comes with C::B, and also the stuff that comes with Dev-C++, etc., but no luck. They all just hit the same blank line in the header file.

What's the deal with this?

This is all on a P4 3GHz running Win2K (SP4) with C::B 1rc2
« Last Edit: July 28, 2006, 05:16:42 pm by gerard »

sethjackson

  • Guest
Re: GDB question and linked static libs...
« Reply #1 on: July 28, 2006, 05:09:41 pm »
I installed C::B today after trying things like Dev-C++, Eclipse & CDT, Vs2005 C++ Express, etc, etc., for use as a C++ IDE with debugging.

None of the other IDEs had any decent GDB or other debugger support, so C::B is looking promising. Otherwise I'm going to opt for using Visuall C++ IDE from Microsoft. :P

Problem I am having is getting GDB (6.3) to stop at break points. In C::B I have a main project (Windows GUI) and I have created another project in the same workspace where I place common libraries in a static library (.a file). All paths, etc, are sorted out properly so the library builds with debugging support (-g3 option) and so does the main GUI application.

I place a breakpoint in the main application where it creates an object from a class defined in the static library. I then have a breakpoint in that classes constructor.

When I do a "step into" from the main application, or do a continue, I am expecting it to hit the breakpoint in the class constructor. The continue however skips all that and the application runs and never hits the break point. The step-into hits some arb blank line in a header file used in the static library. It's just a blank line, there are no inline methods defined in that header either.

I have tried various versions of GDB and tried to build version 6.5 as well without much success.

I have used the mingw that comes with C::B, and also the stuff that comes with Dev-C++, etc., but no luck. They all just hit the same blank line in the header file.

What's the deal with this?

This is all on a P4 3GHz running Win2K (SP4) with C::B 1rc2

Heh we need to add this to the FAQ or something :lol:

It is a bug of GDB unfortunately. :P

http://forums.codeblocks.org/index.php?topic=613.0

Also you are using rc2. You really need to use a nightly build. ;)

Offline Charon

  • Multiple posting newcomer
  • *
  • Posts: 49
  • fnord
    • charon - where mental illness meets chronic nonsense
Re: GDB question and linked static libs...
« Reply #2 on: July 28, 2006, 05:10:10 pm »
hi,

there were lots of bugfixes and additions in the nightly build considering debugging.
i don't know if these fixes will help you with your specific problem but the chances are quite high.

so get yourself a nightly build and try it again!
(but be sure to read the howto for the installation since nightly builds don't have an installer and don't come with their own copy of mingw)

regards
Markus

[edit]
argh, got beaten to it...

but yeah now i remember this myself :
to jump into a constructor during debugging with GDB you need to create an empty member-function in your class, call it first in your constructor and set your breakpoint inside this member-function.
[/edit]
« Last Edit: July 28, 2006, 05:14:07 pm by Charon »
hi, i am a signature virus. please copy me into your sig!
Wish list : no root-node for workspaces, open files and symbols; world domination

Offline gerard

  • Single posting newcomer
  • *
  • Posts: 3
Re: GDB question and linked static libs...
« Reply #3 on: July 28, 2006, 05:25:15 pm »
I'll get a nightly build. Thanks.

Ain't this all going to look way too messy? Lots of ifdef DEBUG stuff everywhere to have a empty member function in the class just to trap the breakpoint.

Liveable if it works, though. :) Will give it a try.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GDB question and linked static libs...
« Reply #4 on: July 28, 2006, 06:18:35 pm »
Quote
I place a breakpoint in the main application where it creates an object from a class defined in the static library. I then have a breakpoint in that classes constructor.

When I do a "step into" from the main application, or do a continue, I am expecting it to hit the breakpoint in the class constructor. The continue however skips all that and the application runs and never hits the break point.

What's the deal with this?
The deal with this is that setting breakpoints in constructors does not work reliably with "plain normal" gcc / gdb. This has nothing to do with Code::Blocks, and it will not be better after installing a nightly build (however, it is very much worth using a nightly build nevertheless).

The compiler generates several versions of a constructor to implement virtual base classes (no matter whether the class is virtual or not). Don't ask me why, ask a guy from the gcc team if you're interested why that has to be like this.
The problem is that all these constructors obviously have the same name. They're mangled differently, so the linker will find the correct one, but the "visible" name is still the same. While they have the same source name, they are nevertheless different things.
So what happens if you set a breakpoint? The debugger uses names as they're found in the source, and it cannot reliably set a breakpoint into the correct thingie (it doesn't know which one).

There are patches for gcc and gdb that follow various strategies to work around this, but that's all non-standard stuff.

An easy way to work around this limitation is to call a dummy function from inside the constructor and set your BP in there (there is only one version of that dummy func, so there's no problem).
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline gerard

  • Single posting newcomer
  • *
  • Posts: 3
Re: GDB question and linked static libs...
« Reply #5 on: July 30, 2006, 01:30:09 am »
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
« Last Edit: July 30, 2006, 01:42:56 am by gerard »

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GDB question and linked static libs...
« Reply #6 on: July 30, 2006, 01:50:29 pm »
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?
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GDB question and linked static libs...
« Reply #7 on: July 30, 2006, 02:13:18 pm »
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.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4291
    • Code::Blocks IDE
Re: GDB question and linked static libs...
« Reply #8 on: July 30, 2006, 05:42:28 pm »
Quote
Yiannis?

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!

(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>
Be patient!
This bug will be fixed soon...

Offline marfig

  • Multiple posting newcomer
  • *
  • Posts: 36
Re: GDB question and linked static libs...
« Reply #9 on: July 30, 2006, 05:52:13 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 ;).

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...

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GDB question and linked static libs...
« Reply #10 on: July 30, 2006, 06:34:21 pm »
Quote
Guess what: this isn't going to work. You can't just count lines! What if these lines contain conditional blocks, like if-else?

Oh right, I entirely forgot about that... there might be for() or while() loops or something, too.

But on the good side, we have gdb's output after calling next:
At D:/Desktop/cb/src/main.cpp:534

Since we always know what line we're in, we could actually call next until the line number where the breakpoint should be is eventually reached.

The only problem is that it is possible that a breakpoint is never reached at all. In that case, we would be stepping through the program for forever and a day.
But... we do have the stack frame. Thus, we could set a breakpoint at the return address, and if that one is reached for whatever reason, assume that the breakpoint won't be hit any more and resume normal operation.
That way, we step through the code line by line until either the constructor is left or the breakpoint line is reached.

It is still a lot of work for rather little benefit, but I think it should work (and we'd be the one and only IDE for gcc having working breakpoints in constructors ;)).
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5193
Re: GDB question and linked static libs...
« Reply #11 on: July 30, 2006, 06:38:54 pm »
Quote
It is still a lot of work for rather little benefit, but I think it should work (and we'd be the one and only IDE for gcc having working breakpoints in constructors Wink).
:twisted: :twisted: :twisted: :twisted:

sethjackson

  • Guest
Re: GDB question and linked static libs...
« Reply #12 on: July 30, 2006, 06:42:08 pm »
Quote
It is still a lot of work for rather little benefit, but I think it should work (and we'd be the one and only IDE for gcc having working breakpoints in constructors :wink:).

Actually one and only cross-platform IDE (to have this feature). :)  8)