1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
semantic: 0.961
vnc: 0.955
other: 0.944
device: 0.942
graphic: 0.934
KVM: 0.899
assembly: 0.892
instruction: 0.888
mistranslation: 0.869
socket: 0.851
network: 0.851
boot: 0.835
golang binaries fail to start under linux-user
With current master golang binaries fail when run under linux-user, for example:
[will@localhost qemu]$ ./arm-linux-user/qemu-arm glide
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc
runtime stack:
runtime.throw(0x45f879, 0x9)
/usr/lib/golang/src/runtime/panic.go:566 +0x78
runtime.newosproc(0x1092c000, 0x1093bfe0)
/usr/lib/golang/src/runtime/os_linux.go:160 +0x1b0
runtime.newm(0x4ae1e8, 0x0)
/usr/lib/golang/src/runtime/proc.go:1572 +0x12c
runtime.main.func1()
/usr/lib/golang/src/runtime/proc.go:126 +0x24
runtime.systemstack(0x5ef900)
/usr/lib/golang/src/runtime/asm_arm.s:247 +0x80
runtime.mstart()
/usr/lib/golang/src/runtime/proc.go:1079
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/lib/golang/src/runtime/asm_arm.s:192 +0x4 fp=0x109287ac sp=0x109287a8
runtime.main()
/usr/lib/golang/src/runtime/proc.go:127 +0x5c fp=0x109287d4 sp=0x109287ac
runtime.goexit()
/usr/lib/golang/src/runtime/asm_arm.s:998 +0x4 fp=0x109287d4 sp=0x109287d4
The reason for this is that the golang runtime does not pass the CLONE_SYSVMEM flag to clone so the clone flags checks fail:
https://github.com/golang/go/blob/master/src/runtime/os_linux.go#L155
The attached patch allows golang binaries to start under linux-user.
The problem with doing that is that it doesn't actually change the behaviour. We use pthread_create to create the new thread, which glibc does with a clone with CLONE_SYSVSEM set. We can't tell the difference between "guest program needs the new threads to not share SysV semaphore behaviour" and "guest program doesn't care but didn't provide the flag" so we err on the side of caution and refuse to create a thread that doesn't behave the way the guest asked us for it to behave.
True, but it used to work albeit with slightly wrong semantics. It now fails hard even though the golang runtime doesn't make any use of Sys V semaphores so the presence of the flag is not noticeable by any normal user.
You can also apply this patch to go - I don't have an opinion on the correct course of action though!
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index a6efc0e3d1..64218e3f7e 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -132,7 +132,8 @@ const (
_CLONE_FS | /* share cwd, etc */
_CLONE_FILES | /* share fd table */
_CLONE_SIGHAND | /* share sig handler table */
- _CLONE_THREAD /* revisit - okay for now */
+ _CLONE_THREAD | /* revisit - okay for now */
+ _CLONE_SYSVSEM
)
//go:noescape
Note that there is a go bug about this issue too: https://github.com/golang/go/issues/20763
The go team have applied the above patch and I can confirm that it is now working properly using go-tip. This means it will be fixed in go 1.10.
So if you recompile your go binary with go-tip or go 1.10 when it is released, it will run fine under qemu-system-arm.
Since this has been fixed/worked around on the go side (thanks for following up with that!) I'm going to close this as "wontfix" on QEMU's side. It would be nice to support clone() with non-standard flags but since we can't do that while we still link with libc there's no way we can do this without a massive (and massively painful!) redesign to remove our libc dependency so that all of QEMU's linux-user code runs bare on the kernel.
I just gave it a test with qemu-arm and Go binaries still crash for me, albeit differently:
root@nofan:/# cat hello.go
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
root@nofan:/# gccgo-7 hello.go -o hello
root@nofan:/# ./hello
mmap errno 9
fatal error: mmap
runtime stack:
mmap errno 9
fatal error: mmap
panic during panic
runtime stack:
mmap errno 9
fatal error: mmap
stack trace unavailable
root@nofan:/#
Should I file a new bug report?
Yes, new bug please, that's definitely a different symptom and likely an unrelated issue.
|