Faculty of Information Technology
Software Engineering Group

#94 closed defect (fixed)

32bit Linux build crashes when compiled using GCC 5.x

Reported by: Jan Vrany Owned by:
Priority: major Milestone:
Component: stc Keywords:
Cc: Also affects CVS HEAD (eXept version): no

Description

...in SequenceableCollection >> #hash. Stack trace looks like:

#0  0xf7788d49 in __kernel_vsyscall ()
#1  0xf2f27116 in kill () at ../sysdeps/unix/syscall-template.S:84
#2  0xf33377eb in __stop () at backtrace.c:1737
#3  0xf3368a32 in __signalSEGVInterrupt (sigNo=11, gs=-1018804, fs=-1018676, es=11, ds=0, edi=1, esi=1249, ebp=-148964105, esp=1361191728, ebx=-1018696, edx=-
1018832, ecx=-146501941, eax=-1018680, trapno=268435977, err=-1018432, eip=268468745, cs=-1018588, eflags=268435977, esp_at_signal=-1018616, ss=1343512652, i3
87=1361191408, oldMask=1343512712, cr2=-1018704) at interrupt.c:4062
#4  <signal handler called>
#5  0xf6f47780 in __MKLARGEINTov_a@plt () from /home/jv/Private/Projects/SmalltalkX/sources/gcc5_x32_lin/build/stx/projects/smalltalk/libstx_libbasic.so
#6  0xf71bfc09 in __x___M_105_SequenceableCollection__hash (self=0xf1edb05c, __selector=0x200029e4, __searchClass=0x0, __pilc=<optimized out>) at ./Sequenceab
leCollection.c:12363
#7  0xf71efd3c in __x___M_41_Set__hashFor_ (self=0xf2484670, __selector=0x200352b4, __searchClass=0x0, __pilc=<optimized out>, aKey=0xf1edb05c) at ./Set.c:480

Observation:

64bit build using GCC 5.x is fine. The hash method uses some
SmallInteger? addition, ending up calling __ADD_IO_IO() macro from cpu_i386. That macro contains inlined assembly call __MKLARGEINTov_a@PLT which is the function that causes SEGFAULT.

Change History (3)

comment:1 Changed 18 months ago by Jan Vrany

Observation:

  • When whole system is compiled with -O optimization, it crashes in @PLT as descibed above.
  • When whole system is compiled with -O2 optimization, then STX:LIBJAVA tests crash in the VM when allocating stack page (double-free kind of error. VM aborted by GLIBC)
  • When classes are compiled with -O2 and librun with -O then it appears to work.

Too bad. It still might be a good idea to use intrinsics to avoid the assembly since it seems to be coded on assumptions that do not hold (are undefined?)

comment:2 Changed 18 months ago by Jan Vrany

More details about the crash with -O:

(gdb) bt 10
#0  0xf7714d49 in __kernel_vsyscall ()
#1  0xf2df1116 in kill () at ../sysdeps/unix/syscall-template.S:84
#2  0xf32017eb in __stop () at backtrace.c:1737
#3  0xf3232a32 in __signalSEGVInterrupt (sigNo=11, gs=-7272116, fs=-7271988, es=11, ds=0, edi=1, esi=1249, ebp=-146977093, esp=-7272008, ebx=268435977, edx=-7271760, ecx=268468745, eax=-7271916, 
    trapno=268435977, err=-7271944, eip=1343512652, cs=1361191408, eflags=1343512712, esp_at_signal=-7272032, ss=-146977093, i387=-7272016, oldMask=-213884096, cr2=-7271864) at interrupt.c:4062
#4  <signal handler called>
#5  0xf6ed3770 in __MKLARGEINTov_a@plt () from /home/jv/Private/Projects/SmalltalkX/sources/gcc5_x32_lin/build/stx/projects/smalltalk/libstx_libbasic.so
#6  0xf714bbf9 in __x___M_105_SequenceableCollection__hash (self=0xf1da4f94, __selector=0x200029e4, __searchClass=0x0, __pilc=<optimized out>) at ./SequenceableCollection.c:12363
#7  0xf717bd2c in __x___M_41_Set__hashFor_ (self=0xf234e5a8, __selector=0x200352b4, __searchClass=0x0, __pilc=<optimized out>, aKey=0xf1da4f94) at ./Set.c:4803
#8  0xf717be4c in __x___M_42_Set__initialIndexForKey_ (self=0xf234e5a8, __selector=0x20035260, __searchClass=0x0, __pilc=<optimized out>, aKey=0xf1da4f94) at ./Set.c:4905
#9  0xf717b76c in __x___M_39_Set__findKeyOrNil_ (self=0xf234e5a8, __selector=0x200351bc, __searchClass=0x0, __pilc=<optimized out>, key=0xf1da4f94) at ./Set.c:4529
(More stack frames follow...)
(gdb) f 5
#5  0xf6ed3770 in __MKLARGEINTov_a@plt () from /home/jv/Private/Projects/SmalltalkX/sources/gcc5_x32_lin/build/stx/projects/smalltalk/libstx_libbasic.so
(gdb) disas
Dump of assembler code for function __MKLARGEINTov_a@plt:
=> 0xf6ed3770 <+0>:	jmp    *0x4e0(%ebx)
   0xf6ed3776 <+6>:	push   $0x9a8
   0xf6ed377b <+11>:	jmp    0xf6ed2410
End of assembler dump.
(gdb) info registers 
eax            0xaab76c61	-1430819743
ecx            0xf1da4f90	-237351024
edx            0x367ebea1	914276001
ebx            0x1	1
esp            0xff910e0c	0xff910e0c
ebp            0xff910e98	0xff910e98
esi            0xf762d314	-144518380
edi            0xf7630e60	-144503200
eip            0xf6ed3770	0xf6ed3770 <__MKLARGEINTov_a@plt>
eflags         0x200296	[ PF AF SF IF ID ]
cs             0x23	35
ss             0x2b	43
ds             0x2b	43
es             0x2b	43
fs             0x0	0
gs             0x63	99

(gdb) f 6
#6  0xf714bbf9 in __x___M_105_SequenceableCollection__hash (self=0xf1da4f94, __selector=0x200029e4, __searchClass=0x0, __pilc=<optimized out>) at ./SequenceableCollection.c:12363
12363	./SequenceableCollection.c: No such file or directory.
(gdb) disas $pc - 100, $pc + 100
Dump of assembler code from 0xf714bb95 to 0xf714bc5d:
   0xf714bb95 <__x___M_105_SequenceableCollection__hash+522>:	lahf   
   0xf714bb96 <__x___M_105_SequenceableCollection__hash+523>:	rorl   $0x6,0x74cb84f3(%ecx)
   0xf714bb9d <__x___M_105_SequenceableCollection__hash+530>:	mov    0x8(%eax,%edx,4),%eax
   0xf714bba1 <__x___M_105_SequenceableCollection__hash+534>:	jmp    0xf714bbc5 <__x___M_105_SequenceableCollection__hash+570>
   0xf714bba3 <__x___M_105_SequenceableCollection__hash+536>:	mov    -0x14(%ebp),%edx
   0xf714bba6 <__x___M_105_SequenceableCollection__hash+539>:	sub    $0xc,%esp
   0xf714bba9 <__x___M_105_SequenceableCollection__hash+542>:	push   %edx
   0xf714bbaa <__x___M_105_SequenceableCollection__hash+543>:	mov    -0x7c(%ebp),%esi
   0xf714bbad <__x___M_105_SequenceableCollection__hash+546>:	lea    0x6b258(%esi),%edx
   0xf714bbb3 <__x___M_105_SequenceableCollection__hash+552>:	push   %edx
   0xf714bbb4 <__x___M_105_SequenceableCollection__hash+553>:	push   $0x0
   0xf714bbb6 <__x___M_105_SequenceableCollection__hash+555>:	push   $0x20000334
   0xf714bbbb <__x___M_105_SequenceableCollection__hash+560>:	push   %eax
   0xf714bbbc <__x___M_105_SequenceableCollection__hash+561>:	call   *0x6b258(%esi)
   0xf714bbc2 <__x___M_105_SequenceableCollection__hash+567>:	add    $0x20,%esp
   0xf714bbc5 <__x___M_105_SequenceableCollection__hash+570>:	mov    -0x7c(%ebp),%esi
   0xf714bbc8 <__x___M_105_SequenceableCollection__hash+573>:	lea    0x6b730(%esi),%edx
   0xf714bbce <__x___M_105_SequenceableCollection__hash+579>:	push   %edx
   0xf714bbcf <__x___M_105_SequenceableCollection__hash+580>:	push   $0x0
   0xf714bbd1 <__x___M_105_SequenceableCollection__hash+582>:	push   $0x200029e4
   0xf714bbd6 <__x___M_105_SequenceableCollection__hash+587>:	push   %eax
   0xf714bbd7 <__x___M_105_SequenceableCollection__hash+588>:	call   *0x6b730(%esi)
   0xf714bbdd <__x___M_105_SequenceableCollection__hash+594>:	mov    %eax,%edx
   0xf714bbdf <__x___M_105_SequenceableCollection__hash+596>:	add    $0x10,%esp
   0xf714bbe2 <__x___M_105_SequenceableCollection__hash+599>:	mov    -0xc(%ebp),%eax
   0xf714bbe5 <__x___M_105_SequenceableCollection__hash+602>:	and    $0x1,%eax
   0xf714bbe8 <__x___M_105_SequenceableCollection__hash+605>:	test   %eax,%edx
   0xf714bbea <__x___M_105_SequenceableCollection__hash+607>:	je     0xf714bbfb <__x___M_105_SequenceableCollection__hash+624>
   0xf714bbec <__x___M_105_SequenceableCollection__hash+609>:	mov    -0xc(%ebp),%eax
   0xf714bbef <__x___M_105_SequenceableCollection__hash+612>:	dec    %eax
   0xf714bbf0 <__x___M_105_SequenceableCollection__hash+613>:	add    %edx,%eax
   0xf714bbf2 <__x___M_105_SequenceableCollection__hash+615>:	jno    0xf714bbf9 <__x___M_105_SequenceableCollection__hash+622>
   0xf714bbf4 <__x___M_105_SequenceableCollection__hash+617>:	call   0xf6ed3770 <__MKLARGEINTov_a@plt>
=> 0xf714bbf9 <__x___M_105_SequenceableCollection__hash+622>:	jmp    0xf714bc1d <__x___M_105_SequenceableCollection__hash+658>
   0xf714bbfb <__x___M_105_SequenceableCollection__hash+624>:	mov    -0xc(%ebp),%eax
   0xf714bbfe <__x___M_105_SequenceableCollection__hash+627>:	sub    $0xc,%esp
   0xf714bc01 <__x___M_105_SequenceableCollection__hash+630>:	push   %edx
   0xf714bc02 <__x___M_105_SequenceableCollection__hash+631>:	mov    -0x7c(%ebp),%ecx
   0xf714bc05 <__x___M_105_SequenceableCollection__hash+634>:	lea    0x6b744(%ecx),%edx
   0xf714bc0b <__x___M_105_SequenceableCollection__hash+640>:	push   %edx
   0xf714bc0c <__x___M_105_SequenceableCollection__hash+641>:	push   $0x0
   0xf714bc0e <__x___M_105_SequenceableCollection__hash+643>:	push   $0x20003abc
   0xf714bc13 <__x___M_105_SequenceableCollection__hash+648>:	push   %eax
   0xf714bc14 <__x___M_105_SequenceableCollection__hash+649>:	call   *0x6b744(%ecx)
   0xf714bc1a <__x___M_105_SequenceableCollection__hash+655>:	add    $0x20,%esp
   0xf714bc1d <__x___M_105_SequenceableCollection__hash+658>:	mov    %eax,-0x10(%ebp)
   0xf714bc20 <__x___M_105_SequenceableCollection__hash+661>:	mov    -0x10(%ebp),%eax
   0xf714bc23 <__x___M_105_SequenceableCollection__hash+664>:	test   $0x1,%al
   0xf714bc25 <__x___M_105_SequenceableCollection__hash+666>:	je     0xf714bc31 <__x___M_105_SequenceableCollection__hash+678>
   0xf714bc27 <__x___M_105_SequenceableCollection__hash+668>:	mov    -0x10(%ebp),%eax
   0xf714bc2a <__x___M_105_SequenceableCollection__hash+671>:	and    $0x3ffffff,%eax
   0xf714bc2f <__x___M_105_SequenceableCollection__hash+676>:	jmp    0xf714bc57 <__x___M_105_SequenceableCollection__hash+716>
---Type <return> to continue, or q <return> to quit---
   0xf714bc31 <__x___M_105_SequenceableCollection__hash+678>:	mov    -0x10(%ebp),%eax
   0xf714bc34 <__x___M_105_SequenceableCollection__hash+681>:	sub    $0xc,%esp
   0xf714bc37 <__x___M_105_SequenceableCollection__hash+684>:	push   $0x3ffffff
   0xf714bc3c <__x___M_105_SequenceableCollection__hash+689>:	mov    -0x7c(%ebp),%esi
   0xf714bc3f <__x___M_105_SequenceableCollection__hash+692>:	lea    0x6b758(%esi),%edx
   0xf714bc45 <__x___M_105_SequenceableCollection__hash+698>:	push   %edx
   0xf714bc46 <__x___M_105_SequenceableCollection__hash+699>:	push   $0x0
   0xf714bc48 <__x___M_105_SequenceableCollection__hash+701>:	push   $0x200115b4
   0xf714bc4d <__x___M_105_SequenceableCollection__hash+706>:	push   %eax
   0xf714bc4e <__x___M_105_SequenceableCollection__hash+707>:	call   *0x6b758(%esi)
   0xf714bc54 <__x___M_105_SequenceableCollection__hash+713>:	add    $0x20,%esp
   0xf714bc57 <__x___M_105_SequenceableCollection__hash+716>:	mov    %eax,-0x10(%ebp)
   0xf714bc5a <__x___M_105_SequenceableCollection__hash+719>:	mov    -0x10(%ebp),%eax
End of assembler dump.
(gdb)

comment:3 Changed 17 months ago by Jan Vrany

Resolution: fixed
Status: newclosed

Fixed in following commits in stc:

changeset: 8284ef5c598f
user: Jan Vrany
date: Mon May 30 11:13:43 2016 +0100
files: cpu_i386.h cpu_x86_64.h
description:
Issue #94: Disable hand-tuned inline assembly for SmallInteger? arightmetics on GCC 5.x.x

...to avoid crash in SequenceableCollection>>hash. The problem is that when @PLT is called,
some registers have wrong values leading to a SEGFAULT when @PLT function does an indirect call.
The exact reason is not known, but likely the GCC 5.x.x generates a slightly different code
then the inline assembly expects.

changeset: 967408bf6279
user: Jan Vrany
date: Tue Jun 21 00:34:59 2016 +0100
files: stcIntern.h
description:
Issue #94: Use GCC/Clang intrinsics for SmallInteger? arithmetics

...rather than inline assembly. Beside the fact the inline assembly
does not work under GCC 5.x.x, intrincis have the advangage to work
on all platforms (on which GCC 5.x.x/Clang is used) and potentially
allows for better register allocation since it does not impose
constraints on registers. On the other hand the generated code is not
as compact as hand-written assembly.

Anyeays, code using intrinsics works on GCC 5.x.x and gives a slightly
better performance than plain-C version. The assembly version - when
it works correctly - is maybe little faster, but the performance gain
does not pay off for maintenance pain.

changeset: 55bfb6cc54e8
user: Jan Vrany
date: Tue Jun 21 16:37:36 2016 +0100
files: cpu_i386.h cpu_x86_64.h
description:
Issue #94: Finally, nuked all SmallInteger? arithmetic macros for i386 and x86_64 using inline assembly

...as those macros are not used any more - superseded by code using GCC/Clang intrinsics.
Even though the code was nice, there's no point keeping dead and broken code.
Less code, less pain.

Note: See TracTickets for help on using tickets.