[GHC] #13617: Segfault in Windows GHCi involving C code compiled with -O4
#13617: Segfault in Windows GHCi involving C code compiled with -O4 ----------------------------------------+------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Keywords: | Operating System: Windows Architecture: Unknown/Multiple | Type of failure: GHCi crash Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: ----------------------------------------+------------------------------- This is a very elusive bug that I noticed when running an `hmatrix` example under GHCi on Windows. Luckily, this example can be reduced down to a couple of `.hs` files and a single `.c` file (with no other Haskell or C dependencies). Unfortunately, I can't quite figure out a way to reproduce this bug without `cabal`, so I've put the source code at https://github.com/RyanGlScott/hmatrix-segfault. You can reproduce this bug by doing the following: {{{ $ git clone https://github.com/RyanGlScott/hmatrix-segfault $ git reset 2bfe38f964fca64dd776993c89ec59d35fb368a5 $ cd hmatrix-segfault/ $ cabal install $ runghc exe/Main.hs Access violation in generated code when reading ffffffffffffffff }}} Running `Main.hs` in GHCi crashes, whereas compiling it works: {{{ $ ghc exe/Main.hs $ ./exe/Main.exe [1,1,1,1,1,1,1,1,1,1,1,1] }}} I've reproduced this with GHC 7.10.3, 8.0.2, and 8.2.1-rc1. There are a couple of things that appear to be necessary to trigger the segfault: 1. You need to have `-O4` under `cc-options` in `hmatrix-segfault.cabal`. 2. You need to define the [https://github.com/RyanGlScott/hmatrix- segfault/blob/2bfe38f964fca64dd776993c89ec59d35fb368a5/src/Internal/Vectorized.hs#L38 FunCodeS] datatype. Removing either of these things causes the program to work again under GHCi. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: Segfault in Windows GHCi involving C code compiled with -O4 --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Comment (by RyanGlScott): As Phyx- pointed out to me, `-O4` is just an alias for `-O3` in `gcc` and `clang`, so the issue is really with `-O3`. I've confirmed that setting `gcc-options: -O3` also triggers this segfault, but not with `gcc-options: -O2`. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCI Linker incorrectly handles the R_X86_64_PC32 relocation --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Changes (by Phyx-): * owner: (none) => Phyx- * related: => #7134 Comment: So I've finally had some time to track this one down. The difference between the `-O2` and the `-O3` code is that the `-O3` code is vectorized and the constants are moved to `.rdata`. To get to the constants a `R_X86_64_PC32` relocation is used. {{{ ac: 48 c1 e0 02 shl $0x2,%rax b0: 31 db xor %ebx,%ebx b2: 66 0f 6f 15 00 00 00 movdqa 0x0(%rip),%xmm2 # ba <stepI+0xba> b9: 00 b6: R_X86_64_PC32 .rdata ba: 48 8d 2c 02 lea (%rdx,%rax,1),%rbp be: 41 c1 ea 02 shr $0x2,%r10d }}} At runtime the program segfaults at `0xb2` when attempting to read from `.rdata`. {{{ │0xced01d2 shl $0x2,%rax │ │0xced01d6 xor %ebx,%ebx │
│0xced01d8 movdqa 0xd8(%rip),%xmm2 # 0xced02b8 │ │0xced01e0 lea (%rdx,%rax,1),%rbp │ │0xced01e4 shr $0x2,%r10d }}}
The calculated address for `.rdata` is correct, `0xced02b8`: {{{ (gdb) x/10i 0xced02b8 0xced02b8: add %eax,(%rax) 0xced02ba: add %al,(%rax) 0xced02bc: add %eax,(%rax) 0xced02be: add %al,(%rax) 0xced02c0: add %eax,(%rax) 0xced02c2: add %al,(%rax) 0xced02c4: add %eax,(%rax) 0xced02c6: add %al,(%rax) 0xced02c8: rex.RXB 0xced02c9: rex.XB }}} and the object file has {{{ Disassembly of section .rdata: 0000000000000000 <.rdata>: 0: 01 00 add %eax,(%rax) 2: 00 00 add %al,(%rax) 4: 01 00 add %eax,(%rax) 6: 00 00 add %al,(%rax) 8: 01 00 add %eax,(%rax) a: 00 00 add %al,(%rax) c: 01 00 add %eax,(%rax) ... }}} However the code is referencing this address. So I suspect it's expecting a trampoline here. So perhaps `R_X86_64_PC32` should be allocated using a jump island. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCI Linker incorrectly handles the R_X86_64_PC32 relocation --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Comment (by Phyx-): It seems the code for `R_X86_64_PC32` does already make a trampoline, but only when the address is more than `32-bits` away: {{{ case 4: /* R_X86_64_PC32 (ELF constant 2) - IMAGE_REL_AMD64_REL32 (PE constant 4) */ { intptr_t v; v = ((intptr_t)S) + ((intptr_t)(int32_t)A) - ((intptr_t)pP) - 4; if ((v >> 32) && ((-v) >> 32)) { /* Make the trampoline then */ copyName ( getSymShortName (info, sym), strtab, symbol, 1000-1 ); S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol); /* And retry */ v = ((intptr_t)S) + ((intptr_t)(int32_t)A) - ((intptr_t)pP) - 4; if ((v >> 32) && ((-v) >> 32)) { barf("IMAGE_REL_AMD64_REL32: High bits are set in %zx for %s", v, (char *)symbol); } } *(uint32_t *)pP = (uint32_t)v; break; } }}} Which explains why it doesn't always segfault.. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: Segfault when using SSE and R_X86_64_PC32 relocations to .rdata on Windows in GHCi --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Comment (by Phyx-): My initial analysis was wrong, the code isn't expecting a trampoline, it's data not code. It's simply trying to load the loop iteration increment into the SSE registers. {{{ (gdb) x/10x 0xced02b8 0xced02b8: 0x00000001 0x00000001 0x00000001 0x00000001 0xced02c8: 0x3a434347 0x65522820 0x202c3276 0x6c697542 0xced02d8: 0x79622074 0x59534d20 }}} The loop seems to have undergone 4-way vectorization. I'm not certain why this is failing.. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: Segfault when using SSE and R_X86_64_PC32 relocations to .rdata on Windows in GHCi --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Comment (by olsner): I think the issue is alignment - `movdqa` requires 16-byte alignment and the data here seems to start at `0x...8` which is only 8-byte aligned. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: Segfault when using SSE and R_X86_64_PC32 relocations to .rdata on Windows in GHCi --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Comment (by Phyx-): Ack, how did I miss the alignment note on the manual.. You're right, and the section is supposed to be 16-byte aligned {{{ 6 .rdata 00000010 0000000000000000 0000000000000000 000002ec 2**4 CONTENTS, ALLOC, LOAD, READONLY, DATA }}} Simple enough fix. Thanks @olsner, completely read over that a few times.. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCi linker does not honor alignment of sections. --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCi linker does not honor alignment of sections. --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Changes (by Phyx-): * milestone: => 8.4.1 -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:8> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCi linker does not honor alignment of sections. --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Wiki Page: | --------------------------------+---------------------------------------- Comment (by Phyx-): This has been fixed as part of a larger patch {{{ Tamar@Destiny MINGW64 /e/temp/hmatrix-segfault $ echo main | ~/ghc/inplace/bin/ghc-stage2.exe --interactive exe/Main.hs GHCi, version 8.3.20170812: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Main ( exe\Main.hs, interpreted ) Ok, 1 module loaded. *Main> [1,1,1,1,1,1,1,1,1,1,1,1] *Main> Leaving GHCi. }}} It will be posted in 1-2 weeks. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:9> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCi linker does not honor alignment of sections. --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: patch Priority: normal | Milestone: 8.4.1 Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: T13617 Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Phab:D3915 Wiki Page: | --------------------------------+---------------------------------------- Changes (by Phyx-): * status: new => patch * testcase: => T13617 * differential: => Phab:D3915 -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:10> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCi linker does not honor alignment of sections. --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: patch Priority: normal | Milestone: 8.8.1 Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: T13617 Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Phab:D3915 Wiki Page: | --------------------------------+---------------------------------------- Comment (by Phyx-): Ok, new cleanup of the linker is progressing again. I'm changing the interface to use mmap on Windows as well. and for the trampolines I have a new memory manager that's able to handle the space and mem protection for it and BSS and rest of the RTS to waste less memory. Have plain object files working almost but need to do some work to support archives. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:13> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCi linker does not honor alignment of sections. --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: patch Priority: normal | Milestone: 8.8.1 Component: GHCi | Version: 8.0.2 Resolution: | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: T13617 Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Phab:D3915 Wiki Page: | --------------------------------+---------------------------------------- Comment (by Tamar Christina <tamar@…>): In [changeset:"5840734379da5d494a368d0b8a6edf1b1216a7f4/ghc" 5840734/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="5840734379da5d494a368d0b8a6edf1b1216a7f4" Updated PE linker, section alignment and cleanup. Summary: This patch is to address a couple of short comings of the PE linker. The first thing it does is properly honor section alignments, so SSE code will work reliably. While doing this I've also changed how it reads and stores ObjectFile information. Previously the entire object file was read in and treated as one blob, including headers, symbol tables etc. Now the ObjectFile is read in but stored in chunks, tables go into a temporary info struct and code/data into a new private heap. This allows me to free all meta data once we're done relocating. Which means we can reclaim this memory. As I've mentioned above I've also moved from using VirtualAlloc to HeapAlloc. The reason is VirtualAlloc is meant to be used for more low level memory allocation, it's very fast because it can only allocate whole blocks, (64k) by default, and the memory must be paged (4k) aligned. So when you ask for e.g. 30k of memory, you're given a whole block where 34k will be wasted memory. Nothing else can ever access that untill you free the 30k. One downside of HeapAlloc is that you're not in control of how the heap grows, and heap memory is always committed. So it's harder to tell how much we're actually using now. Another big upside of splitting off the ObjectCode tables to info structs is that I can adjust them, so that later addressings can just use array subscripts to index into them. This simplifies the code a lot and a lot of complicated casts and indexing can be removed. Leaving less and more simple code. This patch doesn't fix the memprotection but it doesn't regress it either. It does however make the next changes smaller and fixes the alignments. Test Plan: ./validate , new test T13617 Reviewers: bgamari, erikd, simonmar, hvr, angerman Reviewed By: angerman Subscribers: nickkuk, carter, RyanGlScott, rwbarton, thomie GHC Trac Issues: #13617 Differential Revision: https://phabricator.haskell.org/D3915 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:14> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13617: GHCi linker does not honor alignment of sections. --------------------------------+---------------------------------------- Reporter: RyanGlScott | Owner: Phyx- Type: bug | Status: closed Priority: normal | Milestone: 8.8.1 Component: GHCi | Version: 8.0.2 Resolution: fixed | Keywords: Operating System: Windows | Architecture: Unknown/Multiple Type of failure: GHCi crash | Test Case: T13617 Blocked By: | Blocking: Related Tickets: #7134 | Differential Rev(s): Phab:D3915 Wiki Page: | --------------------------------+---------------------------------------- Changes (by Phyx-): * status: patch => closed * resolution: => fixed Comment: This is *finally* closed. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13617#comment:15> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC