是BUG?golang os.Process 在不同环境下的诡异Panic

LepX · 2018-03-01 23:20:40 · 3222 次点击 · 预计阅读时间 1 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2018-03-01 23:20:40 的文章,其中的信息可能已经有所发展或是发生改变。

现象

相同代码在MacOS 13.3下与CentOS 6.5下运行结果不同。

问题代码

// 这段代码是封装了一个MySQL Client,对传入的host、user、port等参数做处理
// 这里起一个协程监听singnal传给子进程,保证MySQL Clinet能够正常监听singal
go func() {
    for {
        sig := <-sc
        switch sig {
        case syscall.SIGINT:
            // MySQL Clinet会通过stdin监听SIGINT,再次传入会造成两次kill
            // proc.Signal(syscall.SIGINT)
        default:
            err := proc.Signal(sig)
            if err != nil {
                Error.Fatalln(err)
            }
        }
    }
}()

本来这段代码一开始Debug正常,也打成包在线上用了一段时间了。最近想给它添加点新功能,结果本地编译运行的时候就panic了。

Panic

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x40886ce]

goroutine 18 [running]:
os.(*Process).signal(0x0, 0x428a880, 0xc420132000, 0x0, 0x0)
        /usr/local/go/src/os/exec_unix.go:56 +0x2e
os.(*Process).Signal(0x0, 0x428a880, 0xc420132000, 0x0, 0x0)
        /usr/local/go/src/os/exec.go:129 +0x3f
main.main.func1(0xc420072240, 0xc42000e058)
        /Users/Lepx/work/code/go/src/ku/ku.go:64 +0x80
created by main.main
        /Users/Lepx/work/code/go/src/ku/ku.go:56 +0x33d

根据painc信息往下找可以看到是这段代码出的问题

func (p *Process) signal(sig Signal) error {
    if p.Pid == -1 {        //这里就是 /usr/local/go/src/os/exec_unix.go:56
        return errors.New("os: process already released")
    }
    if p.Pid == 0 {
        return errors.New("os: process not initialized")
    }
    p.sigMu.RLock()
    defer p.sigMu.RUnlock()
    if p.done() {
        return errFinished
    }
    s, ok := sig.(syscall.Signal)
    if !ok {
        return errors.New("os: unsupported signal type")
    }
    if e := syscall.Kill(p.Pid, s); e != nil {
        if e == syscall.ESRCH {
            return errFinished
        }
        return e
    }
    return nil
}

然而这段代码拉到CentOS上编译运行就正常。

第一次遇到Golang相同代码在不同环境下编译运行状态不一致的问题,不知道这是不是一个bug。

这个问题目前在1.9.2与1.10上都有发现。


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3222 次点击  
加入收藏 微博
3 回复  |  直到 2018-03-02 15:49:59
icexin
icexin · #1 · 7年之前

明显是proc空指针造成的,看到os.(*Process).Signal(0x0, 0x428a880, 0xc420132000, 0x0, 0x0)第一个参数了吗?0代表对象是空指针,好好检查下代码看是不是有漏处理的错误造成的空指针。

LepX
LepX · #2 · 7年之前
icexinicexin #1 回复

明显是proc空指针造成的,看到`os.(*Process).Signal(0x0, 0x428a880, 0xc420132000, 0x0, 0x0)`第一个参数了吗?0代表对象是空指针,好好检查下代码看是不是有漏处理的错误造成的空指针。

上层能接收的错误都接收了,同样的代码拿到Centos编译就没问题。

icexin
icexin · #3 · 7年之前

贴代码,不过我估计多半是构造proc变量的时候某些错误你没有检查造成的,比如要执行的MySQL client不存在

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传