c++/4248: reinterpret_cast in template

Denkhaus, Volker Volker.Denkhaus@softwareag.com
Tue Sep 11 23:33:00 GMT 2001


Hi,

let me try to explain in more detail. Also I will insert the interesting
lines of the code and the machine code as well to explain what I think is
going wrong.

>From what I can see, it looks like the vtable is OK. The pointer passed to
that function (pv) can be examined like this:
(gdb) print pv
$1 = (void *) 0x8072bc8

The pointer this->mpOwner has the same value after the cast statement:
(gdb) print this->m_pOwner
$2 = (CComObject<RsCommon::CRSComponentShellDummy> *) 0x8072bc8

Now I examine the address:

(gdb) x /16x 0x8072bc8
0x8072bc8:	0x40cae020	0x40ce5d00	0x00000000	0xffffffff
0x8072bd8:	0xffffffff	0xffffffff	0xffffffff	0x00000000
0x8072be8:	0x706d742f	0x424c542f	0x33646266	0x504d542e
0x8072bf8:	0x00000000	0x00000000	0x00000000	0x00000000

The first value at 0x8072bc8 I assume is the pointer to the vtable, i.e.
0x40cae020. Now I do an examine of this address:
(gdb) x /16x 0x40cae020
0x40cae020
<ATL::CComObject<RsCommon::CRSComponentShellDummy>::RsCommon::CEDispatchProp
erties<RsCommon::CBDispatchProperties> virtual table>:	0xffffff78
0x40c7a660	0x40c75bec	0x40c75bfc

The prolog of the vtable is 8 bytes, AddRef is always the second method. So
0x40c75bfc should be the AddRef method.
(gdb) x /16x 0x40c75bfc
0x40c75bfc <virtual function thunk (delta:-144) for
ATL::CComObject<RsCommon::CRSComponentShellDummy>::AddRef(void)>:
0x04244481	0xffffff70	0xff95c3e9	0x909090ff
0x40c75c0c <virtual function thunk (delta:-144) for
ATL::CComObject<RsCommon::CRSComponentShellDummy>::Release(void)>:
0x04244481	0xffffff70	0xff95f7e9	0x909090ff

If I look at the machine code I can see the following here:
1.) add    $0x10,%esp
2.) movl   $0x40cae568,0x8(%esi)
3.) movl   $0x40cae580,(%esi)
4.) mov    %ebx,0x34(%esi)
5.) add    $0xfffffff4,%esp
--> This is the code for calling the AddRef function:
6.) mov    0x34(%esi),%edx  // now we have the value of this->m_pOwner in
edx, i.e. 0x8072bc8
7.) add    $0x20,%edx        // Why add 0x20 to this here ??
8.) mov    (%edx),%eax       // Going to the address, i.e. the vtable which
is wrong now because of the 0x20 before
9.) add    $0xc,%eax         // add 12 byte in vtable (8 byte prolog, 4 byte
for first func, cause AddRef is the 2nd func
10.) mov    0x34(%esi),%edx
11.) add    $0x20,%edx
12.) push   %edx
13.) mov    (%eax),%edi
14.) call   *%edi

Up to line 6 everyting seems to be right. edx contains the value of
this->m_pOwner. This points to the vtable. But in line 8 0x20 is added to
that which does point to memory which is not the vtable. If I manually
reassign the vtable address to edx with the set command like set
$edx=0x8072bc8 and continue, my call to AddReff succeeds.

I hope this helps a bit.

I will provide with any additional information of necessary.

Kind regards,
Volker Denkhaus

-----Original Message-----
From: Nathan Sidwell [ mailto:nathan@codesourcery.com ]
Sent: Montag, 10. September 2001 17:42
To: Denkhaus, Volker
Cc: 'rodrigc@gcc.gnu.org'; gcc-bugs@gcc.gnu.org; gcc-prs@gcc.gnu.org;
nobody@gcc.gnu.org
Subject: Re: c++/4248: reinterpret_cast in template


"Denkhaus, Volker" wrote:
> 
> Hi,
> 
> it is hard to provide a sample. First of all it needs the Runtime and SDK
of
> our product (DCOM for Linux), plus the application project of our
customer.
> This would be a lot of stuff. Also I currently do not know if I am allowed
> to forward the customer stuff (source also inlcuded). Would it help to
send
> only the binaries and some of our source files (at least the file where
the
> dump occurs which is in a hedaer file that belongs to our SDK).
no. I suspect your build has become skewed, most probably a header file
has changed and some object file has not been recompiled, or
you're picking up the wrong version of a library.
ldd can tell you the libraries being used.

If you can't reduce it down to a simple test case, because whenever you
do the bug goes away, then it is incredably likely to be version skew.

> This is the code:
                    template <class Base>
                    class CComTearOffObject : public Base
                    {
                    public:
                    CComTearOffObject(void* pv)
                    {
                    ATLASSERT(m_pOwner == NULL);
                    this->m_pOwner = reinterpret_cast<CComObject<typename
Base::_OwnerClass>*>(p
                    v);
                    this->m_pOwner->AddRef();
                    }

                    The AddRef call ends up in a segmentation fault. In the
debugger I can see that the address of the
                    function AddRef which can be found in the vtable is
calculated wrong.

is m_powner the expected value?, what is its type? How is the address
calculated wrong? Is the compiler using the wrong index into the vtable,
or does the right index contain the wrong value?


nathan

-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org



More information about the Gcc-bugs mailing list