From b9fadbae9bfe08ef05e48debeed0d3f827c43eda Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 18 Sep 2024 18:03:41 +0200 Subject: [PATCH] proc: improve Rosetta check (#3810) 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 867c3984..35d7091d 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 +}