main: implement tinygo lldb subcommand

LLDB mostly works on most platforms, but it is still lacking in some
features. For example, it doesn't seem to support RISC-V yet (coming in
LLVM 12), it only partially supports AVR (no stacktraces), and it
doesn't seem to support the Ctrl-C keyboard command when running a
binary for another platform (e.g. with GOOS=arm64). However, it does
mostly work, even on baremetal systems.
This commit is contained in:
Ayke van Laethem
2021-09-28 19:57:22 +02:00
committed by Ron Evans
parent 878b62bbe8
commit dbfaaf7c13
3 changed files with 84 additions and 36 deletions
+25 -11
View File
@@ -21,6 +21,7 @@ func init() {
commands["clang"] = []string{"clang-" + llvmMajor}
commands["ld.lld"] = []string{"ld.lld-" + llvmMajor, "ld.lld"}
commands["wasm-ld"] = []string{"wasm-ld-" + llvmMajor, "wasm-ld"}
commands["lldb"] = []string{"lldb-" + llvmMajor, "lldb"}
// Add the path to a Homebrew-installed LLVM for ease of use (no need to
// manually set $PATH).
if runtime.GOOS == "darwin" {
@@ -28,6 +29,7 @@ func init() {
commands["clang"] = append(commands["clang"], prefix+"clang-"+llvmMajor)
commands["ld.lld"] = append(commands["ld.lld"], prefix+"ld.lld")
commands["wasm-ld"] = append(commands["wasm-ld"], prefix+"wasm-ld")
commands["lldb"] = append(commands["lldb"], prefix+"lldb")
}
// Add the path for when LLVM was installed with the installer from
// llvm.org, which by default doesn't add LLVM to the $PATH environment
@@ -36,6 +38,7 @@ func init() {
commands["clang"] = append(commands["clang"], "clang", "C:\\Program Files\\LLVM\\bin\\clang.exe")
commands["ld.lld"] = append(commands["ld.lld"], "lld", "C:\\Program Files\\LLVM\\bin\\lld.exe")
commands["wasm-ld"] = append(commands["wasm-ld"], "C:\\Program Files\\LLVM\\bin\\wasm-ld.exe")
commands["lldb"] = append(commands["lldb"], "C:\\Program Files\\LLVM\\bin\\lldb.exe")
}
// Add the path to LLVM installed from ports.
if runtime.GOOS == "freebsd" {
@@ -43,23 +46,34 @@ func init() {
commands["clang"] = append(commands["clang"], prefix+"clang-"+llvmMajor)
commands["ld.lld"] = append(commands["ld.lld"], prefix+"ld.lld")
commands["wasm-ld"] = append(commands["wasm-ld"], prefix+"wasm-ld")
commands["lldb"] = append(commands["lldb"], prefix+"lldb")
}
}
func execCommand(cmdNames []string, args ...string) error {
for _, cmdName := range cmdNames {
cmd := exec.Command(cmdName, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
// LookupCommand looks up the executable name for a given LLVM tool such as
// clang or wasm-ld. It returns the (relative) command that can be used to
// invoke the tool or an error if it could not be found.
func LookupCommand(name string) (string, error) {
for _, cmdName := range commands[name] {
_, err := exec.LookPath(cmdName)
if err != nil {
if err, ok := err.(*exec.Error); ok && (err.Err == exec.ErrNotFound || err.Err.Error() == "file does not exist") {
// this command was not found, try the next
if errors.Unwrap(err) == exec.ErrNotFound {
continue
}
return err
return cmdName, err
}
return nil
return cmdName, nil
}
return errors.New("none of these commands were found in your $PATH: " + strings.Join(cmdNames, " "))
return "", errors.New("%#v: none of these commands were found in your $PATH: " + strings.Join(commands[name], " "))
}
func execCommand(name string, args ...string) error {
name, err := LookupCommand(name)
if err != nil {
return err
}
cmd := exec.Command(name, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
+3 -3
View File
@@ -24,7 +24,7 @@ func runCCompiler(flags ...string) error {
}
// Compile this with an external invocation of the Clang compiler.
return execCommand(commands["clang"], flags...)
return execCommand("clang", flags...)
}
// link invokes a linker with the given name and flags.
@@ -38,8 +38,8 @@ func link(linker string, flags ...string) error {
}
// Fall back to external command.
if cmdNames, ok := commands[linker]; ok {
return execCommand(cmdNames, flags...)
if _, ok := commands[linker]; ok {
return execCommand(linker, flags...)
}
cmd := exec.Command(linker, flags...)