dstm2014 2019-03-16 06:26
浏览 170

Cgo在返回Go Runtime之前在x_cgo_notify_runtime_init_done中被阻止

I am trying to write runc exec by myself, but got problems while implementing nsenter module.

Here is Sample Code:

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...
");
    jmp_buf env;
    switch(setjmp(env)) {
        case JUMP_PARENT: 
        printf("JUMP_PARENT
");
            int child_pid = clone(child_func, child_stack, CLONE_PARENT, env);
            printf("CHILD_PID: %d
", child_pid);
            exit(0);
        case JUMP_CHILD:
            printf("JUMP_CHILD
");
            return;
    }
}
*/
import "C"

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

Here is the output in CentOS7:

[root@localhost cgo-practive]# go build .
[root@localhost cgo-practive]# ls
cgo-practive  main.go
[root@localhost cgo-practive]# ./cgo-practive
init...
JUMP_PARENT
CHILD_PID: 14348
[root@localhost cgo-practive]# JUMP_CHILD
// program blocked here

Then I used gdb to find out the blocked reason:

(gdb) list
28              exit(0);
29          case JUMP_CHILD:
30              printf("JUMP_CHILD
");
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 ?? ()

It seems that the program was blocked in x_cgo_notify_runtime_init_done, but I am not good at cgo, can't figure out why it was blocked.

Thanks.

  • 写回答

1条回答 默认 最新

  • douyan1944 2019-03-18 15:30
    关注

    as man page says

    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.

    So you should use code below instead

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

报告相同问题?

悬赏问题

  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的