From ecc7b82ac7c3e40e1c7cd808872ec0037022f272 Mon Sep 17 00:00:00 2001 From: aarzilli Date: Fri, 13 Sep 2024 15:51:55 +0200 Subject: [PATCH] proc: improve Rosetta check We have a check for Rosetta that should point users towards misconfiguration, however occasionally we still get new issues about debugserver crashing and some of those, as it turns out, are still caused by Rosetta (see for example #3804). Check the output of 'uname -m' and check that it isn't 'x86_64' if we are an 'arm64' process: if that happens we are running unemulated but debugserver will refuse to work. --- pkg/proc/gdbserial/gdbserver.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index 867c39848d..35d7091d60 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -297,6 +297,9 @@ func (p *gdbProcess) Listen(listener net.Listener, path, cmdline string, pid int return p.Connect(conn, path, cmdline, pid, debugInfoDirs, stopReason) case status := <-p.waitChan: listener.Close() + if err := checkRosettaExpensive(); err != nil { + return nil, err + } return nil, fmt.Errorf("stub exited while waiting for connection: %v", status) } } @@ -310,6 +313,9 @@ func (p *gdbProcess) Dial(addr string, path, cmdline string, pid int, debugInfoD } select { case status := <-p.waitChan: + if err := checkRosettaExpensive(); err != nil { + return nil, err + } return nil, fmt.Errorf("stub exited while attempting to connect: %v", status) default: } @@ -2228,3 +2234,25 @@ func machTargetExcToError(sig uint8) error { } return nil } + +func checkRosettaExpensive() error { + if runtime.GOOS != "darwin" { + return nil + } + if runtime.GOARCH != "arm64" { + return nil + } + + // Additionally check the output of 'uname -m' if it's x86_64 it means that + // the shell we are running on is being emulated by Rosetta even though our + // process isn't. In this condition debugserver will crash. + out, err := exec.Command("uname", "-m").Output() + if err != nil { + return nil + } + s := strings.TrimSpace(string(out)) + if s == "x86_64" { + return errors.New("can not run under Rosetta, check that the terminal/shell in use is right for your CPU architecture") + } + return nil +}