Bug 9399 - gdb can't call or print a const function that uses virtual inheritance
Summary: gdb can't call or print a const function that uses virtual inheritance
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.6
: P3 enhancement
Target Milestone: 7.1
Assignee: Chris Moller
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-02 20:58 UTC by jlevine
Modified: 2009-12-10 21:06 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jlevine 2007-08-02 20:58:01 UTC
[Converted from Gnats 2294]

Having a virtual const function in a class that is inherited from a base class using virtual inheritance causes a "Cannot access memory at address 0x0" error when doing a 'print' on that function from the gdb console.  Taking out the virtual keyword from the inheritance of the base class solves the problem, or just removing the const from the function also fixes it.

The problem seems to be from the call_function_by_hand() function in gdb/infcall.c, near the start of the function.  You'll see the following two lines that were added in 6.6:

    if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
      ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
      
This replaces ftype with the target type if the function is a pointer, and eventually this leads to a xfer_partial memory read that has a NULL obj->beneath, and the memory read returns a -1.  I wasn't able to track down why the virtual inheritance causes this bad memory read.  As a temp work around, I have commented out the two lines of code and this fixes the problem.  Please see the test case below to reproduce the error.

I haven't tested this test case in 64bit mode, but my early tests showed the problem wasn't there if you compiled with 64bit and used a 64bit gdb.

Release:
gdb 6.6

Environment:
32bit ee3_0 using gnu g++ 3.2.3 and 4.1.1
gdb 6.6

How-To-Repeat:
Compile with the following testcase and run the following commands at the gdb prompt:
(gdb) break main
(gdb) start
(gdb) next
(gdb) print o.do_print()

-------- test case ------------------------
class interface { };
 
class Obj : 
virtual // comment out this line and it works
public interface
{
public:
  virtual const char* do_print() const { return "Obj3"; }
};
 
int main(int argc, char** argv) {
  Obj o;
  return 0;
}
Comment 1 jlevine 2007-08-02 20:58:01 UTC
Fix:
See description
Comment 3 Chris Moller 2009-12-10 21:06:29 UTC
Problem was unnecessary casting in valops.c:value_cast_struct resulting in an
attempt to dereference a null resulting from a  value_zero.  Fix was to return
NULL if the type names are non-null and match.