public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Re: How to setup a breakpoint on constructor
@ 2004-07-18 19:29 Michael Elizabeth Chastain
  2004-07-19  3:58 ` Eli Zaretskii
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-18 19:29 UTC (permalink / raw)
  To: drow, eliz; +Cc: gdb

eliz> Sorry, I must be missing something: if we put the breakpoint on all
eliz> the instances of the constructor's code, and do that without asking
eliz> the user anything, what UI aspects need to be figured out and
eliz> designed?

What does 'print &A::A()' print?

What does 'disassemble A::A()' print?

There's an assumption in some of gdb's commands that one source code
address maps to one object code address.  The UI has to acknowledge
that some source code addresses map to multiple object code addresses.

Michael C

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-18 19:29 How to setup a breakpoint on constructor Michael Elizabeth Chastain
@ 2004-07-19  3:58 ` Eli Zaretskii
  0 siblings, 0 replies; 21+ messages in thread
From: Eli Zaretskii @ 2004-07-19  3:58 UTC (permalink / raw)
  To: Michael Elizabeth Chastain; +Cc: drow, gdb

> Date: Sun, 18 Jul 2004 15:03:16 -0400 (EDT)
> From: mec.gnu@mindspring.com (Michael Elizabeth Chastain)
> 
> What does 'print &A::A()' print?
> 
> What does 'disassemble A::A()' print?

Okay, but these have nothing to do with setting a breakpoint on
A::A().  Moreover, I think these two usages are much more rare than
"break A::A()" (I wonder how many users even know about the former,
for example).

So I don't think these issues should prevent us from using the patch.

> There's an assumption in some of gdb's commands that one source code
> address maps to one object code address.  The UI has to acknowledge
> that some source code addresses map to multiple object code addresses.

We could fix these problems later, as we discover them.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-19  3:22       ` Daniel Jacobowitz
@ 2004-07-19 14:51         ` Eli Zaretskii
  0 siblings, 0 replies; 21+ messages in thread
From: Eli Zaretskii @ 2004-07-19 14:51 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: mec.gnu, gdb, rolandz

> Date: Sun, 18 Jul 2004 17:48:53 -0400
> From: Daniel Jacobowitz <drow@false.org>
> 
> Is it one breakpoint with multiple addresses, or have we created multiple
> breakpoints?

The latter, I'd say.  After all, that was one of the reasons for the
change in the breakpoint machinery that now supports multiple
locations for a single breakpoint, right?

> If the latter, we have to somehow distinguish the two of them in the UI
> so that the user can see which is which; and generate different
> location strings for them, so that if the user recompiles and reloads
> the breakpoints get set on the same place, in case they have different
> conditions or commands or enable status.

We should do these, true; but even if we didn't, the resulting
deficiencies would be much less painful than the current situation.
AFAIK, bugs in constructors and destructors are quite common, so
having no good means to debug them is BAD, IMHO.

> The general case of 'break <line>' has many similar issues, for
> instance in templates or inlined functions; describing the location is
> quite a problem.
> 
> Not an insoluble one, surely, but I get stuck every time I work on
> it...

Maybe describing the issues here could produce some usefule discusion
about possible design solutions.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-18 19:03     ` Eli Zaretskii
@ 2004-07-19  3:22       ` Daniel Jacobowitz
  2004-07-19 14:51         ` Eli Zaretskii
  0 siblings, 1 reply; 21+ messages in thread
From: Daniel Jacobowitz @ 2004-07-19  3:22 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: mec.gnu, gdb, rolandz

On Sun, Jul 18, 2004 at 09:42:39PM +0200, Eli Zaretskii wrote:
> > Date: Sun, 18 Jul 2004 01:04:20 -0400
> > From: Daniel Jacobowitz <drow@false.org>
> > > 
> > > Can't we put a breakpoint on all instances in that case as well?
> > 
> > Yes.  But this requires a certain amount of user interface design and
> > implementation hackery that no one has done
> 
> Sorry, I must be missing something: if we put the breakpoint on all
> the instances of the constructor's code, and do that without asking
> the user anything, what UI aspects need to be figured out and
> designed?

Is it one breakpoint with multiple addresses, or have we created multiple
breakpoints?  If the former, we have to somehow arrange to display
them.

If the latter, we have to somehow distinguish the two of them in the UI
so that the user can see which is which; and generate different
location strings for them, so that if the user recompiles and reloads
the breakpoints get set on the same place, in case they have different
conditions or commands or enable status.

The general case of 'break <line>' has many similar issues, for
instance in templates or inlined functions; describing the location is
quite a problem.

Not an insoluble one, surely, but I get stuck every time I work on
it...

-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-18 18:44   ` Daniel Jacobowitz
@ 2004-07-18 19:03     ` Eli Zaretskii
  2004-07-19  3:22       ` Daniel Jacobowitz
  0 siblings, 1 reply; 21+ messages in thread
From: Eli Zaretskii @ 2004-07-18 19:03 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: mec.gnu, gdb, rolandz

> Date: Sun, 18 Jul 2004 01:04:20 -0400
> From: Daniel Jacobowitz <drow@false.org>
> > 
> > Can't we put a breakpoint on all instances in that case as well?
> 
> Yes.  But this requires a certain amount of user interface design and
> implementation hackery that no one has done

Sorry, I must be missing something: if we put the breakpoint on all
the instances of the constructor's code, and do that without asking
the user anything, what UI aspects need to be figured out and
designed?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-18  5:05 ` Eli Zaretskii
@ 2004-07-18 18:44   ` Daniel Jacobowitz
  2004-07-18 19:03     ` Eli Zaretskii
  0 siblings, 1 reply; 21+ messages in thread
From: Daniel Jacobowitz @ 2004-07-18 18:44 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Michael Elizabeth Chastain, gdb, rolandz

On Sun, Jul 18, 2004 at 07:11:07AM +0200, Eli Zaretskii wrote:
> > Date: Sat, 17 Jul 2004 16:52:25 -0400 (EDT)
> > From: mec.gnu@mindspring.com (Michael Elizabeth Chastain)
> > 
> > > Coincidentally that's what the entire discussion of 1:N breakpoints
> > > last year was about but no one has had time to implement it.
> > 
> > Right.
> > 
> > 1:N breakpoints are better than A::A$base(), but it's been 3 years since
> > the ctor-breakpoint issue came up, and we don't have anything at all
> > yet.
> 
> So how about setting a breakpoint on all of the places, like Daniel
> suggested?
> 
> > But if someone breaks in A::A$base() and then says 'break 1000' to get
> > into the middle of the function (which I do a lot), then they would get
> > the breakpoint in the wrong copy!  So even if we disambiguate the
> > names, the 1:N nature of multiple ctors shines through.
> 
> Can't we put a breakpoint on all instances in that case as well?

Yes.  But this requires a certain amount of user interface design and
implementation hackery that no one has done; every time I tried I got
bogged down in some dependency.

-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-17 23:17 Michael Elizabeth Chastain
@ 2004-07-18  5:05 ` Eli Zaretskii
  2004-07-18 18:44   ` Daniel Jacobowitz
  0 siblings, 1 reply; 21+ messages in thread
From: Eli Zaretskii @ 2004-07-18  5:05 UTC (permalink / raw)
  To: Michael Elizabeth Chastain; +Cc: drow, gdb, mec.gnu, rolandz

> Date: Sat, 17 Jul 2004 16:52:25 -0400 (EDT)
> From: mec.gnu@mindspring.com (Michael Elizabeth Chastain)
> 
> > Coincidentally that's what the entire discussion of 1:N breakpoints
> > last year was about but no one has had time to implement it.
> 
> Right.
> 
> 1:N breakpoints are better than A::A$base(), but it's been 3 years since
> the ctor-breakpoint issue came up, and we don't have anything at all
> yet.

So how about setting a breakpoint on all of the places, like Daniel
suggested?

> But if someone breaks in A::A$base() and then says 'break 1000' to get
> into the middle of the function (which I do a lot), then they would get
> the breakpoint in the wrong copy!  So even if we disambiguate the
> names, the 1:N nature of multiple ctors shines through.

Can't we put a breakpoint on all instances in that case as well?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
@ 2004-07-17 23:17 Michael Elizabeth Chastain
  2004-07-18  5:05 ` Eli Zaretskii
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-17 23:17 UTC (permalink / raw)
  To: drow, eliz; +Cc: gdb, mec.gnu, rolandz

> Coincidentally that's what the entire discussion of 1:N breakpoints
> last year was about but no one has had time to implement it.

Right.

1:N breakpoints are better than A::A$base(), but it's been 3 years since
the ctor-breakpoint issue came up, and we don't have anything at all
yet.

> The reason this is hard is that breakpoints by line number inside the
> constructor will still get randomly set on one copy.  Many IDEs will set
> breakpoints in this fashion.

With A::A$base(), the breakpoints will always get set in the complete
object constructor, because that is the only function named A::A().
People will still get only one breakpoint, but it's deterministic, not
random.

But if someone breaks in A::A$base() and then says 'break 1000' to get
into the middle of the function (which I do a lot), then they would get
the breakpoint in the wrong copy!  So even if we disambiguate the
names, the 1:N nature of multiple ctors shines through.

I wish we could persuade gcc to generate a unified ctor.

Michael C

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-17 14:30 ` Eli Zaretskii
@ 2004-07-17 14:54   ` Daniel Jacobowitz
  0 siblings, 0 replies; 21+ messages in thread
From: Daniel Jacobowitz @ 2004-07-17 14:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Michael Elizabeth Chastain, gdb, rolandz

On Sat, Jul 17, 2004 at 01:28:33PM +0200, Eli Zaretskii wrote:
> > Date: Fri, 16 Jul 2004 15:31:17 -0400 (EDT)
> > From: mec.gnu@mindspring.com (Michael Elizabeth Chastain)
> > 
> > To take the points in reverse order,
> > 
> > > (B) It exposes the difference between complete and base constructors,
> > > which is an implementation detail of the C++ ABI that most users don't
> > > understand.
> > 
> > That is reality.
> 
> Yes.
> 
> > The reality is that g++ emits two functions in the object code.  In
> > my opinion, if we try to gloss over that, then we'll just create
> > more confusion for commands such as 'disassemble' and 'tbreak'.
> 
> We could perhaps help users who are oblivious to this (or just
> forgot) by showing them the possible places where GDB could put the
> breakpoint, including the more self-explaining names, and asking them
> what to do.  For example:
> 
>     (gdb) break 'A::A()'
>     The constructor 'A::A()' has two code instances:
> 
>       Address    Mangled Name   Name               Description
>       08048544   _ZN1AC1Ev      A::A()$base()      Base constructor for A
>       080486e2   _ZN1AC2Ev      A::A()$allocate()  Allocating constructor for A
> 
>     Where do you want to put your breakpoint?  Type `1' for the first
>     instance, `2' for the second, `A' for all of them:
>     1 <==== user response
> 
>     Breakpoint 1 at 0x8048544: file derivation.cc, line 7.

At that point we may as well automatically set both breakpoints; that's
almost always what the user wants.  Then we can do without the naming
hack.

Coincidentally that's what the entire discussion of 1:N breakpoints
last year was about but no one has had time to implement it.

Note that we'll still get continuous complaints about setting
breakpoints in constructors!  The reason this is hard is that
breakpoints by line number inside the constructor will still get
randomly set on one copy.  Many IDEs will set breakpoints in this
fashion.

-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-16 19:59 Michael Elizabeth Chastain
  2004-07-16 22:15 ` Jim Blandy
@ 2004-07-17 14:30 ` Eli Zaretskii
  2004-07-17 14:54   ` Daniel Jacobowitz
  1 sibling, 1 reply; 21+ messages in thread
From: Eli Zaretskii @ 2004-07-17 14:30 UTC (permalink / raw)
  To: Michael Elizabeth Chastain; +Cc: drow, gdb, rolandz

> Date: Fri, 16 Jul 2004 15:31:17 -0400 (EDT)
> From: mec.gnu@mindspring.com (Michael Elizabeth Chastain)
> 
> To take the points in reverse order,
> 
> > (B) It exposes the difference between complete and base constructors,
> > which is an implementation detail of the C++ ABI that most users don't
> > understand.
> 
> That is reality.

Yes.

> The reality is that g++ emits two functions in the object code.  In
> my opinion, if we try to gloss over that, then we'll just create
> more confusion for commands such as 'disassemble' and 'tbreak'.

We could perhaps help users who are oblivious to this (or just
forgot) by showing them the possible places where GDB could put the
breakpoint, including the more self-explaining names, and asking them
what to do.  For example:

    (gdb) break 'A::A()'
    The constructor 'A::A()' has two code instances:

      Address    Mangled Name   Name               Description
      08048544   _ZN1AC1Ev      A::A()$base()      Base constructor for A
      080486e2   _ZN1AC2Ev      A::A()$allocate()  Allocating constructor for A

    Where do you want to put your breakpoint?  Type `1' for the first
    instance, `2' for the second, `A' for all of them:
    1 <==== user response

    Breakpoint 1 at 0x8048544: file derivation.cc, line 7.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-16 14:27     ` Daniel Jacobowitz
@ 2004-07-17 10:30       ` Eli Zaretskii
  0 siblings, 0 replies; 21+ messages in thread
From: Eli Zaretskii @ 2004-07-17 10:30 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: mec.gnu, gdb, rolandz

> Date: Fri, 16 Jul 2004 10:21:13 -0400
> From: Daniel Jacobowitz <drow@false.org>
> 
> (A) It was an ugly interface change to work around an internal
> limitation, and they needed to retrain users to it.
> 
> (B) It exposes the difference between complete and base constructors,
> which is an implementation detail of the C++ ABI that most users don't
> understand.

IMVHO, these 2 objections are not serious enough to prevent us from
using Michael's patch (or yours, for that matter).  As things are now,
GDB has a serious drawback wrt debugging C++ constructors; the patch
in question provides a relatively easy workaround.

So I think we should install the patch (and have it prominently
documented in the user's manual, so that users will be able to easily
find such a subtle technique).

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
@ 2004-07-17 10:09 Michael Elizabeth Chastain
  0 siblings, 0 replies; 21+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-17 10:09 UTC (permalink / raw)
  To: jimb, mec.gnu; +Cc: drow, eliz, gdb, rolandz

jimb> If I remember right, the use of separate complete and base
jimb> constructors is an ABI requirement; the compiler doesn't have the
jimb> option of just generating whatever code it likes.

The ABI does require separate names.

If I recall correctly, Apple implemented this by having separate names
for base ctor and complete ctor (as required by the ABI) and then having
them call a unified constructor.

Gcc optimization can reduce calls from {base,complete}-ctor to
unified-ctor, from call instructions to jump instructions.

Then the debugger just puts ctor breakpoints on the
unified-ctor.

  http://gcc.gnu.org/ml/gcc-patches/2002-08/msg00354.html

Apple folks, have I got that right?

Michael C

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-16 19:59 Michael Elizabeth Chastain
@ 2004-07-16 22:15 ` Jim Blandy
  2004-07-17 14:30 ` Eli Zaretskii
  1 sibling, 0 replies; 21+ messages in thread
From: Jim Blandy @ 2004-07-16 22:15 UTC (permalink / raw)
  To: Michael Elizabeth Chastain; +Cc: drow, eliz, gdb, rolandz

mec.gnu@mindspring.com (Michael Elizabeth Chastain) writes:

> To take the points in reverse order,
> 
> > (B) It exposes the difference between complete and base constructors,
> > which is an implementation detail of the C++ ABI that most users don't
> > understand.
> 
> That is reality.  The reality is that g++ emits two functions in the
> object code.  In my opinion, if we try to gloss over that, then we'll
> just create more confusion for commands such as 'disassemble' and
> 'tbreak'.
> 
> > (A) It was an ugly interface change to work around an internal
> > limitation, and they needed to retrain users to it.
> 
> I agree with this part, to an extent.  However, the gdb group
> has no control over the fact that there are two object code
> functions.
> 
> I like the way it worked in gcc 2.95.3.  With gcc 2.95.3,
> gcc emits one function with a hidden parameter.  c++ programmers
> and gdb are both familiar with hidden parameters ('this').
> If I recall correctly, Apple modified gcc 3.X to do something
> similar.

If I remember right, the use of separate complete and base
constructors is an ABI requirement; the compiler doesn't have the
option of just generating whatever code it likes.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
@ 2004-07-16 19:59 Michael Elizabeth Chastain
  2004-07-16 22:15 ` Jim Blandy
  2004-07-17 14:30 ` Eli Zaretskii
  0 siblings, 2 replies; 21+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-16 19:59 UTC (permalink / raw)
  To: drow, eliz; +Cc: gdb, mec.gnu, rolandz

To take the points in reverse order,

> (B) It exposes the difference between complete and base constructors,
> which is an implementation detail of the C++ ABI that most users don't
> understand.

That is reality.  The reality is that g++ emits two functions in the
object code.  In my opinion, if we try to gloss over that, then we'll
just create more confusion for commands such as 'disassemble' and
'tbreak'.

> (A) It was an ugly interface change to work around an internal
> limitation, and they needed to retrain users to it.

I agree with this part, to an extent.  However, the gdb group
has no control over the fact that there are two object code
functions.

I like the way it worked in gcc 2.95.3.  With gcc 2.95.3,
gcc emits one function with a hidden parameter.  c++ programmers
and gdb are both familiar with hidden parameters ('this').
If I recall correctly, Apple modified gcc 3.X to do something
similar.

Michael C

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-16 11:11   ` Eli Zaretskii
@ 2004-07-16 14:27     ` Daniel Jacobowitz
  2004-07-17 10:30       ` Eli Zaretskii
  0 siblings, 1 reply; 21+ messages in thread
From: Daniel Jacobowitz @ 2004-07-16 14:27 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: mec.gnu, gdb, rolandz

On Fri, Jul 16, 2004 at 02:09:23PM +0200, Eli Zaretskii wrote:
> > Date: Thu, 15 Jul 2004 09:54:28 -0400
> > From: Daniel Jacobowitz <drow@false.org>
> > 
> > FYI, I implemented this once.  The users who tried it didn't like it at
> > all.
> 
> Did they tell why they didn't like it?

(A) It was an ugly interface change to work around an internal
limitation, and they needed to retrain users to it.

(B) It exposes the difference between complete and base constructors,
which is an implementation detail of the C++ ABI that most users don't
understand.

-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-15 11:31 Michael Elizabeth Chastain
@ 2004-07-16 13:17 ` Roland Zerek
  0 siblings, 0 replies; 21+ messages in thread
From: Roland Zerek @ 2004-07-16 13:17 UTC (permalink / raw)
  To: Michael Elizabeth Chastain, gdb

Użytkownik Michael Elizabeth Chastain napisał:

> See the PROBLEMS file:
> 
>   gdb/1091: Constructor breakpoints ignored
>   gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set breakpoints

Well, I am using gdb-6.0 and gcc-3.4.0. Seems that problems remain...

>   When gcc 3.x compiles a C++ constructor or C++ destructor, it generates
>   2 or 3 different versions of the object code.  These versions have
>   unique mangled names (they have to, in order for linking to work), but
>   they have identical source code names, which leads to a great deal of
>   confusion.  Specifically, if you set a breakpoint in a constructor or a
>   destructor, gdb will put a breakpoint in one of the versions, but your
>   program may execute the other version.  This makes it impossible to set
>   breakpoints reliably in constructors or destructors [...]

However this is logical to have mangled names. And of course few 
constructors. Even ISO says that the default constructor may be created by 
the compiler in some situations...

> Things you can try:
> 
> . modify your program so that the constructors that you want to
>   breakpoint call some function that is not a constructor, and break
>   on that.

I've already been considerring it.

> . run 'nm a.out | c++filt' to find the symbols in your program.
>   break on the absolute address: "break *0x01234567".  this is
>   very crude (1960's technique) but it does work.

Seems nice. However my MinGW (Win XP) seems not to have these. I will take 
a look of it later :-)

> . use nm, c++filt, and 'strip -N' to strip out symbols for
>   not-in-charge constructors.  This is scriptable, if someone
>   wants to write a little script.

What the "not-in-charge" means?

Thx for reply.

-- 
Roland
r o l a n d z (at) poczta fm

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-15 14:09 ` Daniel Jacobowitz
@ 2004-07-16 11:11   ` Eli Zaretskii
  2004-07-16 14:27     ` Daniel Jacobowitz
  0 siblings, 1 reply; 21+ messages in thread
From: Eli Zaretskii @ 2004-07-16 11:11 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: mec.gnu, gdb, rolandz

> Date: Thu, 15 Jul 2004 09:54:28 -0400
> From: Daniel Jacobowitz <drow@false.org>
> 
> FYI, I implemented this once.  The users who tried it didn't like it at
> all.

Did they tell why they didn't like it?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
  2004-07-15 13:55 Michael Elizabeth Chastain
@ 2004-07-15 14:09 ` Daniel Jacobowitz
  2004-07-16 11:11   ` Eli Zaretskii
  0 siblings, 1 reply; 21+ messages in thread
From: Daniel Jacobowitz @ 2004-07-15 14:09 UTC (permalink / raw)
  To: Michael Elizabeth Chastain; +Cc: gdb, rolandz

On Thu, Jul 15, 2004 at 07:31:03AM -0400, Michael Chastain wrote:
> Hi Roland,
> 
> Would you like to try a makeshift and experimental patch?
> 
>   ftp://ftp.shout.net/pub/users/mec/ctor-dtor-base.patch
> 
> (Patch attached to this message too).
> 
> You have to apply this to the libiberty/ subdirectory of a
> recent gdb, such as gdb 6.1.1, and then rebuild gdb.
> 
> There's a lot of doco in the patch but it rambles.
> The basic idea is that I patched the demangler so that
> it demangles the different ctor's with different names:
> 
>   A::A()
>   A::A$base()
>   A::A$allocate()
> 
> I don't know if it's a good idea for gdb to work this way,
> but I think it's worth getting some user feedback.
> 
> Testing: I haven't run the test suite with this.
> I did test a small program (testsuite/gdb.cp/derivation.cc)
> and it works the way I think it should.

FYI, I implemented this once.  The users who tried it didn't like it at
all.


-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
@ 2004-07-15 13:55 Michael Elizabeth Chastain
  2004-07-15 14:09 ` Daniel Jacobowitz
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-15 13:55 UTC (permalink / raw)
  To: gdb, rolandz

Hi Roland,

Would you like to try a makeshift and experimental patch?

  ftp://ftp.shout.net/pub/users/mec/ctor-dtor-base.patch

(Patch attached to this message too).

You have to apply this to the libiberty/ subdirectory of a
recent gdb, such as gdb 6.1.1, and then rebuild gdb.

There's a lot of doco in the patch but it rambles.
The basic idea is that I patched the demangler so that
it demangles the different ctor's with different names:

  A::A()
  A::A$base()
  A::A$allocate()

I don't know if it's a good idea for gdb to work this way,
but I think it's worth getting some user feedback.

Testing: I haven't run the test suite with this.
I did test a small program (testsuite/gdb.cp/derivation.cc)
and it works the way I think it should.

Michael C

===

gdb has a problem with g++ constructors and destructors.
This patch resolves the problem in a simple but crude way.

The problem is described in the gdb PROBLEMS file:

  gdb/1091: Constructor breakpoints ignored
  gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set breakpoints

  When gcc 3.x compiles a C++ constructor or C++ destructor, it generates
  2 or 3 different versions of the object code.  These versions have
  unique mangled names (they have to, in order for linking to work), but
  they have identical source code names, which leads to a great deal of
  confusion.  Specifically, if you set a breakpoint in a constructor or a
  destructor, gdb will put a breakpoint in one of the versions, but your
  program may execute the other version.  This makes it impossible to set
  breakpoints reliably in constructors or destructors.

  gcc 3.x generates these multiple object code functions in order to
  implement virtual base classes.  gcc 2.x generated just one object code
  function with a hidden parameter, but gcc 3.x conforms to a multi-vendor
  ABI for C++ which requires multiple object code functions.

This patch changes the demangler so that it demangles different
linkage names back to different source code names, so that gdb and
gdb users are no longer confused by several object code functions
with identical source code names.

Before this patch:

  08048544   _ZN1AC1Ev   A::A()
  080486e2   _ZN1AC2Ev   A::A()

After this patch:

  08048544   _ZN1AC1Ev   A::A()
  080486e2   _ZN1AC2Ev   A::A$base()

You still have to understand that g++ emits two (sometimes three)
copies of each constructor.

The constructor with "C1" in the linkage name is the complete
object constructor.  Your program calls this constructor when it
creates an object whose complete type is A, such as "new A".

The constructor with "C2" in the linkage name is the base object
constructor.  Your program calls this constructor when it creates
an object derived from A, such as "new B".  Your program does *not*
call the base object constructor for "new A".

The difference between type "C1" and type "C2" has to do with
virtual base classes.  In C++, the constructor for the complete
object initializes all the virtual bases, and constructors for
base classes do not initialize any virtual bases.

Here is an example:

  class A { ... };
  class B1 : virtual public A { ... };
  class B2 : virtual public A { ... };
  class C  : public B1, public B2 { ... };

When your program creates a C with "new C", your program calls the type
C1 constructor for C::C.  C::C (type C1) calls A::A (type C2) to
initialize the virtual base.  Then C::C (type C1) calls B1::B1 (type C2)
and B2::B2 (type C2) to initialize the normal bases.

If you understand virtual bases, all this should make sense.
If you don't understand virtual bases, just remember the simple rule:
"new Foo" calls Foo::Foo (type C1), and everything that Foo::Foo
for all its bases is of type C2.

There is also a constructor of type "C3".  I have never actually
seen one of these, but it would be marked "Foo::Foo$allocate".

After you apply this patch and rebuild gdb, all the constructors
with names 'Foo::Foo' are the complete object constructors.
'Foo::Foo$base' are the base object constructors, and
'Foo::Foo$allocate' are the allocating object constructors.

All three constructors are compiled from the same source code.
To set a breakpoint on the constructor, you actually have to set
two or three breakpoints (usually just two).  If you take the
short-cut and just break on 'Foo::Foo', you will get breakpoints
whenever 'new Foo' happens, but not when 'new Bar' happens if
Bar is derived from Foo.  You need to break on 'Foo::Foo$base'
to get breakpoints for that.

Michael C

===

Here is a typescript of a gdb session with this patch.
Note how 'A::A()' is called for an object of type A,
and 'A::A$base()' is called for objects of types D, E, F, and G,
which have A as a base class.

Script started on Thu Jul 15 07:14:52 2004

[mec.gnu@berman HEAD]$ ./gdb/gdb ~/tmp/a.out
GNU gdb 2004-07-14-cvs
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) break 'A::A^G
A::A$base()  A::A()       

(gdb) break 'A::A()'
Breakpoint 1 at 0x8048547: file derivation.cc, line 7.

(gdb) break 'A::A$base()' 
Breakpoint 2 at 0x80486e5: file derivation.cc, line 7.

(gdb) run
Starting program: /berman/home/mec.gnu/tmp/a.out 

Breakpoint 1, A (this=0xbffff888) at derivation.cc:8
8	        a=1;

(gdb) backtrace
#0  A (this=0xbffff888) at derivation.cc:8
#1  0x08048481 in main () at derivation.cc:203

(gdb) list 203
198	
199	
200	int main(void)
201	{
202	
203	    A a_instance;
204	    B b_instance;
205	    C c_instance;
206	    D d_instance;
207	    E e_instance;

(gdb) cont
Continuing.

Breakpoint 2, A (this=0xbffff850) at derivation.cc:8
8	        a=1;

(gdb) backtrace
#0  A (this=0xbffff850) at derivation.cc:8
#1  0x0804859d in D (this=0xbffff850) at derivation.cc:58
#2  0x080484ae in main () at derivation.cc:206

(gdb) cont
Continuing.

Breakpoint 2, A (this=0xbffff830) at derivation.cc:8
8	        a=1;

(gdb) backtrace
#0  A (this=0xbffff830) at derivation.cc:8
#1  0x080485eb in E (this=0xbffff830) at derivation.cc:74
#2  0x080484bd in main () at derivation.cc:207

(gdb) cont
Continuing.

Breakpoint 2, A (this=0xbffff810) at derivation.cc:8
8	        a=1;

(gdb) backtrace
#0  A (this=0xbffff810) at derivation.cc:8
#1  0x08048639 in F (this=0xbffff810) at derivation.cc:90
#2  0x080484cf in main () at derivation.cc:208

(gdb) cont
Continuing.

Breakpoint 2, A (this=0xbffff7e0) at derivation.cc:8
8	        a=1;

(gdb) backtrace
#0  A (this=0xbffff7e0) at derivation.cc:8
#1  0x08048687 in G (this=0xbffff7e0) at derivation.cc:108
#2  0x080484e1 in main () at derivation.cc:209

(gdb) cont
Continuing.

Program exited normally.

(gdb) quit
[mec.gnu@berman HEAD]$ exit

Script done on Thu Jul 15 07:15:50 2004
===

2004-07-15  Michael Chastain  <mec.gnu@mindspring.com>

	* cp-demangle.c (d_print_comp) Return unique names for
	ctor and dtor names by decorating them with "$base",
	"$allocate", and "$delete".

Index: cp-demangle.c
===================================================================
RCS file: /cvs/src/src/libiberty/cp-demangle.c,v
retrieving revision 1.51
diff -c -3 -p -r1.51 cp-demangle.c
*** cp-demangle.c	28 Jun 2004 18:01:41 -0000	1.51
--- cp-demangle.c	15 Jul 2004 10:53:01 -0000
*************** d_print_comp (dpi, dc)
*** 2978,2988 ****
--- 2978,3012 ----
  
      case DEMANGLE_COMPONENT_CTOR:
        d_print_comp (dpi, dc->u.s_ctor.name);
+       switch (dc->u.s_ctor.kind)
+ 	{
+ 	case gnu_v3_complete_object_ctor:
+ 	  /* no decoration */
+ 	  break;
+ 	case gnu_v3_base_object_ctor:
+ 	  d_append_string_constant (dpi, "$base");
+ 	  break;
+ 	case gnu_v3_complete_object_allocating_ctor:
+ 	  d_append_string_constant (dpi, "$allocate");
+ 	  break;
+ 	}
        return;
  
      case DEMANGLE_COMPONENT_DTOR:
        d_append_char (dpi, '~');
        d_print_comp (dpi, dc->u.s_dtor.name);
+       switch (dc->u.s_dtor.kind)
+ 	{
+ 	case gnu_v3_deleting_dtor:
+ 	  d_append_string_constant (dpi, "$delete");
+ 	  break;
+ 	case gnu_v3_complete_object_dtor:
+ 	  /* no decoration */
+ 	  break;
+ 	case gnu_v3_base_object_dtor:
+ 	  d_append_string_constant (dpi, "$base");
+ 	  break;
+ 	}
        return;
  
      case DEMANGLE_COMPONENT_VTABLE:

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: How to setup a breakpoint on constructor
@ 2004-07-15 11:31 Michael Elizabeth Chastain
  2004-07-16 13:17 ` Roland Zerek
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-15 11:31 UTC (permalink / raw)
  To: gdb, rolandz

> Is there anything different in the constructor in comparision to normal 
> function since I cannot break the program in there?

Yes, this is a long-standing problem with gdb and gcc 3.X.

See the PROBLEMS file:

  gdb/1091: Constructor breakpoints ignored
  gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set breakpoints

  When gcc 3.x compiles a C++ constructor or C++ destructor, it generates
  2 or 3 different versions of the object code.  These versions have
  unique mangled names (they have to, in order for linking to work), but
  they have identical source code names, which leads to a great deal of
  confusion.  Specifically, if you set a breakpoint in a constructor or a
  destructor, gdb will put a breakpoint in one of the versions, but your
  program may execute the other version.  This makes it impossible to set
  breakpoints reliably in constructors or destructors.

  gcc 3.x generates these multiple object code functions in order to
  implement virtual base classes.  gcc 2.x generated just one object code
  function with a hidden parameter, but gcc 3.x conforms to a multi-vendor
  ABI for C++ which requires multiple object code functions.

Things you can try:

. modify your program so that the constructors that you want to
  breakpoint call some function that is not a constructor, and break
  on that.

. run 'nm a.out | c++filt' to find the symbols in your program.
  break on the absolute address: "break *0x01234567".  this is
  very crude (1960's technique) but it does work.

. use nm, c++filt, and 'strip -N' to strip out symbols for
  not-in-charge constructors.  This is scriptable, if someone
  wants to write a little script.

It's a hard problem.

Michael C

^ permalink raw reply	[flat|nested] 21+ messages in thread

* How to setup a breakpoint on constructor
@ 2004-07-15 10:30 Roland Zerek
  0 siblings, 0 replies; 21+ messages in thread
From: Roland Zerek @ 2004-07-15 10:30 UTC (permalink / raw)
  To: gdb

Hi,

Is there anything different in the constructor in comparision to normal 
function since I cannot break the program in there?

I am able to set the breakpoint but it never stops there. I am working with 
mingw (gcc-3.4.0) and gdb-6.0 (from mingw page).

I would appreciate any hints. TIA.

-- 
Roland
r o l a n d z (at) poczta fm

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2004-07-19  3:58 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-18 19:29 How to setup a breakpoint on constructor Michael Elizabeth Chastain
2004-07-19  3:58 ` Eli Zaretskii
  -- strict thread matches above, loose matches on Subject: below --
2004-07-17 23:17 Michael Elizabeth Chastain
2004-07-18  5:05 ` Eli Zaretskii
2004-07-18 18:44   ` Daniel Jacobowitz
2004-07-18 19:03     ` Eli Zaretskii
2004-07-19  3:22       ` Daniel Jacobowitz
2004-07-19 14:51         ` Eli Zaretskii
2004-07-17 10:09 Michael Elizabeth Chastain
2004-07-16 19:59 Michael Elizabeth Chastain
2004-07-16 22:15 ` Jim Blandy
2004-07-17 14:30 ` Eli Zaretskii
2004-07-17 14:54   ` Daniel Jacobowitz
2004-07-15 13:55 Michael Elizabeth Chastain
2004-07-15 14:09 ` Daniel Jacobowitz
2004-07-16 11:11   ` Eli Zaretskii
2004-07-16 14:27     ` Daniel Jacobowitz
2004-07-17 10:30       ` Eli Zaretskii
2004-07-15 11:31 Michael Elizabeth Chastain
2004-07-16 13:17 ` Roland Zerek
2004-07-15 10:30 Roland Zerek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).