Closed huyungtang closed 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?
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)
@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.
@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>
@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.
@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"
}
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:
go-serial
project dir -> it crashesmmmmhhhh
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.
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.