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/cgo: blocked in x_cgo_notify_runtime_init_done before going back to Go Runtime #30900

Closed
songxinjianqwe opened this issue Mar 18, 2019 · 2 comments
Labels
FrozenDueToAge help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@songxinjianqwe
Copy link

songxinjianqwe commented Mar 18, 2019

What version of Go are you using (go version)?

$ go version
go version go1.11.5 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN="/usr/local/go/bin"
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build767481384=/tmp/go-build -gno-record-gcc-switches"

What did you do?

https://play.golang.org/p/Ec9WVLIS8OF

package main
import "fmt"
/*
#define JUMP_PARENT 0x00
#define JUMP_CHILD  0xA0
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <setjmp.h>

char child_stack[4096] __attribute__ ((aligned(16)));

int child_func(void *arg) {
    jmp_buf* env  = (jmp_buf*)arg;
    longjmp(*env, JUMP_CHILD);
}

__attribute__((constructor)) void init(void) {
    printf("init...\n");
    jmp_buf env;
    switch(setjmp(env)) {
        case JUMP_PARENT: 
        printf("JUMP_PARENT\n");
            int child_pid = clone(child_func, child_stack, CLONE_PARENT, env);
            printf("CHILD_PID: %d\n", child_pid);
            exit(0);
        case JUMP_CHILD:
            printf("JUMP_CHILD\n");
            return;
    }
}
*/
import "C"

func main() {
    fmt.Println("main...")
}

What did you expect to see?

child process can go back to Go Runtime.

What did you see instead?

child process was blocked before going back to Go Runtime.

gdb info stack:

(gdb) list
28              exit(0);
29          case JUMP_CHILD:
30              printf("JUMP_CHILD\n");
31              return;
32      }
33  }
34  */
35  import "C"
36
37  func main() {
(gdb) info stack
#0  0x00007efd6f9684ed in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x00007efd6f966170 in pthread_cond_broadcast@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#2  0x00000000004862e6 in x_cgo_notify_runtime_init_done (dummy=<optimized out>) at gcc_libinit.c:69
#3  0x0000000000451070 in runtime.asmcgocall () at /usr/local/go/src/runtime/asm_amd64.s:637
#4  0x00007ffdec4b5c30 in ?? ()
#5  0x000000000044efd1 in runtime.malg.func1 () at /usr/local/go/src/runtime/proc.go:3289
#6  0x000000000044f886 in runtime.systemstack () at /usr/local/go/src/runtime/asm_amd64.s:351
#7  0x000000000042c5b0 in ?? () at /usr/local/go/src/runtime/proc.go:1146
#8  0x000000000044f719 in runtime.rt0_go () at /usr/local/go/src/runtime/asm_amd64.s:201
#9  0x0000000000000000 in ?? ()

I also posted this problem in stackoverflow

Thanks.

@ianlancetaylor ianlancetaylor changed the title Cgo blocked in x_cgo_notify_runtime_init_done before going back to Go Runtime runtime/cgo: blocked in x_cgo_notify_runtime_init_done before going back to Go Runtime Mar 18, 2019
@ianlancetaylor ianlancetaylor added help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Mar 18, 2019
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Mar 18, 2019
@ianlancetaylor
Copy link
Contributor

Is this a problem in a real program?

I don't mind if somebody figures out a fix for this, but it doesn't seem high priority to fix a case where the C function pthread_cond_broadcast hangs. I think it's reasonable for cgo code to assume that ordinary C pthread functions will work as documented.

@songxinjianqwe
Copy link
Author

songxinjianqwe commented Mar 19, 2019

Is this a problem in a real program?

I don't mind if somebody figures out a fix for this, but it doesn't seem high priority to fix a case where the C function pthread_cond_broadcast hangs. I think it's reasonable for cgo code to assume that ordinary C pthread functions will work as documented.

I got an answer:

Stacks grow downward on all processors that run Linux (except the HP PA processors), so child_stack > usually points to the topmost address of the memory space set up for the child stack.

int child_pid = clone(child_func, &child_stack[4096], CLONE_PARENT, &env);

Thanks.

@golang golang locked and limited conversation to collaborators Mar 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

3 participants