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

That highly annoying C++ unaligned trap..



.. turns out to be a bug in the glibc dynamic linker or gcc!

Using Chris's neat little program to enable SIGBUS signals, I was able to
get gdb to stop at the exact position of the fault, then asking gdb to
load the symbol table for ld-2.1.2.so to the proper load address yields a
nice backtrace.
[the fact that it was ld-2.1.2.so was determined by looking in /proc/*maps 
 and cross referencing the fault address with all loaded files, the magic
 number there is determined by adding the base address to the VMA of the 
 .text section given by objdump -h..]

So what we do is go on IRC and whine at Espy untill he recompiles glibc
with debug symbols then do repeat the above to get something like this:

g++ -Wl,-dynamic-linker,/mnt/md0/home/espy/glibc-2.1.3/alpha-linux/libc6.1/lib/ld-2.1.3.so t.cc

lully{jgg}~#./sigbus /tmp/a.out 
Starting program: /tmp/a.out 
Program received signal SIGBUS, Bus error.
0x2000000ed04 in ?? ()
(gdb) add-symbol-file /mnt/md0/home/espy/glibc-2.1.3/alpha-linux/libc6.1/lib/ld-2.1.3.so 0x00000200000050e0
(gdb) bt
#0  _dl_relocate_object (l=0x2000001e9c0, scope=0x2000001edc0, lazy=1288320, 
    consider_profiling=1288328) at ../sysdeps/alpha/dl-machine.h:456
#1  0x20000007444 in dl_main (phdr=0x0, phent=59840, user_entry=0x11ffff5a8)
    at rtld.c:1022
#2  0x20000013610 in _dl_sysdep_start (start_argptr=0x20000121e40, 
    dl_main=0x20000005ba0 <dl_main>) at ../sysdeps/generic/dl-sysdep.c:170
#3  0x20000005974 in _dl_start_final (arg=0x11ffffa90, bootstrap_map_p=0x0, 
    start_time=126400) at rtld.c:232
#4  0x200000058b0 in _dl_start (arg=0x11ffffa90) at rtld.c:192

and:
(gdb) down
#0  _dl_relocate_object (l=0x2000001e9c0, scope=0x2000001edc0,lazy=1288320, 
    consider_profiling=1288328) at ../sysdeps/alpha/dl-machine.h:456
456             *reloc_addr += map->l_addr;


*wew* 

Now at this point I start to give up - the dl_relocate_object is a
*MASSIVE* inline'd function that spans many header files and so on - the
net results is that *reloc_addr is not an aligned value. What I don't know
is if it *should* be an aligned value or not.. ie should the linker be
taking special measures to not do trap, or should the compiler not be
generating relocations like that. 

Indeed, given this information an 'objdump -R
/usr/lib/libstdc++-libc6.1-2.so.3' turns up a couple addresses like this: 

0000000000159424 RELATIVE          *ABS*

That's unaligned!!!

So.. The net result is that G++ is generating unaligned 64 bit relocation
fields in the C++ library which causes the dynamic loader to unalign trap
when it loads them.

'Fini'

Guys, I don't even know *who* to send this to who knows more about what
should be going on, let alone fixing it - but I strongly suspect it should
go to the gcc group.

Jason


Reply to: