본문 바로가기

카테고리 없음

44. GoLand 원격 디버깅

GORM, Echo 웹 서버, gRPC 서버를 실행하고, GoLand에서 원격 디버깅을 진행하였다. 결론부터 말하면, GoLand는 원격 디버깅을 잘 지원한다.

1. GORM 원격 디버깅

GoLand를 사용해서 일반적인 Go 어플리케이션을 원격 디버깅하는 데모를 진행한다.

동일한 프로젝트로 생성, GOPATH 이하에 같은 폴더와 같은 소스명으로 구성한다.
build 시 옵션을 추가한다. go build -gcflags="all=-N -l" -o gorm 

[root@localhost ~]# systemctl stop firewalld
[root@localhost gorm]# go get -u github.com/go-delve/delve/cmd/dlv
go: downloading github.com/go-delve/delve v1.8.0
go: downloading github.com/spf13/cobra v1.1.3
go: downloading github.com/spf13/cobra v1.3.0
go: downloading github.com/mattn/go-isatty v0.0.3
go: downloading github.com/konsorten/go-windows-terminal-sequences v1.0.3
go: downloading golang.org/x/sys v0.0.0-20211019181941-9d821ace8654
go: downloading golang.org/x/sys v0.0.0-20220111092808-5a964db01320
go: downloading github.com/cosiner/argv v0.1.0
go: downloading github.com/derekparker/trie v0.0.0-20200317170641-1fdf38b7b0e9
go: downloading github.com/mattn/go-colorable v0.0.9
go: downloading github.com/peterh/liner v1.2.1
go: downloading github.com/google/go-dap v0.6.0
go: downloading go.starlark.net v0.0.0-20200821142938-949cc6f4b097
go: downloading go.starlark.net v0.0.0-20211203141949-70c0e40ae128
go: downloading github.com/mattn/go-runewidth v0.0.3
go: downloading golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4
go: downloading github.com/mattn/go-runewidth v0.0.13
go: downloading golang.org/x/arch v0.0.0-20210923205945-b76863e36670
go: downloading github.com/cpuguy83/go-md2man v1.0.10
go: downloading github.com/cpuguy83/go-md2man/v2 v2.0.0
go: downloading github.com/cpuguy83/go-md2man/v2 v2.0.1
go: downloading github.com/cilium/ebpf v0.7.0
go: downloading github.com/russross/blackfriday/v2 v2.0.1
go: downloading github.com/russross/blackfriday v1.6.0
go: downloading github.com/russross/blackfriday/v2 v2.1.0
go: downloading github.com/shurcooL/sanitized_anchor_name v1.0.0
go: downloading github.com/rivo/uniseg v0.2.0
go get: added github.com/cpuguy83/go-md2man v1.0.10
go get: added github.com/go-delve/delve v1.8.0
go get: added github.com/mattn/go-runewidth v0.0.13
go get: added github.com/sirupsen/logrus v1.8.1
go get: added github.com/spf13/cobra v1.3.0
go get: added go.starlark.net v0.0.0-20211203141949-70c0e40ae128
go get: added golang.org/x/arch v0.0.0-20210923205945-b76863e36670
go get: upgraded golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd => v0.0.0-20220111092808-5a964db01320
[root@localhost gorm]#

dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./gorm

192.168.17.206 입력

자동 생성된 Debug 'go build gorm' 을 선택

API server listening at: 127.0.0.1:59750 출력한다. build -gcflags="all=-N -l" 옵션이 추가되면 API server listening 출력이 사라진다.

GOROOT=C:\Program Files\Go #gosetup
GOPATH=C:\Users\germany\go #gosetup
"C:\Program Files\Go\bin\go.exe" build -o C:\Users\germany\AppData\Local\Temp\GoLand\___go_build_gorm.exe -gcflags "all=-N -l" gorm #gosetup
"C:\Program Files\JetBrains\GoLand 2021.3.2\plugins\go\lib\dlv\windows\dlv.exe" --listen=127.0.0.1:59954 --headless=true --api-version=2 --check-go-version=false --only-same-user=false exec C:\Users\germany\AppData\Local\Temp\GoLand\___go_build_gorm.exe --
API server listening at: 127.0.0.1:59954

 

브레이크포인트에서 중지

 

2. Echo 원격 디버깅

옵션을 추가해서 빌드한다.

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

아래처럼 dlv를 시작한다.

dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./echo

 

 

C:\Users\germany\go\echo>go build -gcflags="all=-N -l" -o echo.exe

3. gRPC

처음에 사용하던 예제 소스를 변경했다. 아래의 작업은 GoLand가 설치된 VM에서 진행한다.

syntax = "proto3";

option go_package = "google.golang.org/grpc/examples/helloworld/main";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package main;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
PATH=$PATH:/root/Downloads/bin
C:\Users\germany\go\grpc>protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld.proto
'protoc-gen-go' is not recognized as an internal or external command,
operable program or batch file.
--go_out: protoc-gen-go: Plugin failed with status code 1.

설치해 주지 않으면 위의 에러가 발생한다.

C:\Users\germany\go\grpc>go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
go: downloading google.golang.org/protobuf v1.26.0

C:\Users\germany\go\grpc>go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
go: downloading google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0
go: downloading google.golang.org/protobuf v1.23.0

 

package main

import (
        "context"
        "flag"
        "fmt"
        "log"
        "net"

        "google.golang.org/grpc"
        pb "google.golang.org/grpc/examples/helloworld/helloworld"
)

var (
        port = flag.Int("port", 50051, "The server port")
)

// server is used to implement helloworld.GreeterServer.
type server struct {
        pb.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
        log.Printf("Received: %v", in.GetName())
        return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

func main() {
        flag.Parse()
        lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
        if err != nil {
                log.Fatalf("failed to listen: %v", err)
        }
        s := grpc.NewServer()
        pb.RegisterGreeterServer(s, &server{})
        log.Printf("server listening at %v", lis.Addr())
        if err := s.Serve(lis); err != nil {
                log.Fatalf("failed to serve: %v", err)
        }
}

 

C:\Users\germany\go\grpc>go mod init main
C:\Users\germany\go\grpc>go mod tidy
C:\Users\germany\go\grpc>go build -gcflags="all=-N -l" -o main

main.exe로 빌드하지 않아도 문제가 없다. 브레이크 포인트가 문제 없이 적용된다.

동일한 작업을 서버에서도 진행한다. 특이사항은 없다.

https://github.com/protocolbuffers/protobuf/releases 에서 protoc-3.19.3-linux-x86_64.zip을 다운받는다.

PATH에 추가한다.

PATH=$PATH:/root/Downloads/bin

dlv를 시작한다.

[root@localhost grpc]# dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./main
API server listening at: [::]:2345
2022-01-11T21:14:21-05:00 warning layer=rpc Listening for remote connections (connections are not authenticated nor encrypted)