如何查看 GoLand 调试器是否正在程序中运行?

Phi*_*ber 6 go delve goland

在 C# 中,执行程序可以使用以下命令检测它是否在调试器中运行:

System.Diagnostics.Debugger.IsAttached
Run Code Online (Sandbox Code Playgroud)

在 Go 中有等价物吗?我有一些超时,我想在我逐步执行代码时将其禁用。谢谢!

我正在使用 GoLand 调试器。

Mar*_*oij 9

据我所知,没有内置的方法可以按照您描述的方式执行此操作。但是您可以使用构建标记或多或少地做同样的事情来指示 delve 调试器正在运行。您可以dlv使用--build-flags参数将构建标签传递给。这基本上与我在如何检查竞争检测器在运行时是否启用中描述的技术相同

isdelve/delve.go

// +build delve

package isdelve

const Enabled = true
Run Code Online (Sandbox Code Playgroud)

isdelve/nodelve.go

// +build !delve

package isdelve

const Enabled = false
Run Code Online (Sandbox Code Playgroud)

a.go

package main

import (
    "isdelve"
    "fmt"
)

func main() {
    fmt.Println("delve", isdelve.Enabled)
}
Run Code Online (Sandbox Code Playgroud)

在 Goland 中,您可以在“运行/调试配置”下启用此功能,方法是将以下内容添加到“Go 工具参数”中:

-tags=delve
Run Code Online (Sandbox Code Playgroud)

Goland 运行/调试配置窗口


如果您在 Goland 之外,运行go run a.go会报告delve false,如果您想自己运行 dlv,请使用 dlv debug --build-flags='-tags=delve' a.go; 这将报告delve true


或者,您可以使用 delve 的set命令在启动调试器后手动设置变量。


Joh*_*SFT 4

如果您假设使用的调试器是 Delve,则可以检查 Delve 进程。至少有两种情况需要考虑(也许更多)。

  1. Delve 启动了您的流程。在这种情况下,当您调用os.Getppid()获取父进程的 pid 时,该进程将是 Delve。
  2. Delve 没有启动您的流程,但后来附加到了它。在这种情况下,您需要查找所有正在运行的 Delve 进程,查看它们的命令行,并查看是否使用包含“attach”的命令行启动了任何进程,其中是调用os.Getpid(). 这依赖于这样的假设:您没有找到旧的 Delve,并且使用与您的 PID 恰好匹配的旧 PID 运行。(我忘记了操作系统重用 PID 的规则是什么)。

注意1和2使用的os函数是不同的。一个获取父级 PID,另一个获取您的 PID。

执行 1 的一些非常基本的代码如下所示:

func isLaunchedByDebugger() bool {
    // gops executable must be in the path. See https://github.com/google/gops
    gopsOut, err := exec.Command("gops", strconv.Itoa(os.Getppid())).Output()
    if err == nil && strings.Contains(string(gopsOut), "\\dlv.exe") {
        // our parent process is (probably) the Delve debugger
        return true
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)