bugst / go-serial

A cross-platform serial library for go-lang.
BSD 3-Clause "New" or "Revised" License
618 stars 188 forks source link

Fatal error with go version go1.17 darwin/amd64 #115

Closed huyungtang closed 2 years ago

huyungtang commented 2 years ago

os macOS Big Sur Version 11.5.2 (20G95) go version go1.17 darwin/amd64 go.bug.st/serial v1.3.1 or v1.3.0

After update go version 1.17, fatal error occurred when call serial.Open

serial.Open("port name", &serial.Mode{})

remove go version 1.17 & install 1.16.7, everything goes fine.

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x7fff20421c9e]

runtime stack:
runtime: unexpected return pc for runtime.sigpanic called from 0x7fff20421c9e
stack: frame={sp:0x7ffeefbff888, fp:0x7ffeefbff8d8} stack=[0x7ffeefb80928,0x7ffeefbff990)
0x00007ffeefbff788:  0x01007ffeefbff7a8  0x0000000000000004 
0x00007ffeefbff798:  0x000000000000001f  0x00007fff20421c9e 
0x00007ffeefbff7a8:  0x0b01dfacedebac1e  0x0000000000000001 
0x00007ffeefbff7b8:  0x0000000004033b31 <runtime.throw+0x0000000000000071>  0x00007ffeefbff858 
0x00007ffeefbff7c8:  0x000000000482e4b3  0x00007ffeefbff810 
0x00007ffeefbff7d8:  0x0000000004033de8 <runtime.fatalthrow.func1+0x0000000000000048>  0x0000000004e1db80 
0x00007ffeefbff7e8:  0x0000000000000001  0x0000000000000001 
0x00007ffeefbff7f8:  0x00007ffeefbff858  0x0000000004033b31 <runtime.throw+0x0000000000000071> 
0x00007ffeefbff808:  0x0000000004e1db80  0x00007ffeefbff848 
0x00007ffeefbff818:  0x0000000004033d70 <runtime.fatalthrow+0x0000000000000050>  0x00007ffeefbff828 
0x00007ffeefbff828:  0x0000000004033da0 <runtime.fatalthrow.func1+0x0000000000000000>  0x0000000004e1db80 
0x00007ffeefbff838:  0x0000000004033b31 <runtime.throw+0x0000000000000071>  0x00007ffeefbff858 
0x00007ffeefbff848:  0x00007ffeefbff878  0x0000000004033b31 <runtime.throw+0x0000000000000071> 
0x00007ffeefbff858:  0x00007ffeefbff860  0x0000000004033b60 <runtime.throw.func1+0x0000000000000000> 
0x00007ffeefbff868:  0x00000000048377dd  0x000000000000002a 
0x00007ffeefbff878:  0x00007ffeefbff8c8  0x00000000040492d6 <runtime.sigpanic+0x0000000000000396> 
0x00007ffeefbff888: <0x00000000048377dd  0x000000000403c9fe <runtime.checkTimers+0x000000000000005e> 
0x00007ffeefbff898:  0x00004f8e95d7e351  0x000000c000804410 
0x00007ffeefbff8a8:  0x00007ffeefbff8d0  0x000000000403afef <runtime.execute+0x000000000000012f> 
0x00007ffeefbff8b8:  0x000000c0001036f8  0x0000000200000001 
0x00007ffeefbff8c8:  0x00007ffeefbff910 !0x00007fff20421c9e 
0x00007ffeefbff8d8: >0x00007ffeefbff910  0x0000000004da4000 
0x00007ffeefbff8e8:  0x000000000000059d  0x0000000004295705 <golang.org/x/sys/unix.libc_ioctl_trampoline+0x0000000000000005> 
0x00007ffeefbff8f8:  0x00000000040659df <runtime.syscall+0x000000000000001f>  0x000000c0003ad608 
0x00007ffeefbff908:  0x000000c0001036c0  0x000000c0003ad5d8 
0x00007ffeefbff918:  0x0000000004063830 <runtime.asmcgocall+0x0000000000000070>  0x000000000403cd2d <runtime.park_m+0x000000000000014d> 
0x00007ffeefbff928:  0x000000c000103860  0x0000000400000002 
0x00007ffeefbff938:  0x0000000004e1db80  0x000000c000103860 
0x00007ffeefbff948:  0x0000000000000250  0x000000c0001036c0 
0x00007ffeefbff958:  0x000000c000103860  0x0000000000000004 
0x00007ffeefbff968:  0x00000000049ada78  0x0000000004e1db80 
0x00007ffeefbff978:  0x00007ffeefbff9c0  0x0000000004061845 <runtime.mstart+0x0000000000000005> 
0x00007ffeefbff988:  0x00000000040617fd <runtime.rt0_go+0x000000000000013d> 
runtime.throw({0x48377dd, 0x403c9fe})
    /usr/local/go/src/runtime/panic.go:1198 +0x71
runtime: unexpected return pc for runtime.sigpanic called from 0x7fff20421c9e
stack: frame={sp:0x7ffeefbff888, fp:0x7ffeefbff8d8} stack=[0x7ffeefb80928,0x7ffeefbff990)
0x00007ffeefbff788:  0x01007ffeefbff7a8  0x0000000000000004 
0x00007ffeefbff798:  0x000000000000001f  0x00007fff20421c9e 
0x00007ffeefbff7a8:  0x0b01dfacedebac1e  0x0000000000000001 
0x00007ffeefbff7b8:  0x0000000004033b31 <runtime.throw+0x0000000000000071>  0x00007ffeefbff858 
0x00007ffeefbff7c8:  0x000000000482e4b3  0x00007ffeefbff810 
0x00007ffeefbff7d8:  0x0000000004033de8 <runtime.fatalthrow.func1+0x0000000000000048>  0x0000000004e1db80 
0x00007ffeefbff7e8:  0x0000000000000001  0x0000000000000001 
0x00007ffeefbff7f8:  0x00007ffeefbff858  0x0000000004033b31 <runtime.throw+0x0000000000000071> 
0x00007ffeefbff808:  0x0000000004e1db80  0x00007ffeefbff848 
0x00007ffeefbff818:  0x0000000004033d70 <runtime.fatalthrow+0x0000000000000050>  0x00007ffeefbff828 
0x00007ffeefbff828:  0x0000000004033da0 <runtime.fatalthrow.func1+0x0000000000000000>  0x0000000004e1db80 
0x00007ffeefbff838:  0x0000000004033b31 <runtime.throw+0x0000000000000071>  0x00007ffeefbff858 
0x00007ffeefbff848:  0x00007ffeefbff878  0x0000000004033b31 <runtime.throw+0x0000000000000071> 
0x00007ffeefbff858:  0x00007ffeefbff860  0x0000000004033b60 <runtime.throw.func1+0x0000000000000000> 
0x00007ffeefbff868:  0x00000000048377dd  0x000000000000002a 
0x00007ffeefbff878:  0x00007ffeefbff8c8  0x00000000040492d6 <runtime.sigpanic+0x0000000000000396> 
0x00007ffeefbff888: <0x00000000048377dd  0x000000000403c9fe <runtime.checkTimers+0x000000000000005e> 
0x00007ffeefbff898:  0x00004f8e95d7e351  0x000000c000804410 
0x00007ffeefbff8a8:  0x00007ffeefbff8d0  0x000000000403afef <runtime.execute+0x000000000000012f> 
0x00007ffeefbff8b8:  0x000000c0001036f8  0x0000000200000001 
0x00007ffeefbff8c8:  0x00007ffeefbff910 !0x00007fff20421c9e 
0x00007ffeefbff8d8: >0x00007ffeefbff910  0x0000000004da4000 
0x00007ffeefbff8e8:  0x000000000000059d  0x0000000004295705 <golang.org/x/sys/unix.libc_ioctl_trampoline+0x0000000000000005> 
0x00007ffeefbff8f8:  0x00000000040659df <runtime.syscall+0x000000000000001f>  0x000000c0003ad608 
0x00007ffeefbff908:  0x000000c0001036c0  0x000000c0003ad5d8 
0x00007ffeefbff918:  0x0000000004063830 <runtime.asmcgocall+0x0000000000000070>  0x000000000403cd2d <runtime.park_m+0x000000000000014d> 
0x00007ffeefbff928:  0x000000c000103860  0x0000000400000002 
0x00007ffeefbff938:  0x0000000004e1db80  0x000000c000103860 
0x00007ffeefbff948:  0x0000000000000250  0x000000c0001036c0 
0x00007ffeefbff958:  0x000000c000103860  0x0000000000000004 
0x00007ffeefbff968:  0x00000000049ada78  0x0000000004e1db80 
0x00007ffeefbff978:  0x00007ffeefbff9c0  0x0000000004061845 <runtime.mstart+0x0000000000000005> 
0x00007ffeefbff988:  0x00000000040617fd <runtime.rt0_go+0x000000000000013d> 
runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:719 +0x396
cmaglie commented 2 years ago

This really looks like a golang compiler problem. May you add some fmt.Print in the Open function to see where the error happens?

huyungtang commented 2 years ago

This really looks like a golang compiler problem. May you add some fmt.Print in the Open function to see where the error happens?

serial_unix.go Line 426

func (port *unixPort) getTermSettings() (*unix.Termios, error) {
    fmt.Printf("BGN =====> %s\n", "unix.IoctlGetTermios")
    defer fmt.Printf("END =====> %s\n", "unix.IoctlGetTermios")

    return unix.IoctlGetTermios(port.handle, ioctlTcgetattr)
}

output:

=====> serial.Open
=====> nativeOpen
=====> unix.Open
=====> BytePtrFromString
=====> syscall_syscall
=====> port.getTermSettings
BGN =====> unix.IoctlGetTermios
=====> ioctl
BGN =====> _, _, e1 := syscall_syscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x7fff20421c9e]

runtime stack:
runtime: unexpected return pc for runtime.sigpanic called from 0x7fff20421c9e
stack: frame={sp:0x700003c5de58, fp:0x700003c5dea8} stack=[0x700003bde338,0x700003c5df38)
cmaglie commented 2 years ago

@huyungtang thanks for testing!

Could you extract that single line into a separate go program? something like:

package main

import (
    "fmt"

    "golang.org/x/sys/unix"
)

const ioctlTcgetattr = unix.TIOCGETA

func main() {
    var handle int
    res, err := unix.IoctlGetTermios(handle, ioctlTcgetattr)
    fmt.Println(res, err)
}

If this program still crashes we could submit it to the golang developers.

huyungtang commented 2 years ago

@cmaglie Yes, it works fine.

As your instruction, I get same results without any error, just like listed below.

go version go1.16.7 darwin/amd64 &{27394 3 19200 536872395 [4 255 255 127 23 21 18 255 3 28 26 25 17 19 22 15 1 0 20 255] 9600 9600} <nil>

go version go1.17 darwin/amd64 &{27394 3 19200 536872395 [4 255 255 127 23 21 18 255 3 28 26 25 17 19 22 15 1 0 20 255] 9600 9600} <nil>

cmaglie commented 2 years ago

@huyungtang I finally tried to reproduce your issue on a MacMini M1, (trying to do a serial.Open on a simple test program), but it works fine here.

It seems that the bug is triggered with a very specific set of conditions, could you post the full code that triggers the problem? If I can't reproduce the problem it will be very difficult to diagnose.

huyungtang commented 2 years ago

@cmaglie This might be the same error as #116. Try to import "gorm.io/driver/sqlite", you will reproduce the error successfully!

func nativeOpen(portName string, mode *Mode) (*unixPort, error) {
    h, err := unix.Open(portName, unix.O_RDWR|unix.O_NOCTTY|unix.O_NDELAY, 0)
        // import sqlite, the value h will be different
...

Full testing code below:

package main

import (
    "log"

    "go.bug.st/serial"
    _ "gorm.io/driver/sqlite"
)

func main() {
    rece := make(chan interface{})
    port := "/dev/tty.usbmodem48E9436036341"

    go capture(port, rece)

LOOP:
    for {
        switch val := (<-rece).(type) {
        case []byte:
            log.Println(val)
        case string:
            if val == "eof" {
                log.Println("finish")
                break LOOP
            }
        case error:
            log.Fatal(val)
        default:
            log.Fatal("unknow")
        }
    }
}

func capture(port string, data chan<- interface{}) {
    sp, err := serial.Open(port, &serial.Mode{})
    if err != nil {
        data <- err
        return
    }
    defer sp.Close()

    ln, cnt := 0, 0
    buf := make([]byte, 64)

    for cnt < 100 {
        if ln, err = sp.Read(buf); err != nil {
            data <- err
            break
        }

        if ln > 0 {
            data <- buf[0:ln]
            cnt++
        }
    }

    data <- "eof"
}
cmaglie commented 2 years ago

Thanks! I finally reproduced the issue!

I further reduced the example to:

package main

import (
    _ "github.com/mattn/go-sqlite3"
    "golang.org/x/sys/unix"
)

const ioctlTcgetattr = unix.TIOCGETA

func main() {
    unix.IoctlGetTermios(0, ioctlTcgetattr)
}

so it seems that the problem is in the golang.org/x/sys/unix package. Now, the funny thing is that:

mmmmhhhh

cmaglie commented 2 years ago

I think I found it:

~/Code/go-serial$ go get -u
go get: upgraded golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 => v0.0.0-20210823070655-63515b42dcdf
~/Code/go-serial$ go run ./test/main.go
~/Code/go-serial$                                     <- NO more crash!

so the solution is to update go.mod to use the latest x/unix package. I'll push a PR for that in a moment.