console
console copied to clipboard
console.NewPty panics on macOS
macOS Ventura, M1, go 1.20.6, console 1.0.3
A trivial program
package main
import "github.com/containerd/console"
func main() {
_, _, _ = console.NewPty()
}
Crashes with
% go run cmd/main.go
runtime: g 1: unexpected return pc for runtime.sigpanic called from 0x0
stack: frame={sp:0x14000070f10, fp:0x14000070f50} stack=[0x14000070000,0x14000071000)
0x0000014000070e10: 0x0000014000070ef0 0x00000140000021a0
0x0000014000070e20: 0x0000000000000000 0x0000014000070ee8
0x0000014000070e30: 0x0000000102b2dae8 <runtime.panicmem+0x0000000000000048> 0x0000000020007452
0x0000014000070e40: 0x0000014000070f04 0xffffffffffffffff
0x0000014000070e50: 0xffffffffffffffff 0x0000000000000009
0x0000014000070e60: 0x0000000102b8d210 <libc_ioctl_trampoline+0x0000000000000000> 0x0000014000070e98
0x0000014000070e70: 0x0000000102b8cf40 <golang.org/x/sys/unix.ioctlPtr+0x00000000000000a0> 0x00000140000021a0
0x0000014000070e80: 0x0000000000000000 0x0000000000000000
0x0000014000070e90: 0x0000000000000000 0x0000014000070ed8
0x0000014000070ea0: 0x0000000102b8d710 <github.com/containerd/console.unlockpt+0x0000000000000060> 0x00000140000021c0
0x0000014000070eb0: 0x0000000000000000 0x0000000102bbaf40
0x0000014000070ec0: 0x0000000102c412e0 0x0000000000000000
0x0000014000070ed0: 0x0000000000000000 0x0000000000000000
0x0000014000070ee0: 0x0000000000000000 0x0000014000070f08
0x0000014000070ef0: 0x0000000102b44b38 <runtime.sigpanic+0x0000000000000218> 0x0000000102bbaf40
0x0000014000070f00: 0x0000000102c412e0 0x0000000000000000
0x0000014000070f10: <0x0000000000000000 0x0000000000000000
0x0000014000070f20: 0x0000000000000000 0x0000000000000000
0x0000014000070f30: 0x0000000000000000 0x0000000000000000
0x0000014000070f40: 0x00000140000021a0 0x0000000000000000
0x0000014000070f50: >0x0000000000000000 0x0000000000000000
0x0000014000070f60: 0x0000000000000000 0x0000000000000000
0x0000014000070f70: 0x0000000102b5cb54 <runtime.goexit+0x0000000000000004> 0x000001400006a000
0x0000014000070f80: 0x0000000000000000 0x0000000000000000
0x0000014000070f90: 0x0000000000000000 0x0100000000000000
0x0000014000070fa0: 0x0000000000000000 0x0000000102c48c40
0x0000014000070fb0: 0x0000000102b31c30 <runtime.main.func2+0x0000000000000000> 0x0000014000070f9e
0x0000014000070fc0: 0x0000014000070fb0 0x0000000000000000
0x0000014000070fd0: 0x0000000000000000 0x0000000000000000
0x0000014000070fe0: 0x0000000000000000 0x0000000000000000
0x0000014000070ff0: 0x0000000000000000 0x0000000000000000
fatal error: unknown caller pc
runtime stack:
runtime.throw({0x102b8ff13?, 0x102c36060?})
/opt/homebrew/opt/go/libexec/src/runtime/panic.go:1047 +0x40 fp=0x16d2ff040 sp=0x16d2ff010 pc=0x102b2f4b0
runtime.gentraceback(0x102d98000?, 0x16d2ff3d0?, 0x2b370001873cc434?, 0x140000021a0, 0x0, 0x0, 0x7fffffff, 0x16d2ff410, 0x8124800102b5e12c?, 0x0)
/opt/homebrew/opt/go/libexec/src/runtime/traceback.go:270 +0x14bc fp=0x16d2ff3b0 sp=0x16d2ff040 pc=0x102b529ac
runtime.addOneOpenDeferFrame.func1()
/opt/homebrew/opt/go/libexec/src/runtime/panic.go:645 +0x64 fp=0x16d2ff430 sp=0x16d2ff3b0 pc=0x102b2e6c4
runtime.systemstack()
/opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:243 +0x6c fp=0x16d2ff440 sp=0x16d2ff430 pc=0x102b5a70c
goroutine 1 [running]:
runtime.systemstack_switch()
/opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:200 +0x8 fp=0x14000070df0 sp=0x14000070de0 pc=0x102b5a688
runtime.addOneOpenDeferFrame(0x20007452?, 0x14000070f04?, 0xffffffffffffffff?)
/opt/homebrew/opt/go/libexec/src/runtime/panic.go:644 +0x64 fp=0x14000070e30 sp=0x14000070df0 pc=0x102b2e624
panic({0x102bbaf40, 0x102c412e0})
/opt/homebrew/opt/go/libexec/src/runtime/panic.go:844 +0xf4 fp=0x14000070ef0 sp=0x14000070e30 pc=0x102b2ee54
runtime.panicmem()
/opt/homebrew/opt/go/libexec/src/runtime/panic.go:260 +0x48 fp=0x14000070f10 sp=0x14000070ef0 pc=0x102b2dae8
runtime: g 1: unexpected return pc for runtime.sigpanic called from 0x0
stack: frame={sp:0x14000070f10, fp:0x14000070f50} stack=[0x14000070000,0x14000071000)
0x0000014000070e10: 0x0000014000070ef0 0x00000140000021a0
0x0000014000070e20: 0x0000000000000000 0x0000014000070ee8
0x0000014000070e30: 0x0000000102b2dae8 <runtime.panicmem+0x0000000000000048> 0x0000000020007452
0x0000014000070e40: 0x0000014000070f04 0xffffffffffffffff
0x0000014000070e50: 0xffffffffffffffff 0x0000000000000009
0x0000014000070e60: 0x0000000102b8d210 <libc_ioctl_trampoline+0x0000000000000000> 0x0000014000070e98
0x0000014000070e70: 0x0000000102b8cf40 <golang.org/x/sys/unix.ioctlPtr+0x00000000000000a0> 0x00000140000021a0
0x0000014000070e80: 0x0000000000000000 0x0000000000000000
0x0000014000070e90: 0x0000000000000000 0x0000014000070ed8
0x0000014000070ea0: 0x0000000102b8d710 <github.com/containerd/console.unlockpt+0x0000000000000060> 0x00000140000021c0
0x0000014000070eb0: 0x0000000000000000 0x0000000102bbaf40
0x0000014000070ec0: 0x0000000102c412e0 0x0000000000000000
0x0000014000070ed0: 0x0000000000000000 0x0000000000000000
0x0000014000070ee0: 0x0000000000000000 0x0000014000070f08
0x0000014000070ef0: 0x0000000102b44b38 <runtime.sigpanic+0x0000000000000218> 0x0000000102bbaf40
0x0000014000070f00: 0x0000000102c412e0 0x0000000000000000
0x0000014000070f10: <0x0000000000000000 0x0000000000000000
0x0000014000070f20: 0x0000000000000000 0x0000000000000000
0x0000014000070f30: 0x0000000000000000 0x0000000000000000
0x0000014000070f40: 0x00000140000021a0 0x0000000000000000
0x0000014000070f50: >0x0000000000000000 0x0000000000000000
0x0000014000070f60: 0x0000000000000000 0x0000000000000000
0x0000014000070f70: 0x0000000102b5cb54 <runtime.goexit+0x0000000000000004> 0x000001400006a000
0x0000014000070f80: 0x0000000000000000 0x0000000000000000
0x0000014000070f90: 0x0000000000000000 0x0100000000000000
0x0000014000070fa0: 0x0000000000000000 0x0000000102c48c40
0x0000014000070fb0: 0x0000000102b31c30 <runtime.main.func2+0x0000000000000000> 0x0000014000070f9e
0x0000014000070fc0: 0x0000014000070fb0 0x0000000000000000
0x0000014000070fd0: 0x0000000000000000 0x0000000000000000
0x0000014000070fe0: 0x0000000000000000 0x0000000000000000
0x0000014000070ff0: 0x0000000000000000 0x0000000000000000
runtime.sigpanic()
/opt/homebrew/opt/go/libexec/src/runtime/signal_unix.go:841 +0x218 fp=0x14000070f50 sp=0x14000070f10 pc=0x102b44b38
goroutine 2 [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:381 +0xe4 fp=0x14000044fa0 sp=0x14000044f80 pc=0x102b31f24
runtime.goparkunlock(...)
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:387
runtime.forcegchelper()
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:305 +0xb8 fp=0x14000044fd0 sp=0x14000044fa0 pc=0x102b31d68
runtime.goexit()
/opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:1172 +0x4 fp=0x14000044fd0 sp=0x14000044fd0 pc=0x102b5cb54
created by runtime.init.6
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:293 +0x24
goroutine 3 [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:381 +0xe4 fp=0x14000045760 sp=0x14000045740 pc=0x102b31f24
runtime.goparkunlock(...)
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:387
runtime.bgsweep(0x0?)
/opt/homebrew/opt/go/libexec/src/runtime/mgcsweep.go:278 +0xa4 fp=0x140000457b0 sp=0x14000045760 pc=0x102b1fb54
runtime.gcenable.func1()
/opt/homebrew/opt/go/libexec/src/runtime/mgc.go:178 +0x28 fp=0x140000457d0 sp=0x140000457b0 pc=0x102b14908
runtime.goexit()
/opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:1172 +0x4 fp=0x140000457d0 sp=0x140000457d0 pc=0x102b5cb54
created by runtime.gcenable
/opt/homebrew/opt/go/libexec/src/runtime/mgc.go:178 +0x74
goroutine 4 [GC scavenge wait]:
runtime.gopark(0x1400005a000?, 0x102babf88?, 0x1?, 0x0?, 0x0?)
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:381 +0xe4 fp=0x14000045f50 sp=0x14000045f30 pc=0x102b31f24
runtime.goparkunlock(...)
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:387
runtime.(*scavengerState).park(0x102c487c0)
/opt/homebrew/opt/go/libexec/src/runtime/mgcscavenge.go:400 +0x5c fp=0x14000045f80 sp=0x14000045f50 pc=0x102b1d9dc
runtime.bgscavenge(0x0?)
/opt/homebrew/opt/go/libexec/src/runtime/mgcscavenge.go:628 +0x44 fp=0x14000045fb0 sp=0x14000045f80 pc=0x102b1df54
runtime.gcenable.func2()
/opt/homebrew/opt/go/libexec/src/runtime/mgc.go:179 +0x28 fp=0x14000045fd0 sp=0x14000045fb0 pc=0x102b148a8
runtime.goexit()
/opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:1172 +0x4 fp=0x14000045fd0 sp=0x14000045fd0 pc=0x102b5cb54
created by runtime.gcenable
/opt/homebrew/opt/go/libexec/src/runtime/mgc.go:179 +0xb8
goroutine 5 [finalizer wait]:
runtime.gopark(0x140000445a8?, 0x60000102b127f8?, 0x48?, 0x6a?, 0x1?)
/opt/homebrew/opt/go/libexec/src/runtime/proc.go:381 +0xe4 fp=0x14000044580 sp=0x14000044560 pc=0x102b31f24
runtime.runfinq()
/opt/homebrew/opt/go/libexec/src/runtime/mfinal.go:193 +0x10c fp=0x140000447d0 sp=0x14000044580 pc=0x102b1399c
runtime.goexit()
/opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:1172 +0x4 fp=0x140000447d0 sp=0x140000447d0 pc=0x102b5cb54
created by runtime.createfing
/opt/homebrew/opt/go/libexec/src/runtime/mfinal.go:163 +0x84
exit status 2
And the reason for the crash is that ptsname
in tc_darwin.go
is totally broken.
First, it attempts to use %d
to print a 64-bit value.
Second, and most important, it doesn't properly use syscall.TIOCPTYGNAME
. It is supposed to be called something like this:
func ptsname(f *os.File) (string, error) {
n := make([]byte, 128)
if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0]))); errno != 0 {
return "", errno
}
end := bytes.IndexByte(n, 0)
if end < 0 {
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
}
return string(n[:end]), nil
}
@dmcgowan can we merge this?