Skip to content

Instantly share code, notes, and snippets.

@rutsky rutsky/README.md
Created Jul 17, 2018

Embed
What would you like to do?
cgo race condition example

Ran on a laptop with 4 cores.

$ go version
go version go1.10.1 linux/amd64
$ go run cgo.go 
panic: Iteration 39068207 - receive: "y" != "\x00"

goroutine 5 [running]:
main.main.func1()
        /home/bob/stuff/go/playground/cgo.go:35 +0x156
created by main.main
        /home/bob/stuff/go/playground/cgo.go:28 +0x47
exit status 2
$ go run cgo.go 
panic: Iteration 44789915 - execute: "y" != "\xd0"

goroutine 1 [running]:
main.main()
        /home/bob/stuff/go/playground/cgo.go:46 +0x16e
exit status 2
$ go run cgo.go 
panic: Iteration 1963975 - receive: "y" != "\x00"

goroutine 5 [running]:
main.main.func1()
        /home/bob/stuff/go/playground/cgo.go:35 +0x156
created by main.main
        /home/bob/stuff/go/playground/cgo.go:28 +0x47
exit status 2
$ go run cgo.go 
panic: Iteration 56646123 - execute: "y" != "\xd0"

goroutine 1 [running]:
main.main()
        /home/bob/stuff/go/playground/cgo.go:46 +0x16e
exit status 2
$
package main
import "fmt"
// #include <stdlib.h>
// #include <assert.h>
// static __thread char *buf = NULL;
// char * free_and_allocate() {
// if (buf) {
// buf[0] = 'x';
// free(buf);
// }
// buf = malloc(sizeof(char) * 2);
// assert(buf != NULL);
// buf[0] = 'y';
// buf[1] = 0;
// return buf;
// }
// char * receive() {
// return free_and_allocate();
// }
// char * execute() {
// return free_and_allocate();
// }
import "C"
func main() {
go func () {
i := 0
for {
i++
result := C.receive()
s := C.GoString(result)
if s != "y" {
panic(fmt.Sprintf("Iteration %v - receive: \"y\" != %#v", i, s))
}
}
}()
i := 0
for {
i++
result := C.execute();
s := C.GoString(result)
if s != "y" {
panic(fmt.Sprintf("Iteration %v - execute: \"y\" != %#v", i, s))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.