Member offset differs between constructor and destructor (g++)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Running Fedora Core 10 x86_64, g++ 4.3.2 and 4.3.3.

I have some classes (maximally simplified)

ip4_service : public boost::totally_ordered<ip4_service> {
  ip_protocol _proto;
  boost::variant<icmp, ip_port> _value;
}

ip_protocol { int _value; }

My code is crashing on uses of ip4_service. To isolate the problem I added this line

{ ip4_service tmp; }

This generates a crash. Stepping in to it, I get the following machine code

Dump of assembler code for function ip4_service:
0x000000000055b95c <ip4_service+0>:	push   %rbp
0x000000000055b95d <ip4_service+1>:	mov    %rsp,%rbp
0x000000000055b960 <ip4_service+4>:	sub    $0x10,%rsp
0x000000000055b964 <ip4_service+8>:	mov    %rdi,-0x8(%rbp)
0x000000000055b968 <ip4_service+12>:	mov    -0x8(%rbp),%rdi
0x000000000055b96c <ip4_service+16>:	callq  0x482126 <totally_ordered>
0x000000000055b971 <ip4_service+21>:	mov    -0x8(%rbp),%rdi
0x000000000055b975 <ip4_service+25>:	callq  0x55b5ac <ip_protocol>
0x000000000055b97a <ip4_service+30>:	mov    -0x8(%rbp),%rax
0x000000000055b97e <ip4_service+34>:	lea    0x4(%rax),%rdi
0x000000000055b982 <ip4_service+38>:	callq  0x55b8a6 <variant>
0x000000000055b987 <ip4_service+43>:	leaveq 
0x000000000055b988 <ip4_service+44>:	retq   
End of assembler dump.

Dump of assembler code for function ~ip4_service:
0x0000000000486102 <~ip4_service+0>:	push   %rbp
0x0000000000486103 <~ip4_service+1>:	mov    %rsp,%rbp
0x0000000000486106 <~ip4_service+4>:	sub    $0x10,%rsp
0x000000000048610a <~ip4_service+8>:	mov    %rdi,-0x8(%rbp)
0x000000000048610e <~ip4_service+12>:	mov    -0x8(%rbp),%rax
0x0000000000486112 <~ip4_service+16>:	lea    0x8(%rax),%rdi
0x0000000000486116 <~ip4_service+20>:	callq  0x4860de <~variant>
0x000000000048611b <~ip4_service+25>:	leaveq 
0x000000000048611c <~ip4_service+26>:	retq   
End of assembler dump.

The interesting bit is that in the ip4_service constructor, the variant member is at offset 4. But in the destructor, it is at offset 8. This causes the variant destructor to do Bad Things.

I have tried for a couple of days to simplify this to no avail. The overall executable is a project with a number of statically linked libraries. This only happens in one library. Use of ip4_service in other libraries compiles and runs without error. I have checked the compile flags very carefully and the only difference is that some libraries use -fPIC. The only flags I use are -I, -Wall, -ggdb3. Nothing classes use __attribute__. As far as I can tell, every translation unit that uses the constructor also uses the destructor.

Observing that the constructor and destructor function addresses were quite different, I tried putting them in explictly but inline. That didn't make any difference. So I move the implementations to the .cpp file. No more crashes. So, somehow, the two functions were being generated in two different places with different memory layouts. I cannot see how that could happen because the places that use this class construct and destruct instances. In this case it is destructor that is wrong, in the working version the variant member is at offset 4.

Has anyone seen anything like this before? Any clues as to where to look for the problem? Does this sound like a known compiler bug?


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux