public inbox for archer@sourceware.org
 help / color / mirror / Atom feed
* Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01
@ 2009-09-23 14:08 Dragos Tatulea
  2009-09-25 18:40 ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Dragos Tatulea @ 2009-09-23 14:08 UTC (permalink / raw)
  To: keiths; +Cc: archer, jan.kratochvil, cmoller

Hi Keith,

> That is, I think "set print object on" ought to affect the type of the
> resulting history variable -- but not the type of any intermediate
> values in an expression.
>
> Jan> One should change this (+some other related options in
> Jan> `user_print_options') and in some way fix the testsuite regressions
> Jan> afterwards by one of:
>
> I agree, we should change this default.

I changed objectprint to on by default on Jan's suggestion, but this breaks some
other cases like this one (from ptr-typedef test)

struct foo {
  int x;
};

typedef struct foo *foz;

int
main (void)
{
  foz_ptr = NULL;
}

gdb> p foz_ptr
$1 = (struct foo *) 0x0
instead of
(foz*)

So the change isn't acceptable.

Back to the previous case: Jan suggested printing an error/warning for the user
saying that the ptr has a different type (and maybe printing the type). What do
you think?

Thanks,
Dragos

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

* Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01
  2009-09-23 14:08 [Keith Seitz] Re: [tools-team] Status 2008-09-01 Dragos Tatulea
@ 2009-09-25 18:40 ` Tom Tromey
  2009-09-25 19:39   ` Dragos Tatulea
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2009-09-25 18:40 UTC (permalink / raw)
  To: Dragos Tatulea; +Cc: keiths, archer, jan.kratochvil, cmoller

>>>>> "Dragos" == Dragos Tatulea <dragos.tatulea@gmail.com> writes:

Dragos> I changed objectprint to on by default on Jan's suggestion, but
Dragos> this breaks some other cases like this one (from ptr-typedef
Dragos> test)

Dragos> gdb> p foz_ptr
Dragos> $1 = (struct foo *) 0x0
Dragos> instead of
Dragos> (foz*)

This seems like a generic bug, though.  So, it could be fixed either
separately or at the same time the default is flipped.

Dragos> Back to the previous case: Jan suggested printing an
Dragos> error/warning for the user saying that the ptr has a different
Dragos> type (and maybe printing the type). What do you think?

I think it depends on how often the warning would trigger, and where it
would be printed (e.g., would it show up mid-struct?).

Tom

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

* Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01
  2009-09-25 18:40 ` Tom Tromey
@ 2009-09-25 19:39   ` Dragos Tatulea
  2009-09-25 20:45     ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Dragos Tatulea @ 2009-09-25 19:39 UTC (permalink / raw)
  To: Tom Tromey; +Cc: keiths, archer, jan.kratochvil, cmoller

Hi,

> Dragos> I changed objectprint to on by default on Jan's suggestion, but
> Dragos> this breaks some other cases like this one (from ptr-typedef
> Dragos> test)
>
> Dragos> gdb> p foz_ptr
> Dragos> $1 = (struct foo *) 0x0
> Dragos> instead of
> Dragos> (foz*)
>
> This seems like a generic bug, though.  So, it could be fixed either
> separately or at the same time the default is flipped.
>
Why is this a bug? Isn't objectprint supposed to follow up to the original/true
type?

> Dragos> Back to the previous case: Jan suggested printing an
> Dragos> error/warning for the user saying that the ptr has a different
> Dragos> type (and maybe printing the type). What do you think?
>
> I think it depends on how often the warning would trigger, and where it
> would be printed (e.g., would it show up mid-struct?).
>
Maybe it's not such a good idea to show up in mid struct. Maybe display the
usual output and then print warnings on following lines. Dunno' if it's actually
possible (noob alert!).

-- Dragos

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

* Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01
  2009-09-25 19:39   ` Dragos Tatulea
@ 2009-09-25 20:45     ` Tom Tromey
  2009-09-27 12:22       ` set print objct pros/cons [Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01] Jan Kratochvil
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2009-09-25 20:45 UTC (permalink / raw)
  To: Dragos Tatulea; +Cc: keiths, archer, jan.kratochvil, cmoller

>>>>> "Dragos" == Dragos Tatulea <dragos.tatulea@gmail.com> writes:

Tom> This seems like a generic bug, though.  So, it could be fixed either
Tom> separately or at the same time the default is flipped.

Dragos> Why is this a bug? Isn't objectprint supposed to follow up to
Dragos> the original/true type?

I see what you mean.

But, it seems like it would be a little more user-friendly to print the
original type name if we examine the runtime type and find that it is
identical to the declared type (after typdef stripping).

Dragos> Maybe it's not such a good idea to show up in mid struct. Maybe
Dragos> display the usual output and then print warnings on following
Dragos> lines. Dunno' if it's actually possible (noob alert!).

Probably not easily, but I'm sure it could be managed.
But, when printing a long structure this is likely to be more confusing.

Tom

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

* set print objct pros/cons  [Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01]
  2009-09-25 20:45     ` Tom Tromey
@ 2009-09-27 12:22       ` Jan Kratochvil
  2009-09-27 17:14         ` Keith Seitz
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Kratochvil @ 2009-09-27 12:22 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Dragos Tatulea, keiths, archer, cmoller

[-- Attachment #1: Type: text/plain, Size: 1269 bytes --]

Hi,

just found out `set print object on' is not such a clear win:

(gdb) b 27
Breakpoint 1 at 0x40069b: file cxxinherit.C, line 27.
(gdb) r
Starting program: /home/jkratoch/t/cxxinherit 
derived::m
base::m
Breakpoint 1, main () at cxxinherit.C:27
27	  return 0;
(gdb) show print object 
Printing of object's derived type based on vtable info is off.
(gdb) p derivedp->m
$1 = {void (Derived *)} 0x4006c4 <Derived::m()>
(gdb) p basep->m
$2 = {void (Base *)} 0x4006a2 <Base::m()>
(gdb) call derivedp->m ()
derived::m
(gdb) call basep->m ()
base::m
(gdb) set print object on
(gdb) p derivedp->m
$3 = {void (Derived *)} 0x4006c4 <Derived::m()>
(gdb) p basep->m
$4 = {void (Derived *)} 0x4006c4 <Derived::m()>
(gdb) call derivedp->m ()
derived::m
(gdb) call basep->m ()
base::m


(1) Last "call basep->m ()" should have printed "derived::m"
    because "p basep->m" prints "Derived::m()", shouldn't it?

(2) A lookup can succeed in both "off" and "on" cases with different results.

One should fix (1) as it looks just as a bug to me.

Afterwards for (2) maybe any C++ print should be evaluated both ways and if
the resulting `struct value' differs it should print both values with a warning?

("any C++ print" could be optimized somehow, not the point here.)


Thanks,
Jan

[-- Attachment #2: cxxinherit.C --]
[-- Type: text/plain, Size: 396 bytes --]

#include <stdio.h>

class Base
  {
  public:
    void m () { puts ("base::m"); }
    virtual void stub () {}
  };

class Derived : public Base
  {
  public:
    virtual void m () { puts ("derived::m"); }
    virtual void stub () {}
  };

int
main ()
{
  Derived derived_local;
  Derived *derivedp = &derived_local;
  Base *basep = &derived_local;

  derivedp->m ();
  basep->m ();

  return 0;
}

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

* Re: set print objct pros/cons  [Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01]
  2009-09-27 12:22       ` set print objct pros/cons [Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01] Jan Kratochvil
@ 2009-09-27 17:14         ` Keith Seitz
  2009-09-27 18:26           ` Jan Kratochvil
  0 siblings, 1 reply; 10+ messages in thread
From: Keith Seitz @ 2009-09-27 17:14 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: archer

On 09/27/2009 05:21 AM, Jan Kratochvil wrote:
>
> (1) Last "call basep->m ()" should have printed "derived::m"
>      because "p basep->m" prints "Derived::m()", shouldn't it?
>

basep->m will always print "base::m" -- your test case did not declare 
Base::m virtual. Or is that just an omission in the file you attached?

> (2) A lookup can succeed in both "off" and "on" cases with different results.

Indeed. I believe gdb should stick to the language rules, "print object" 
or not. We need to break the unwritten gdb development rule that 
everything must have a freakin' switch in the debugger. It's 
unscalable/unmanageable/user-unfriendly. IMO, "object print" should not 
even exist at all.

Keith

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

* Re: set print objct pros/cons  [Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01]
  2009-09-27 17:14         ` Keith Seitz
@ 2009-09-27 18:26           ` Jan Kratochvil
  0 siblings, 0 replies; 10+ messages in thread
From: Jan Kratochvil @ 2009-09-27 18:26 UTC (permalink / raw)
  To: Keith Seitz; +Cc: archer

[-- Attachment #1: Type: text/plain, Size: 1383 bytes --]

On Sun, 27 Sep 2009 19:14:22 +0200, Keith Seitz wrote:
> On 09/27/2009 05:21 AM, Jan Kratochvil wrote:
> >
> >(1) Last "call basep->m ()" should have printed "derived::m"
> >     because "p basep->m" prints "Derived::m()", shouldn't it?
> >
> 
> basep->m will always print "base::m" -- your test case did not
> declare Base::m virtual. Or is that just an omission in the file you
> attached?

It was intentional that way (unaware how common it is in C++ to override
non-virtual method name by a virtual one, though).

I think the following two commands should deal with the same pointer, whithout
even talking about which pointer ("Derived::m" or "Base::m") it should be:

It does not work now - with the previous testcase cxxinherit.C:
	(gdb) set print object on
	(gdb) p basep->m
	$4 = {void (Derived *)} 0x4006c4 <Derived::m()>
	(gdb) call basep->m ()
	base::m


> IMO, "object print" should not even exist at all.

Currently the "off" mode does not work right for the virtual/virtual case:

With the new attached testcase cxxinherit2.C:
	Starting program: /home/jkratoch/t/cxxinherit2 
	derived::m
	derived::m
	Breakpoint 1, main () at cxxinherit2.C:27
	27	  return 0;
	(gdb) show print object 
	Printing of object's derived type based on vtable info is off.
	(gdb) call basep->m ()
	derived::m
	(gdb) p basep->m
	$1 = {void (Base *)} 0x4006a6 <Base::m()>
	(gdb) 


Regards,
Jan

[-- Attachment #2: cxxinherit2.C --]
[-- Type: text/plain, Size: 404 bytes --]

#include <stdio.h>

class Base
  {
  public:
    virtual void m () { puts ("base::m"); }
    virtual void stub () {}
  };

class Derived : public Base
  {
  public:
    virtual void m () { puts ("derived::m"); }
    virtual void stub () {}
  };

int
main ()
{
  Derived derived_local;
  Derived *derivedp = &derived_local;
  Base *basep = &derived_local;

  derivedp->m ();
  basep->m ();

  return 0;
}

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

* Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01
  2009-09-02 21:44 ` Jan Kratochvil
@ 2009-09-03 19:19   ` Tom Tromey
  0 siblings, 0 replies; 10+ messages in thread
From: Tom Tromey @ 2009-09-03 19:19 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Project Archer, Chris Moller, Keith Seitz

>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:

Jan> Just this is due the wrong printing defaults:
Jan> (gdb) p obj->num_
Jan> There is no member or method named num_.
Jan> (gdb) set print object on 
Jan> (gdb) p obj->num_
Jan> $1 = 2

I'm really surprised that "set print object" affects this.

It seems to me that this should always follow the language rules, and
that "obj->num_" should therefore be an error.  (I used to hold the
opposite position for Java, funnily enough, but I have come around.)

Instead I would expect this to work:

(gdb) set print object on
(gdb) print *obj
$1 = ... # something of type special_int_math
(gdb) print $.num_
$2 = whatever


That is, I think "set print object on" ought to affect the type of the
resulting history variable -- but not the type of any intermediate
values in an expression.

Jan> One should change this (+some other related options in
Jan> `user_print_options') and in some way fix the testsuite regressions
Jan> afterwards by one of:

I agree, we should change this default.

Tom

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

* Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01
  2009-09-02 19:44 [Keith Seitz] Re: [tools-team] Status 2008-09-01 Tom Tromey
@ 2009-09-02 21:44 ` Jan Kratochvil
  2009-09-03 19:19   ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Kratochvil @ 2009-09-02 21:44 UTC (permalink / raw)
  To: Project Archer; +Cc: Chris Moller, Keith Seitz

On Wed, 02 Sep 2009 21:44:06 +0200, Tom Tromey wrote:
> From: Keith Seitz <keiths@redhat.com>
[...]
> This one is a little less cut-n-dry IMO, but it should still "work":
> (gdb) p obj->num_
> There is no member or method named num_.

Just this is due the wrong printing defaults:

(gdb) p obj->num_
There is no member or method named num_.
(gdb) set print object on 
(gdb) p obj->num_
$1 = 2

One should change this (+some other related options in `user_print_options')
and in some way fix the testsuite regressions afterwards by one of:
(a) Updating the specific testsuite expectations by hand.
(b) Making the "old" options default globally (deprecated)
(c) Making the "old" options default only in the current testcases.


Regards,
Jan

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

* [Keith Seitz] Re: [tools-team] Status 2008-09-01
@ 2009-09-02 19:44 Tom Tromey
  2009-09-02 21:44 ` Jan Kratochvil
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2009-09-02 19:44 UTC (permalink / raw)
  To: Project Archer

[-- Attachment #1: Type: text/plain, Size: 185 bytes --]

Keith sent this useful email privately.  It details some areas of
investigation relating to virtual methods.  I'm forwarding it with his
permission, so we can have it in the archives.


[-- Attachment #2: Type: message/rfc822, Size: 6928 bytes --]

From: Keith Seitz <keiths@redhat.com>
To: Chris Moller <cmoller@redhat.com>
Cc: Tom Tromey <tromey@redhat.com>
Subject: Re: [tools-team] Status 2008-09-01
Date: Tue, 01 Sep 2009 14:55:11 -0700
Message-ID: <4A9D983F.5010707@redhat.com>

On 09/01/2009 02:15 PM, Chris Moller wrote:
> I kinda back-burnered that--to quote Keith, "I'm not even sure I
> completely understand what this task is," but I'll see what I can do
> with it.

For me, the biggest questions lie around virtual (pure and otherwise) 
classes and virtual methods -- printing, listing, breaking/running, 
variable/stack inspection. I've added none of this to realcpp yet. [And 
as you can imagine, gdb's own c++ test suite doesn't even come close to 
testing any real-world c++ usage.]

I'd like to see how gdb handles something like this (very contrived, 
very stupid example):

#include <iostream>

using namespace std;

template <typename T>
class virt_math
{
public:
   virtual T add (T num) = 0;
   virtual T sub (T num) = 0;
   virtual T mul (T num) = 0;
   virtual T div (T num) { return static_cast<T> (-3); } // Yes, I know 
this is really evil!
};

class base_int_math : public virt_math<int>
{
public:
   base_int_math (int a) : num_ (a) { };
   virtual ~base_int_math (void) { };

   virtual int add (int num) { return num_ + num; }
   int sub (int num) { return num_ - num; }
   virtual int mul (int num) { return num_ * num; }

protected:
   int num_;
};

class special_int_math : public base_int_math
{
public:
   special_int_math (int a) : base_int_math (a) { }
   int add (int num) { return num_ + num + 100; }
   int mul (int num) { return num_ * num + 100; }
};

int
main (int argc, char* argv[])
{
   virt_math<int> *obj = new special_int_math (2);
   cout << "obj.add (2) = " << obj->add (2) << endl;
   cout << "obj.sub (2) = " << obj->sub (2) << endl;
   cout << "obj.mul (2) = " << obj->mul (2) << endl;
   cout << "obj.div (2) = " << obj->div (2) << endl;
   delete obj;

   return 0;
}

In main, doing "print *obj" isn't particularly useful IMO (I don't know 
if we could do better, though):
(gdb) p *obj
$1 = {_vptr.virt_math = 0x8048c68}

I don't think this is very useful, either:

(gdb) ptype obj
type = class virt_math<int> {
   public:
     virtual int add(int);
     virtual int sub(int);
     virtual int mul(int);
     virtual int div(int);
} *

IMO, gdb should at least be able to tell us that obj is really a 
special_int_math object using RTTI or something.

I'm also not so sure about this:

(gdb) p special_int_math::add
Cannot reference virtual member function "add"
(gdb) p special_int_math::mul
Cannot reference virtual member function "mul"
(gdb) p special_int_math::div
Cannot reference virtual member function "div"
(gdb) p special_int_math::sub
Cannot reference virtual member function "sub"
(gdb) p base_int_math::add
Cannot reference virtual member function "add"
(gdb) p base_int_math::sub
Cannot reference virtual member function "sub"
(gdb) p base_int_math::div
Cannot reference virtual member function "div"
(gdb) p base_int_math::mul
Cannot reference virtual member function "mul"

IMO, we should be able to figure these things out.

I also don't think this is correct (or at least user-friendly):

(gdb) break virt_math<int>::mul
the class virt_math<int> does not have any method named mul
Hint: try 'virt_math<int>::mul<TAB> or 'virt_math<int>::mul<ESC-?>
(Note leading single quote.)
(gdb) ptype virt_math<int>
type = class virt_math<int> {
   public:
     virtual int add(int);
     virtual int sub(int);
     virtual int mul(int);
     virtual int div(int);
}

The ptype here should mention that most of these class members are pure 
virtual (=0). As it is, it does not tell you.

I also don't like the error messages here:

(gdb) b virt_math<int>::add
the class virt_math<int> does not have any method named add
Hint: try 'virt_math<int>::add<TAB> or 'virt_math<int>::add<ESC-?>
(Note leading single quote.)
(gdb) b virt_math<int>::sub
the class virt_math<int> does not have any method named sub
Hint: try 'virt_math<int>::sub<TAB> or 'virt_math<int>::sub<ESC-?>
(Note leading single quote.)
(gdb) b virt_math<int>::div
Breakpoint 1 at 0x8048acb: file virt_math.cc, line 12.

It's not that virt_math<int> /doesn't/ have methods named "add", "mul", 
and "sub", but that these are pure virtual. This is, IMO, misleading to 
the user, especially since "ptype" makes no distinction between these 
methods and "div" (which is virtual, but not "pure" virtual).

This one is a little less cut-n-dry IMO, but it should still "work":
(gdb) p obj->num_
There is no member or method named num_.

This isn't entirely correct. Yes, "obj" *is* literally a virt_math<int> 
(which contains no fields), but it *is* also a C++ class for which we 
should be able to figure out that it is *really* a special_int_math, and 
therefore num_ *is* a member of that class.

There's also the question about virtual inheritance (realcpp has an 
example): does printing/ptyping these things do something sane and 
USEFUL for the user? I imagine we're going to get multiple vtables. Blah.

Just some of the things that I've been wanting to investigate a bit, but 
haven't gotten around to it.

Keith


[-- Attachment #3: Type: text/plain, Size: 6 bytes --]



Tom

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

end of thread, other threads:[~2009-09-27 18:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-23 14:08 [Keith Seitz] Re: [tools-team] Status 2008-09-01 Dragos Tatulea
2009-09-25 18:40 ` Tom Tromey
2009-09-25 19:39   ` Dragos Tatulea
2009-09-25 20:45     ` Tom Tromey
2009-09-27 12:22       ` set print objct pros/cons [Re: [Keith Seitz] Re: [tools-team] Status 2008-09-01] Jan Kratochvil
2009-09-27 17:14         ` Keith Seitz
2009-09-27 18:26           ` Jan Kratochvil
  -- strict thread matches above, loose matches on Subject: below --
2009-09-02 19:44 [Keith Seitz] Re: [tools-team] Status 2008-09-01 Tom Tromey
2009-09-02 21:44 ` Jan Kratochvil
2009-09-03 19:19   ` Tom Tromey

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