go语言

使用GoLand进行调试1 - 入门

2019-05-15  本文已影响0人  癞痢头

本文由Florin Pățan于2019年2月6日发表

调试是任何现代应用程序生命周期的重要组成部分。它不仅有助于发现错误,因为程序员经常使用调试器来查看和理解他们必须使用的新代码库或学习新语言时会发生什么。

人们更喜欢两种调试方式:

在本系列中,我们将重点介绍第二个选项,使用IDE调试应用程序。

正如您从上面的描述中注意到的那样,这样做提供了更多的控制和功能来查找错误,因此本文分为几个部分:

我们在下面介绍这些场景,不论从哪里调试, 都会会提供以下功能

IDE还支持调试在Linux上生成的核心转储以及在Linux上使用Mozilla的rr可逆调试器。我们将在即将发布的单独博文中看到这些功能。

我们将在所有上述应用程序中使用简单的Web服务器,但这些应用程序可以应用于任何类型的应用程序,CLI工具,GUI应用程序等。

我们将使用Go Modules,但使用任何其他依赖管理表单的默认GOPATH也可以正常工作。

使用Go Modules(vgo)类型创建应用程序,并确保您使用Go 1.11+或更高版本。
如果您没有Go 1.11或想要使用GOPATH模式,请选择Go

该应用程序可以在下面找到:

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
    "time"

    "github.com/gorilla/mux"
)

const (
    readTimeout  = 5
    writeTimeout = 10
    idleTimeout  = 120
)

func indexHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    returnStatus := http.StatusOK
    w.WriteHeader(returnStatus)
    message := fmt.Sprintf("Hello %s!", r.UserAgent())
    w.Write([]byte(message))
}

func main() {
    serverAddress := ":8080"
    l := log.New(os.Stdout, "sample-srv ", log.LstdFlags|log.Lshortfile)
    m := mux.NewRouter()

    m.HandleFunc("/", indexHandler)

    srv := &http.Server{
        Addr:         serverAddress,
        ReadTimeout:  readTimeout * time.Second,
        WriteTimeout: writeTimeout * time.Second,
        IdleTimeout:  idleTimeout * time.Second,
        Handler:      m,
    }

    l.Println("server started")
    if err := srv.ListenAndServe(); err != nil {
        panic(err)
    }
}

我们还可以创建一个这样的测试文件:

package main
 
import (
    "net/http"
    "net/http/httptest"
    "testing"
)
 
func TestIndexHandler(t *testing.T) {
    tests := []struct {
        name           string
        r              *http.Request
        w              *httptest.ResponseRecorder
        expectedStatus int
    }{
        {
            name:           "good",
            r:              httptest.NewRequest("GET", "/", nil),
            w:              httptest.NewRecorder(),
            expectedStatus: http.StatusOK,
        },
    }
    for _, test := range tests {
        test := test
        t.Run(test.name, func(t *testing.T) {
            indexHandler(test.w, test.r)
            if test.w.Code != test.expectedStatus {
                t.Errorf("Failed to produce expected status code %d, got %d", test.expectedStatus, test.w.Code)
            }
        })
    }
}

我们应该注意的最后一个信息是调试体验也受到用于编译目标程序的Go版本的影响。随着每个Go版本的发布,Go团队致力于添加更多调试信息并提高现有版本的质量,从旧版本(如Go 1.8)切换到Go 1.9或以更戏剧性的方式从转1.8到Go 1.11。因此,您可以使用的Go版本越新,您的体验就越好。

现在我们所有的代码都已到位,让我们开始调试它!

调试应用程序

要调试应用程序,我们可以单击绿色三角形,然后选择Debug'go build main.go'。
或者,我们可以右键单击文件夹并选择Debug | go build <项目名称>

使用GoLand进行调试 - 1

调试测试

这与调试应用程序类似, Goland识别这些测试用例是标准的测试包, ,gocheck和测试框架,所以这些测试可以从编辑器窗口直接运行

至于其它测试框架,则需要编辑配置文件,或添加额外的参数,具体取决于使用非标准包的参数。

使用GoLand进行调试 - 2

在本地计算机上调试正在运行的应用程序

在某些情况下,您可能希望调试在IDE外部启动的应用程序。

为了确保调试能够成功, 你必须要做的是编译是为的程序添加一写特殊的flag。goland将会自动添加添加这些flag,因此仅在手动编译时,才需要你来配置。

要确保调试会话成功并且您可以毫无问题地调试应用程序,您需要做的就是使用特殊标志编译应用程序。IDE将自动为其他配置类型添加这些标志,因此仅在手动编译应用程序时才需要这些标志。

如果您使用Go 1.10或更高版本运行,则需要添加-gcflags="all=-N -l"go build命令中。

  go build -gcflags="all=-N -l"

如果您使用的是Go 1.9或更早版本,则需要添加-gcflags="-N -l"go build命令中。

go build -gcflags="-N -l"

重要的提示!有些人也使用-ldflags="all=-w"-ldflags="-w",这取决于使用的Go版本。
但这与调试应用程序不兼容,因为它删除了Delve工作所需的必要DWARF信息。因此,goland无法调试应用程序。在支持此功能的操作系统和文件系统上使用符号链接或符号链接时,将遇到类似的问题。由于Go工具链,Delve和IDE之间不兼容,使用符号链接目前与调试应用程序不兼容。

使用GoLand进行调试 - 3

在远程计算机上调试正在运行的应用程序

最后这种情况比较复杂,这类调试允许goland调试远程主机上运行的程序。通过远程调试,我们可以在本地或云中考虑在本地计算机远程目标或实际服务器上运行的容器。
运行远程调试,有一下几点需要注意:

下一步,在部署应用程序时,还要在远程服务器安装相同的版本Delve。完成之后,有两种方法启动调试

以上两步请注意防火墙开启2345端口

完成所有这些操作后,编辑配置,监听远程主机和端口,即可开始调试了。


配置远程调试 使用GoLand进行调试 - 4

您可以使用以下Dockerfile中的容器来调试:

FROM golang:1.11.5-alpine3.8 AS build-env

ENV CGO_ENABLED 0

# Allow Go to retreive the dependencies for the build step
RUN apk add --no-cache git

WORKDIR /goland-debugging/
ADD . /goland-debugging/

RUN go build -o /goland-debugging/srv .

# Get Delve from a GOPATH not from a Go Modules project
WORKDIR /go/src/
RUN go get github.com/go-delve/delve/cmd/dlv

# final stage
FROM alpine:3.8

WORKDIR /
COPY --from=build-env /goland-debugging/srv /
COPY --from=build-env /go/bin/dlv /

EXPOSE 8080 40000

CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "exec", "/srv"]

请注意,在此Dockerfile中,项目名为goland-debugging,但您应更改此文件夹名称以匹配您创建的项目的名称。
运行Docker容器时,还需要为其指定--security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE参数。如果从命令行执行此操作,则这些是docker run命令的参数。如果从IDE执行此操作,则必须将这些选项放在“ 运行选项”字段中。

使用GoLand进行调试 - 5

本文章翻译自https://blog.jetbrains.com/go/2019/02/06/debugging-with-goland-getting-started
,本文译者酌情量改动

上一篇下一篇

猜你喜欢

热点阅读