This is the mail archive of the gdb-prs@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: c++/186: gdb have problems with C++ casting


Synopsis: gdb have problems with C++ casting

Responsible-Changed-From-To: nobody->chastain
Responsible-Changed-By: chastain
Responsible-Changed-When: Sun Nov 23 20:28:57 2003
Responsible-Changed-Why:
    
    Mine (unless David C wants it).
State-Changed-From-To: open->analyzed
State-Changed-By: chastain
State-Changed-When: Sun Nov 23 20:28:57 2003
State-Changed-Why:
    
    Hello,
    
    This is an old PR, but I'm finally getting to it.
    
    David C, could you take a look at this?
    
    The use case is:
    
    . there is a local variable with a derived type
    . the user sets a breakpoint on the close brace of the function
    
    So, the breakpoint is taken after the local variable is destroyed.
    
    The first issue is that the user is examining memory that has been destroyed.  At the C++ abstraction level, anything could have happened to that memory after the destructor was called.  However, in this specific case, and many cases like this, the actual generated code does not touch the fields of the variable, so it's useful for someone to look at them in the debugger.
    
    But ...
    
    The destructor for the local variable *does* change the vptr of the variable while it is running.  That is, the actual variable "y" was of type "B" while it was alive.  But the destructor code in B::~B() actually changed the vptr in "y" so that the variable is of type "A".  Naturally, B::~B() does this so that it can call A::~A() with a variable of the correct type.  This is a normal part of C++.
    
    So, after the destructor is called, two things are happening.  First, the user is looking at dead memory.  This is okay in this particular case because the memory isn't getting re-used.
    
    Second, and more importantly, the dynamic type of 'y' is now a vptr to "A" rather than a vptr to "B".  gdb follows the vptr's.  That is why gdb gets the right result for the fields from the base class and the wrong result for the fields from the derived class.
    
    It is kind of bogus for gdb to do this:
    
      (gdb) print * (B *) x
      $3 = {<A> = {i = 1, _vptr. = 0x8048828 <A virtual table>}, j = 0, k = 0}
    
    The user wants to print a "B" structure, but the actual data in memory says that it is only an "A".  gdb wants to print a "B" structure, but it uses an "A" virtual table to look up information for "j" and "k".  gdb ought to know that there is no "j" and "k" in "A", so it ought to print something like "there is no A" here, or maybe use the "B" virtual table anyways.  Anything is better than garbage data.  (We know that gdb isn't using the "B" virtual table because if it was, then it would get the right values from memory, where they are correct).
    
     

http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=186


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]