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

gcc-10: regression in 10.2.0-9 causes segmentation fault in vlc



Control: reassign -1 gcc-10 10.2.0-9
Control: retitle -1 gcc-10: regression in 10.2.0-9 causes segmentation fault in vlc
Control: affects -1 vlc
Control: severity -1 serious

Hi,

the vlc crash is caused by a compiler regression introduced in gcc-10 version 10.2.0-9, which was used to compile vlc 3.0.11.1-2.

With the buggy compiler, the function picture_Clone from src/misc/picture.c gets miscompiled, in particular the following loop:
https://salsa.debian.org/multimedia-team/vlc/-/blob/1d01d5e56132e9917c53c5a97f10d42426081512/src/misc/picture.c#L401-405
    for (int i = 0; i < picture->i_planes; i++) {
        res.p[i].p_pixels = picture->p[i].p_pixels;
        res.p[i].i_lines = picture->p[i].i_lines;
        res.p[i].i_pitch = picture->p[i].i_pitch;
    }

A correctly working gcc simply unrolls the loop:
$ objdump --disassemble=picture_Clone /usr/lib/x86_64-linux-gnu/libvlccore.so.9.0.0 | head -n 62 | tail -n 30
   a8c04:	85 c9                	test   %ecx,%ecx
   a8c06:	0f 8e 8c 00 00 00    	jle    a8c98 <picture_Clone@@Base+0xe8>
   a8c0c:	48 8b b7 b0 00 00 00 	mov    0xb0(%rdi),%rsi
   a8c13:	48 8b bf b8 00 00 00 	mov    0xb8(%rdi),%rdi
   a8c1a:	48 89 74 24 10       	mov    %rsi,0x10(%rsp)
   a8c1f:	48 89 7c 24 18       	mov    %rdi,0x18(%rsp)
   a8c24:	83 f9 01             	cmp    $0x1,%ecx
   a8c27:	74 6f                	je     a8c98 <picture_Clone@@Base+0xe8>
   a8c29:	4c 8b 83 d0 00 00 00 	mov    0xd0(%rbx),%r8
   a8c30:	4c 8b 8b d8 00 00 00 	mov    0xd8(%rbx),%r9
   a8c37:	4c 89 44 24 20       	mov    %r8,0x20(%rsp)
   a8c3c:	4c 89 4c 24 28       	mov    %r9,0x28(%rsp)
   a8c41:	83 f9 02             	cmp    $0x2,%ecx
   a8c44:	74 52                	je     a8c98 <picture_Clone@@Base+0xe8>
   a8c46:	4c 8b 93 f0 00 00 00 	mov    0xf0(%rbx),%r10
   a8c4d:	4c 8b 9b f8 00 00 00 	mov    0xf8(%rbx),%r11
   a8c54:	4c 89 54 24 30       	mov    %r10,0x30(%rsp)
   a8c59:	4c 89 5c 24 38       	mov    %r11,0x38(%rsp)
   a8c5e:	83 f9 03             	cmp    $0x3,%ecx
   a8c61:	74 35                	je     a8c98 <picture_Clone@@Base+0xe8>
   a8c63:	4c 8b a3 10 01 00 00 	mov    0x110(%rbx),%r12
   a8c6a:	48 8b 83 18 01 00 00 	mov    0x118(%rbx),%rax
   a8c71:	4c 89 64 24 40       	mov    %r12,0x40(%rsp)
   a8c76:	48 89 44 24 48       	mov    %rax,0x48(%rsp)
   a8c7b:	83 f9 04             	cmp    $0x4,%ecx
   a8c7e:	74 18                	je     a8c98 <picture_Clone@@Base+0xe8>
   a8c80:	48 8b 93 30 01 00 00 	mov    0x130(%rbx),%rdx
   a8c87:	48 8b 8b 38 01 00 00 	mov    0x138(%rbx),%rcx
   a8c8e:	48 89 54 24 50       	mov    %rdx,0x50(%rsp)
   a8c93:	48 89 4c 24 58       	mov    %rcx,0x58(%rsp)


The buggy gcc does something strange instead:
$ objdump --disassemble=picture_Clone /usr/lib/x86_64-linux-gnu/libvlccore.so.9.0.0 | head -n 80 | tail -n 48
   a8c04:	85 f6                	test   %esi,%esi
   a8c06:	0f 8e ca 00 00 00    	jle    a8cd6 <picture_Clone@@Base+0x126>
   a8c0c:	8d 46 ff             	lea    -0x1(%rsi),%eax
   a8c0f:	83 f8 01             	cmp    $0x1,%eax
   a8c12:	0f 86 18 01 00 00    	jbe    a8d30 <picture_Clone@@Base+0x180>
   a8c18:	48 8b bf b8 00 00 00 	mov    0xb8(%rdi),%rdi
   a8c1f:	48 8b 8b b0 00 00 00 	mov    0xb0(%rbx),%rcx
   a8c26:	41 89 c1             	mov    %eax,%r9d
   a8c29:	4c 8b 83 d8 00 00 00 	mov    0xd8(%rbx),%r8
   a8c30:	41 d1 e9             	shr    %r9d
   a8c33:	48 89 4c 24 10       	mov    %rcx,0x10(%rsp)
   a8c38:	48 89 7c 24 20       	mov    %rdi,0x20(%rsp)
   a8c3d:	48 89 7c 24 18       	mov    %rdi,0x18(%rsp)
   a8c42:	4c 89 44 24 28       	mov    %r8,0x28(%rsp)
   a8c47:	41 83 f9 01          	cmp    $0x1,%r9d
   a8c4b:	74 30                	je     a8c7d <picture_Clone@@Base+0xcd>
   a8c4d:	4c 8b 93 c8 00 00 00 	mov    0xc8(%rbx),%r10
   a8c54:	4c 8b 9b c0 00 00 00 	mov    0xc0(%rbx),%r11
   a8c5b:	4c 8b a3 18 01 00 00 	mov    0x118(%rbx),%r12
   a8c62:	48 8b 93 f8 00 00 00 	mov    0xf8(%rbx),%rdx
   a8c69:	4c 89 5c 24 30       	mov    %r11,0x30(%rsp)
   a8c6e:	4c 89 54 24 40       	mov    %r10,0x40(%rsp)
   a8c73:	48 89 54 24 38       	mov    %rdx,0x38(%rsp)
   a8c78:	4c 89 64 24 48       	mov    %r12,0x48(%rsp)
   a8c7d:	83 e0 fe             	and    $0xfffffffe,%eax
   a8c80:	4c 63 c0             	movslq %eax,%r8
   a8c83:	83 c0 01             	add    $0x1,%eax
   a8c86:	49 8d 48 01          	lea    0x1(%r8),%rcx
   a8c8a:	49 c1 e0 05          	shl    $0x5,%r8
   a8c8e:	4a 8b bc 03 b0 00 00 	mov    0xb0(%rbx,%r8,1),%rdi
   a8c95:	00
   a8c96:	4e 8b 8c 03 b8 00 00 	mov    0xb8(%rbx,%r8,1),%r9
   a8c9d:	00
   a8c9e:	48 c1 e1 04          	shl    $0x4,%rcx
   a8ca2:	48 89 3c 0c          	mov    %rdi,(%rsp,%rcx,1)
   a8ca6:	4c 89 4c 0c 08       	mov    %r9,0x8(%rsp,%rcx,1)
   a8cab:	39 c6                	cmp    %eax,%esi
   a8cad:	7e 27                	jle    a8cd6 <picture_Clone@@Base+0x126>
   a8caf:	48 98                	cltq  
   a8cb1:	48 8d 70 01          	lea    0x1(%rax),%rsi
   a8cb5:	48 c1 e0 05          	shl    $0x5,%rax
   a8cb9:	4c 8b 94 03 b0 00 00 	mov    0xb0(%rbx,%rax,1),%r10
   a8cc0:	00
   a8cc1:	48 8b 84 03 b8 00 00 	mov    0xb8(%rbx,%rax,1),%rax
   a8cc8:	00
   a8cc9:	48 c1 e6 04          	shl    $0x4,%rsi
   a8ccd:	4c 89 14 34          	mov    %r10,(%rsp,%rsi,1)
   a8cd1:	48 89 44 34 08       	mov    %rax,0x8(%rsp,%rsi,1)


The specific cause of the vlc crash is that the 'mov %rdi,0x20(%rsp)' at a8c38 writes a bogus value to the res.p[1].p_pixels pointer, as rdi contains picture->p[0].i_lines and picture->p[0].i_pitch. The rdi register is correctly used by 'mov %rdi,0x18(%rsp)' at a8c3d to write them to res.p[0].i_lines and res.p[0].i_pitch.
When that p_pixels pointer is later accessed, it results in a segmentation fault.


The problem in gcc is triggered by this commit:https://gcc.gnu.org/git/?p=gcc.git;a=patch;h=e93428a8b056aed83a7678d4dc8272131ab671ba
>From e93428a8b056aed83a7678d4dc8272131ab671ba Mon Sep 17 00:00:00 2001
From: Richard Biener <rguenther@suse.de>
Date: Mon, 14 Sep 2020 11:25:04 +0200
Subject: [PATCH] tree-optimization/97043 - fix latent wrong-code with SLP
vectorization

When the unrolling decision comes late and would have prevented
eliding a SLP load permutation we can end up generating aligned
loads when the load is in fact unaligned.  Most of the time
alignment analysis figures out the load is in fact unaligned
but that cannot be relied upon.

The following removes the SLP load permutation eliding based on
the still premature vectorization factor.

2020-09-14  Richard Biener  <rguenther@suse.de>

PR tree-optimization/97043
* tree-vect-slp.c (vect_analyze_slp_instance): Do not
elide a load permutation if the current vectorization
factor is one.
---
gcc/tree-vect-slp.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index f6331eeea86..3fdf56f9335 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2309,9 +2309,8 @@ vect_analyze_slp_instance (vec_info *vinfo,
  /* The load requires permutation when unrolling exposes
     a gap either because the group is larger than the SLP
     group-size or because there is a gap between the groups.  */
-		  && (known_eq (unrolling_factor, 1U)
-		      || (group_size == DR_GROUP_SIZE (first_stmt_info)
-			  && DR_GROUP_GAP (first_stmt_info) == 0)))
+		  && group_size == DR_GROUP_SIZE (first_stmt_info)
+		  && DR_GROUP_GAP (first_stmt_info) == 0)
{
  SLP_TREE_LOAD_PERMUTATION (load_node).release ();
  continue;
--
2.18.4


After reverting this commit on top of gcc-10 version 10.2.0-9 and recompiling vlc, the crash does not happen.

Given that a rather simple loop gets miscompiled, this might affect many other packages, as well. Thus a higher severity seems warranted.

The problematic gcc commit should be reverted or gcc otherwise be fixed.
Afterwards, vlc simply needs to be recompiled to work again properly.

Regards,
Ahzo


Reply to: