Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: crash in GC on 386 #3798

Closed
dvyukov opened this issue Jul 4, 2012 · 3 comments
Closed

runtime: crash in GC on 386 #3798

dvyukov opened this issue Jul 4, 2012 · 3 comments

Comments

@dvyukov
Copy link
Member

dvyukov commented Jul 4, 2012

Current tip (13699:21130d62eeb0), linux/386, run enough times on a parallel machine:

$ GOARCH=386 GOMAXPROCS=32 go test std

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x8073d94]

goroutine 50 [running]:
testing.func·003(0xf7756fd4, 0xf7756100)
    /usr/local/google/home/dvyukov/go_vanilla/src/pkg/testing/testing.go:268 +0x123
----- stack segment boundary -----
runtime_test.TestStopTheWorldDeadlock(0x18855200, 0xe)
    /usr/local/google/home/dvyukov/go_vanilla/src/pkg/runtime/proc_test.go:25 +0x24
testing.tRunner(0x18855200, 0x82b3dd4, 0x0)
    /usr/local/google/home/dvyukov/go_vanilla/src/pkg/testing/testing.go:273 +0x71
created by testing.RunTests
    /usr/local/google/home/dvyukov/go_vanilla/src/pkg/testing/testing.go:349 +0x711

The culprit is:

// mgc0.c
static struct {
    uint64  full;  // lock-free list of full blocks
    uint64  empty; // lock-free list of empty blocks
...
} work;

8c does not align uint64 on 8-bytes, occasionally full/empty crosses cache-line boundary
and then

TEXT runtime·atomicload64(SB), 7, $0
    MOVL    4(SP), BX
    MOVL    8(SP), AX
    // MOVQ (%EAX), %MM0
    BYTE $0x0f; BYTE $0x6f; BYTE $0x00
    // MOVQ %MM0, 0(%EBX)
    BYTE $0x0f; BYTE $0x7f; BYTE $0x03
    // EMMS
    BYTE $0x0F; BYTE $0x77
    RET

becomes not particularly atomic.

There are 2 ways to fix it:
1. Fix the compilers to properly align uint64 (I am not sure why they do not align it
now).
2. Just patch the GC to manually align the vars.
@dvyukov
Copy link
Member Author

dvyukov commented Jul 4, 2012

Comment 1:

I think sync/atomic is also broken.
There is another option - atomic ops can check whether the adds is aligned and fallback
to LOCK CMPXCHG8B. Some C/C++ libraries use the trick, but in C/C++ is not expected to
happen, while in Go it can happen with fair probability, so I think it's a bad option.

@minux
Copy link
Member

minux commented Aug 6, 2012

Comment 2:

related issue #3799: 5c, 5g, 8c, 8g: make 64-bit fields 64-bit aligned.

@rsc
Copy link
Contributor

rsc commented Sep 12, 2012

Comment 3:

Status changed to Duplicate.

Merged into issue #3799.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants