This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
ss980406 -- SIGSEGV when attempting to determine "typeid"
- To: egcs-bugs at cygnus dot com
- Subject: ss980406 -- SIGSEGV when attempting to determine "typeid"
- From: Derek Upham <sand at celia dot serv dot net>
- Date: Sat, 11 Apr 1998 10:34:32 -0700 (PDT)
- Reply-To: sand at celia dot serv dot net
I've got an app that uses a fairly deep hierarchy of interface
classes, all of them hanging off a single "Rendered" interface class.
In one place in my code, I take pointers to objects of derived classes
and pack them into a heterogenous container for storage and eventual
removal. At the removal end, all I know is that the pointer is of
type "Rendered *" and I need to downcast it to a more specific
interface before I can do work on it. If "obj" contains the address
of a "Rendered" interface, then the line
const type_info &ti = typeid(*obj);
should give me the type of the underlying object. However, the
compiler is giving me the following i586 assembler output (according
to "objdump"):
2c9: 8b 45 e8 movl 0xffffffe8(%ebp),%eax
2cc: 8b 50 04 movl 0x4(%eax),%edx
2cf: 83 c2 04 addl $0x4,%edx
2d2: 8b 0a movl (%edx),%ecx
2d4: 89 4d c4 movl %ecx,0xffffffc4(%ebp)
2d7: 8b 4d c4 movl 0xffffffc4(%ebp),%ecx
2da: ff d1 call *%ecx
2dc: 89 45 c8 movl %eax,0xffffffc8(%ebp)
2df: 8b 4d c8 movl 0xffffffc8(%ebp),%ecx
2e2: 89 4d e4 movl %ecx,0xffffffe4(%ebp)
The segmentation fault occurs at line 0x2d2, where we are
dereferencing %edx (which has the value 0x7 according to the
debugger). Writing a toy program that does a similar "typeid" on a
pure virtual base pointer produces the following assembler output:
8048760: 8b 45 fc movl 0xfffffffc(%ebp),%eax
8048763: 8b 10 movl (%eax),%edx
8048765: 83 c2 04 addl $0x4,%edx
8048768: 8b 0a movl (%edx),%ecx
804876a: 89 4d f0 movl %ecx,0xfffffff0(%ebp)
804876d: 8b 4d f0 movl 0xfffffff0(%ebp),%ecx
8048770: ff d1 call *%ecx
8048772: 89 c6 movl %eax,%esi
8048774: 89 75 f8 movl %esi,0xfffffff8(%ebp)
The second line is the important one---we are taking the contents of
%eax as an address and extracting its contents as a long. In the bad
code, we're getting the address and bumping it by 0x4 before
dereferencing it. That means we end up getting the (long) value 0x3,
storing it in %edx, bumping *that* by 0x4, and then we're trying to
dereference it. Blammo.
The working assembler code maps to the following insns:
(note 55 54 57 ("baz.cc") 40)
(insn 57 55 59 (set (reg:SI 27)
(mem:SI (plus:SI (reg:SI 18)
(const_int -4)))) -1 (nil)
(nil))
(insn 59 57 61 (set (reg:SI 28)
(plus:SI (mem/s:SI (reg:SI 27))
(const_int 4))) -1 (nil)
(nil))
(insn 61 59 63 (set (reg:SI 29)
(mem/s:SI (reg:SI 28))) -1 (nil)
(nil))
(call_insn 63 61 65 (parallel[
(set (reg:SI 0 %eax)
(call (mem:QI (reg:SI 29))
(const_int 0)))
(set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int 0)))
] ) -1 (nil)
(nil)
(nil))
(insn 65 63 67 (set (reg:SI 26)
(reg:SI 0 %eax)) -1 (nil)
(nil))
(insn 67 65 68 (set (mem:SI (plus:SI (reg:SI 18)
(const_int -8)))
(reg:SI 26)) -1 (nil)
(nil))
while the bad assembler code maps to the following insns:
(note 186 185 188 ("pick.cc") 66)
(insn 188 186 190 (set (reg:SI 50)
(mem:SI (plus:SI (reg:SI 18)
(const_int -24)))) -1 (nil)
(nil))
(insn 190 188 192 (set (reg:SI 51)
(plus:SI (mem/s:SI (plus:SI (reg:SI 50)
(const_int 4)))
(const_int 4))) -1 (nil)
(nil))
(insn 192 190 194 (set (reg:SI 52)
(mem/s:SI (reg:SI 51))) -1 (nil)
(nil))
(call_insn 194 192 196 (parallel[
(set (reg:SI 0 %eax)
(call (mem:QI (reg:SI 52))
(const_int 0)))
(set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int 0)))
] ) -1 (nil)
(nil)
(nil))
(insn 196 194 198 (set (reg:SI 49)
(reg:SI 0 %eax)) -1 (nil)
(nil))
(insn 198 196 199 (set (mem:SI (plus:SI (reg:SI 18)
(const_int -28)))
(reg:SI 49)) -1 (nil)
(nil))
so the problem is the "(plus:SI (reg:SI 50) (const_int 4))" in
instruction 190.
If this isn't enough to track down the bug, I can send a copy of the
preprocessed file, but it's long enough (440kB) that I don't want to
do it unless necessary. This is all on an ultra-custom Linux 2.0.33
running EGCS ss980406.
Derek
--
Derek Upham
sand@celia.serv.net http://www.serv.net/~sand
"Ha! Your Leaping Tiger Kung Fu is no match for my Frightened Piglet style!"