** Description changed:
Binary package hint: gcc-4.5
I noticed this first last week when I tried to do a profile-guided build
of Firefox with gcc-4.5 in maverick, and the build was hanging in my
PPA. However, I've now recreated this locally on a normal build with
gcc-4.5 (in maverick and natty) - on i386 only.
It is hanging here:
#0 0xffffe405 in __kernel_vsyscall ()
#1 0xf7fb1169 in __lll_lock_wait () at
../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:142
#2 0xf7fac5cb in _L_lock_748 () from /lib/libpthread.so.0
#3 0xf7fac3f1 in __pthread_mutex_lock (mutex=0xf3a4fab0) at
pthread_mutex_lock.c:61
#4 0xf7ff67b3 in malloc_mutex_lock (size=<value optimized out>) at
/home/chrisccoulson/src/firefox-4.0/firefox-4.0-4.0~b8~hg20101012r55334+nobinonly/build-tree/mozilla/memory/jemalloc/jemalloc.c:1417
#5 arena_malloc_small (size=<value optimized out>) at
/home/chrisccoulson/src/firefox-4.0/firefox-4.0-4.0~b8~hg20101012r55334+nobinonly/build-tree/mozilla/memory/jemalloc/jemalloc.c:3766
#6 arena_malloc (size=<value optimized out>) at
/home/chrisccoulson/src/firefox-4.0/firefox-4.0-4.0~b8~hg20101012r55334+nobinonly/build-tree/mozilla/memory/jemalloc/jemalloc.c:3845
#7 imalloc (size=<value optimized out>) at
/home/chrisccoulson/src/firefox-4.0/firefox-4.0-4.0~b8~hg20101012r55334+nobinonly/build-tree/mozilla/memory/jemalloc/jemalloc.c:3857
#8 malloc (size=<value optimized out>) at
/home/chrisccoulson/src/firefox-4.0/firefox-4.0-4.0~b8~hg20101012r55334+nobinonly/build-tree/mozilla/memory/jemalloc/jemalloc.c:5873
#9 0xf40bf11f in __fopen_internal (filename=0xf3b49522 "/proc/filesystems",
mode=0xf3b49417 "r", is32=0) at iofopen.c:76
#10 0xf40c17bc in _IO_fopen64 (filename=0xf3b49522 "/proc/filesystems",
mode=0xf3b49417 "r") at iofopen64.c:39
#11 0xf3b3f3ca in ?? () from /lib/libselinux.so.1
#12 0xf3b48f0d in ?? () from /lib/libselinux.so.1
#13 0xf3b37158 in _init () from /lib/libselinux.so.1
#14 0xf7fdf70c in call_init (l=<value optimized out>, argc=<value optimized
out>, argv=0xffffd5e4, env=0xffffd5ec) at dl-init.c:70
#15 0xf7fdf829 in _dl_init (main_map=0xf7fee918, argc=<value optimized out>,
argv=<value optimized out>, env=0xffffd5ec) at dl-init.c:134
#16 0xf7fd188f in _dl_start_user () from /lib/ld-linux.so.2
...which is happening even before entering main()
If I break in pthread_mutex_lock, and look at the contents of the mutex,
I see:
- $61 = {__data = {__lock = -207291728, __count = 4087676744, __owner =
-207291728, __kind = 0, __nusers = 4294960128, {__spins = 36645888, __list =
{__next = 0x22f2c00}}},
- __size =
"\260\372\244\363H\377\244\363\260\372\244\363\000\000\000\000\000\344\377\377\000,/\002",
__align = -207291728}
+ $61 = {__data = {__lock = -207291728, __count = 4087676744, __owner =
-207291728, __kind = 0, __nusers = 4294960128, {__spins = 36645888, __list =
{__next = 0x22f2c00}}},
+ __size =
"\260\372\244\363H\377\244\363\260\372\244\363\000\000\000\000\000\344\377\377\000,/\002",
__align = -207291728}
...which is clearly full of garbage. Initially, I thought that perhaps
the mutex wasn't being initialized - but it is. The interesting bit is
happening here, in imalloc():
static inline void *
imalloc(size_t size)
{
- assert(size != 0);
-
- if (size <= arena_maxclass)
- return (arena_malloc(choose_arena(), size, false));
- else
- return (huge_malloc(size, false));
+ assert(size != 0);
+
+ if (size <= arena_maxclass)
+ return (arena_malloc(choose_arena(), size, false));
+ else
+ return (huge_malloc(size, false));
Note that in this case, size < arena_maxclass.
choose_arena() is an inline that returns arenas[0], which is a pointer
to a struct arena_t (note that firefox is using only a single arena). If
I break inside choose_arena(), and inspect some values, I see:
(gdb) print arenas[0]
$3 = (arena_t *) 0xf394e040
(gdb) print &arenas[0]
$4 = (arena_t **) 0xf394e000
(gdb) print arenas[0]->lock
- $5 = {__data = {__lock = 0, __count = 0, __owner = 0, __kind = 3, __nusers =
0, {__spins = 0, __list = {__next = 0x0}}}, __size = '\000' <repeats 12 times>,
"\003\000\000\000\000\000\000\000\000\000\000",
- __align = 0}
+ $5 = {__data = {__lock = 0, __count = 0, __owner = 0, __kind = 3, __nusers =
0, {__spins = 0, __list = {__next = 0x0}}}, __size = '\000' <repeats 12 times>,
"\003\000\000\000\000\000\000\000\000\000\000",
+ __align = 0}
The mutex looks correctly initialized here, and is unlocked.
If I step through a few more instructions in to arena_malloc(), then the
value of arena (which was returned by choose_arena), is something else
entirely:
(gdb) print arena
$6 = (arena_t *) 0xf3a4fab0
...this should be the same as arenas[0], which is what the C code
suggests was returned by choose_arena and passed to arena_malloc
Also:
(gdb) print arena->lock
- $8 = {__data = {__lock = -207291728, __count = 4087676744, __owner =
-207291728, __kind = 0, __nusers = 4294960128, {__spins = 36645888, __list =
{__next = 0x22f2c00}}},
- __size =
"\260\372\244\363H\377\244\363\260\372\244\363\000\000\000\000\000\344\377\377\000,/\002",
__align = -207291728}
+ $8 = {__data = {__lock = -207291728, __count = 4087676744, __owner =
-207291728, __kind = 0, __nusers = 4294960128, {__spins = 36645888, __list =
{__next = 0x22f2c00}}},
+ __size =
"\260\372\244\363H\377\244\363\260\372\244\363\000\000\000\000\000\344\377\377\000,/\002",
__align = -207291728}
So, what is happening here? If I look at the registers, I see that eax
and edi both contain this bogus pointer;
(gdb) info registers
eax 0xf3a4fab0 -207291728
ecx 0x3 3
edx 0x0 0
ebx 0xf7ffeebc -134222148
esp 0xffffd3d4 0xffffd3d4
ebp 0xffffd42c 0xffffd42c
esi 0x160 352
edi 0xf3a4fab0 -207291728
eip 0xf7ff673f 0xf7ff673f <malloc+159>
eflags 0x282 [ SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
Here is the interesting part of malloc disassembled:
- 0xf7ff66a0 <+0>: push %ebp
- 0xf7ff66a1 <+1>: mov %esp,%ebp
- 0xf7ff66a3 <+3>: sub $0x58,%esp
- 0xf7ff66a6 <+6>: mov %ebx,-0xc(%ebp)
- 0xf7ff66a9 <+9>: call 0xf7ff0917 <__i686.get_pc_thunk.bx>
- 0xf7ff66ae <+14>: add $0x880e,%ebx
- 0xf7ff66b4 <+20>: mov %esi,-0x8(%ebp)
- 0xf7ff66b7 <+23>: mov 0x8(%ebp),%esi
- 0xf7ff66ba <+26>: mov %edi,-0x4(%ebp)
- 0xf7ff66bd <+29>: cmpb $0x0,0x151c(%ebx)
- 0xf7ff66c4 <+36>: je 0xf7ff66f8 <malloc+88>
- 0xf7ff66c6 <+38>: test %esi,%esi
- 0xf7ff66c8 <+40>: mov $0x1,%eax
- 0xf7ff66cd <+45>: cmove %eax,%esi
- 0xf7ff66d0 <+48>: cmp 0x480(%ebx),%esi
- 0xf7ff66d6 <+54>: jbe 0xf7ff6720 <malloc+128>
- 0xf7ff66d8 <+56>: mov %esi,%eax
- 0xf7ff66da <+58>: call 0xf7ff5980 <huge_malloc>
- 0xf7ff66df <+63>: mov %eax,%esi
- 0xf7ff66e1 <+65>: test %esi,%esi
- 0xf7ff66e3 <+67>: je 0xf7ff6701 <malloc+97>
- 0xf7ff66e5 <+69>: mov %esi,%eax
- 0xf7ff66e7 <+71>: mov -0xc(%ebp),%ebx
- 0xf7ff66ea <+74>: mov -0x8(%ebp),%esi
- 0xf7ff66ed <+77>: mov -0x4(%ebp),%edi
- 0xf7ff66f0 <+80>: mov %ebp,%esp
- 0xf7ff66f2 <+82>: pop %ebp
- 0xf7ff66f3 <+83>: ret
- 0xf7ff66f4 <+84>: lea 0x0(%esi,%eiz,1),%esi
- 0xf7ff66f8 <+88>: call 0xf7ff45c0 <malloc_init_hard>
- 0xf7ff66fd <+93>: test %al,%al
- 0xf7ff66ff <+95>: je 0xf7ff66c6 <malloc+38>
- 0xf7ff6701 <+97>: call 0xf7ff0530 <__errno_locat...@plt>
- 0xf7ff6706 <+102>: xor %esi,%esi
- 0xf7ff6708 <+104>: movl $0xc,(%eax)
- 0xf7ff670e <+110>: mov %esi,%eax
- 0xf7ff6710 <+112>: mov -0xc(%ebp),%ebx
- 0xf7ff6713 <+115>: mov -0x8(%ebp),%esi
- 0xf7ff6716 <+118>: mov -0x4(%ebp),%edi
- 0xf7ff6719 <+121>: mov %ebp,%esp
- 0xf7ff671b <+123>: pop %ebp
- 0xf7ff671c <+124>: ret
- 0xf7ff671d <+125>: lea 0x0(%esi),%esi
- 0xf7ff6720 <+128>: mov %gs:0x0,%eax
- 0xf7ff6726 <+134>: nop
- 0xf7ff6727 <+135>: lea 0x0(%esi,%eiz,1),%esi
- 0xf7ff672b <+139>: lea 0x0,%edx
- 0xf7ff6731 <+145>: mov %edx,-0x1c(%ebp)
- 0xf7ff6734 <+148>: mov (%edx,%eax,1),%edi
- 0xf7ff6737 <+151>: test %edi,%edi
- 0xf7ff6739 <+153>: je 0xf7ff6960 <malloc+704>
- 0xf7ff673f <+159>: cmp 0x14f8(%ebx),%esi
- 0xf7ff6745 <+165>: ja 0xf7ff68a0 <malloc+512>
- 0xf7ff674b <+171>: cmp 0x14f0(%ebx),%esi
- 0xf7ff6751 <+177>: jae 0xf7ff6858 <malloc+440>
- 0xf7ff6757 <+183>: sub $0x1,%esi
- 0xf7ff675a <+186>: mov %esi,%edx
- 0xf7ff675c <+188>: shr %edx
- 0xf7ff675e <+190>: or %esi,%edx
- 0xf7ff6760 <+192>: mov %edx,%eax
- 0xf7ff6762 <+194>: shr $0x2,%eax
- 0xf7ff6765 <+197>: or %edx,%eax
- 0xf7ff6767 <+199>: mov %eax,%edx
- 0xf7ff6769 <+201>: shr $0x4,%edx
- 0xf7ff676c <+204>: or %eax,%edx
- 0xf7ff676e <+206>: mov %edx,%eax
- 0xf7ff6770 <+208>: shr $0x8,%eax
- 0xf7ff6773 <+211>: or %edx,%eax
- 0xf7ff6775 <+213>: mov $0xffffffff,%edx
- 0xf7ff677a <+218>: mov %eax,%esi
- 0xf7ff677c <+220>: shr $0x10,%esi
- 0xf7ff677f <+223>: or %eax,%esi
- 0xf7ff6781 <+225>: add $0x1,%esi
- 0xf7ff6784 <+228>: mov %esi,%eax
- 0xf7ff6786 <+230>: shr $0x2,%eax
- 0xf7ff6789 <+233>: bsf %eax,%eax
- 0xf7ff678c <+236>: cmove %edx,%eax
- 0xf7ff678f <+239>: cmp $0x1,%esi
- 0xf7ff6792 <+242>: lea 0x9(%eax,%eax,8),%eax
- 0xf7ff6796 <+246>: lea 0x94(%edi,%eax,8),%eax
- 0xf7ff679d <+253>: mov %eax,-0x1c(%ebp)
- 0xf7ff67a0 <+256>: mov $0x2,%eax
- 0xf7ff67a5 <+261>: cmova %esi,%eax
- 0xf7ff67a8 <+264>: mov %eax,-0x20(%ebp)
- 0xf7ff67ab <+267>: mov %edi,(%esp)
- 0xf7ff67ae <+270>: call 0xf7ff0620 <pthread_mutex_l...@plt>
+ 0xf7ff66a0 <+0>: push %ebp
+ 0xf7ff66a1 <+1>: mov %esp,%ebp
+ 0xf7ff66a3 <+3>: sub $0x58,%esp
+ 0xf7ff66a6 <+6>: mov %ebx,-0xc(%ebp)
+ 0xf7ff66a9 <+9>: call 0xf7ff0917 <__i686.get_pc_thunk.bx>
+ 0xf7ff66ae <+14>: add $0x880e,%ebx
+ 0xf7ff66b4 <+20>: mov %esi,-0x8(%ebp)
+ 0xf7ff66b7 <+23>: mov 0x8(%ebp),%esi
+ 0xf7ff66ba <+26>: mov %edi,-0x4(%ebp)
+ 0xf7ff66bd <+29>: cmpb $0x0,0x151c(%ebx)
+ 0xf7ff66c4 <+36>: je 0xf7ff66f8 <malloc+88>
+ 0xf7ff66c6 <+38>: test %esi,%esi
+ 0xf7ff66c8 <+40>: mov $0x1,%eax
+ 0xf7ff66cd <+45>: cmove %eax,%esi
+ 0xf7ff66d0 <+48>: cmp 0x480(%ebx),%esi
+ 0xf7ff66d6 <+54>: jbe 0xf7ff6720 <malloc+128>
+ 0xf7ff66d8 <+56>: mov %esi,%eax
+ 0xf7ff66da <+58>: call 0xf7ff5980 <huge_malloc>
+ 0xf7ff66df <+63>: mov %eax,%esi
+ 0xf7ff66e1 <+65>: test %esi,%esi
+ 0xf7ff66e3 <+67>: je 0xf7ff6701 <malloc+97>
+ 0xf7ff66e5 <+69>: mov %esi,%eax
+ 0xf7ff66e7 <+71>: mov -0xc(%ebp),%ebx
+ 0xf7ff66ea <+74>: mov -0x8(%ebp),%esi
+ 0xf7ff66ed <+77>: mov -0x4(%ebp),%edi
+ 0xf7ff66f0 <+80>: mov %ebp,%esp
+ 0xf7ff66f2 <+82>: pop %ebp
+ 0xf7ff66f3 <+83>: ret
+ 0xf7ff66f4 <+84>: lea 0x0(%esi,%eiz,1),%esi
+ 0xf7ff66f8 <+88>: call 0xf7ff45c0 <malloc_init_hard>
+ 0xf7ff66fd <+93>: test %al,%al
+ 0xf7ff66ff <+95>: je 0xf7ff66c6 <malloc+38>
+ 0xf7ff6701 <+97>: call 0xf7ff0530 <__errno_locat...@plt>
+ 0xf7ff6706 <+102>: xor %esi,%esi
+ 0xf7ff6708 <+104>: movl $0xc,(%eax)
+ 0xf7ff670e <+110>: mov %esi,%eax
+ 0xf7ff6710 <+112>: mov -0xc(%ebp),%ebx
+ 0xf7ff6713 <+115>: mov -0x8(%ebp),%esi
+ 0xf7ff6716 <+118>: mov -0x4(%ebp),%edi
+ 0xf7ff6719 <+121>: mov %ebp,%esp
+ 0xf7ff671b <+123>: pop %ebp
+ 0xf7ff671c <+124>: ret
+ 0xf7ff671d <+125>: lea 0x0(%esi),%esi
+ 0xf7ff6720 <+128>: mov %gs:0x0,%eax
+ 0xf7ff6726 <+134>: nop
+ 0xf7ff6727 <+135>: lea 0x0(%esi,%eiz,1),%esi
+ 0xf7ff672b <+139>: lea 0x0,%edx
+ 0xf7ff6731 <+145>: mov %edx,-0x1c(%ebp)
+ 0xf7ff6734 <+148>: mov (%edx,%eax,1),%edi
+ 0xf7ff6737 <+151>: test %edi,%edi
+ 0xf7ff6739 <+153>: je 0xf7ff6960 <malloc+704>
+ 0xf7ff673f <+159>: cmp 0x14f8(%ebx),%esi
+ 0xf7ff6745 <+165>: ja 0xf7ff68a0 <malloc+512>
+ 0xf7ff674b <+171>: cmp 0x14f0(%ebx),%esi
+ 0xf7ff6751 <+177>: jae 0xf7ff6858 <malloc+440>
+ 0xf7ff6757 <+183>: sub $0x1,%esi
+ 0xf7ff675a <+186>: mov %esi,%edx
+ 0xf7ff675c <+188>: shr %edx
+ 0xf7ff675e <+190>: or %esi,%edx
+ 0xf7ff6760 <+192>: mov %edx,%eax
+ 0xf7ff6762 <+194>: shr $0x2,%eax
+ 0xf7ff6765 <+197>: or %edx,%eax
+ 0xf7ff6767 <+199>: mov %eax,%edx
+ 0xf7ff6769 <+201>: shr $0x4,%edx
+ 0xf7ff676c <+204>: or %eax,%edx
+ 0xf7ff676e <+206>: mov %edx,%eax
+ 0xf7ff6770 <+208>: shr $0x8,%eax
+ 0xf7ff6773 <+211>: or %edx,%eax
+ 0xf7ff6775 <+213>: mov $0xffffffff,%edx
+ 0xf7ff677a <+218>: mov %eax,%esi
+ 0xf7ff677c <+220>: shr $0x10,%esi
+ 0xf7ff677f <+223>: or %eax,%esi
+ 0xf7ff6781 <+225>: add $0x1,%esi
+ 0xf7ff6784 <+228>: mov %esi,%eax
+ 0xf7ff6786 <+230>: shr $0x2,%eax
+ 0xf7ff6789 <+233>: bsf %eax,%eax
+ 0xf7ff678c <+236>: cmove %edx,%eax
+ 0xf7ff678f <+239>: cmp $0x1,%esi
+ 0xf7ff6792 <+242>: lea 0x9(%eax,%eax,8),%eax
+ 0xf7ff6796 <+246>: lea 0x94(%edi,%eax,8),%eax
+ 0xf7ff679d <+253>: mov %eax,-0x1c(%ebp)
+ 0xf7ff67a0 <+256>: mov $0x2,%eax
+ 0xf7ff67a5 <+261>: cmova %esi,%eax
+ 0xf7ff67a8 <+264>: mov %eax,-0x20(%ebp)
+ 0xf7ff67ab <+267>: mov %edi,(%esp)
+ 0xf7ff67ae <+270>: call 0xf7ff0620 <pthread_mutex_l...@plt>
So, the contents of edi (which seems to contain our pointer to the bogus
arena_t) is what is passed to pthread_mutex_lock (which makes sense -
the lock is the first entry in struct arena_t).
From 0xf7ff6720 <+128> is happening inside choose_arena(). I'm not sure
what the following instruction sequence is doing, but it's loading the
- wrong value in to edi, which is then passed to put on the stack and
- passed to pthread_mutex_lock:
-
- 0xf7ff6720 <+128>: mov %gs:0x0,%eax
- 0xf7ff672b <+139>: lea 0x0,%edx
- 0xf7ff6734 <+148>: mov (%edx,%eax,1),%edi
+ wrong value in to edi, which is then put on the stack and passed to
+ pthread_mutex_lock:
+
+ 0xf7ff6720 <+128>: mov %gs:0x0,%eax
+ 0xf7ff672b <+139>: lea 0x0,%edx
+ 0xf7ff6734 <+148>: mov (%edx,%eax,1),%edi
I would have thought that this sequence would be loading the contents of
0xf394e000 in to the edi register, which is where the valid pointer is
currently stored
I'm not sure what the problem is, but I can't see anything obviously
wrong with jemalloc, and this worked just fine in gcc-4.4
--
Firefox built with gcc-4.5 is a non-starter on i386
https://bugs.launchpad.net/bugs/663294
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs