Bug 90245 - A data race with a segmentation fault handler
Summary: A data race with a segmentation fault handler
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-04-25 09:20 UTC by Martin Liška
Modified: 2019-04-25 10:42 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-04-25 00:00:00


Attachments
test-case (697 bytes, text/plain)
2019-04-25 09:20 UTC, Martin Liška
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Liška 2019-04-25 09:20:34 UTC
Created attachment 46241 [details]
test-case

It's follow up of:
https://bugzilla.opensuse.org/show_bug.cgi?id=1133245

For the attached conftest we end up with:

    56	  /* Check that the handler was called only once.  */
    57	  if (handler_called != 1) <--- problematic condition
    58	  {
    59	    __builtin_printf ("handler_called == 1\n");
    60	    exit (1);
    61	  }
    62	  /* Test passed!  */
    63	  return 0;
    64	}

$ gcc conftest.c -O2 -S -o/dev/stdout
main:
...

	movq	page(%rip), %rax
	movl	$42, 1656(%rax) <--- segfault happens here
	cmpl	$1, handler_called(%rip) <- comparison after that
	jne	.L16

While using LTO:

Disassembly of section .text:

0000000000401090 <main>:
...
  401118:	83 3d 41 2f 00 00 01 	cmpl   $0x1,0x2f41(%rip)        # 404060 <handler_called>
  40111f:	c7 83 78 06 00 00 2a 	movl   $0x2a,0x678(%rbx)
  401126:	00 00 00 
  401129:	75 15                	jne    401140 <main+0xb0>

So here we first do 'handler_called != 1' comparison and next instruction triggers the segfault handler. I tried:
--param allow-store-data-races=0, but it does not help.

Solution is to add a barrier I guess. I guess the transformation is valid?
Comment 1 Martin Liška 2019-04-25 09:21:53 UTC
More clarification:

    54	  /* The second write access should not invoke the handler.  */
    55	  crasher (page);
    56	  /* Check that the handler was called only once.  */
    57	  if (handler_called != 1)
    58	  {
    59	    __builtin_printf ("handler_called == 1\n");
    60	    exit (1);
    61	  }

The segfault happens at line 55.
Comment 2 Florian Weimer 2019-04-25 10:09:54 UTC
I think that handler_called should be volatile sig_atomic_t.  Or you would have to add signal fences.
Comment 3 Martin Liška 2019-04-25 10:42:38 UTC
(In reply to Florian Weimer from comment #2)
> I think that handler_called should be volatile sig_atomic_t.  Or you would
> have to add signal fences.

Thanks Florian.