how can I debug go tests with gdb - go

I have some go tests. I would like to debug with gdb.
But the binaries built by go test are thrown away after running.
So how do I do it?
go 1.6 on windows/64

You use go test -c which will produce the executable file xyz.test. Afterwards you use gdb xyz.test to debug.
Just check go test --help for an explanation of the -c flag:
Compile the test binary to pkg.test but do not run it
(where pkg is the last element of the package's import path).
The file name can be changed with the -o flag.

Related

How to `go install` to bin inside module dir?

For example, when I run this
GOOS="windows" GOARCH="386" go install ./something
The executable would be created at
$GOROOT/bin/$GOOS_$GOARCH/something.exe
I want the executable to be created at
path/to/my/module/bin/$GOOS_$GOARCH/something.exe
EDIT
To clarify, I ask the question in the context of cross compiled builds inside a module.
I get the desired result using this command inside my module. I'd like to avoid specifying the path.
GOOS="windows" GOARCH="386" go build -o ./bin/$GOOS_$GOARCH/something.exe ./something
So, is it possible to get the same with go install?
Setting GOBIN results in an error
GOBIN=$(pwd)/bin GOOS="windows" GOARCH="386" go install ./something
# go install: cannot install cross-compiled binaries when GOBIN is set
Don't use go install for cross compiling. Use go build with -o flag.
Here is some history regarding GOBIN, robpike posted an issue stating "I have $GOBIN set but the go tool is ignoring it when installing..."
This article mentions
"When cross compiling, you should use go build, not go install. This is the one of the few cases where go build is preferable to go install...
The reason for this is go install always caches compiled packages, .a files, into the pkg/ directory that matches the root of the source code...
This logic also holds true for the standard library, which lives in /usr/local/go/src, so will be compiled to /usr/local/go/pkg/$GOOS_$GOARCH. This is a problem, because when cross compiling the go tool needs to rebuild the standard library for your target, but the binary distribution expects that /usr/local/go is not writeable.
Using go build rather that go install is the solution here, because go build builds, then throws away most of the result (rather than caching it for later), leaving you with the final binary in the current directory, which is most likely writeable by you"

Is it possible to debug pre-build go executables with GoLand?

I am wondering if GoLand can use the dlv exec command for debugging.
The reason we need this is because we have a complicated build process with CGO, and it's impossible to create a run configuration that works.
Maybe attach to process could work, but it doesn't seem like a great solution.
VSCode has nice integration with dlv exec, but the IDE works too slow and buggy, I wish we could use GoLand.
Has anybody found a solution for this?
Thanks in advance.
You can use the same steps as in debugging a remote process.
Those steps are:
build the binary with go build -gcflags="all=-N -l" -o myApp and any other flags you might need for CGO/etc.
run the binary using dlv --listen=:2345 --headless=true --api-version=2 exec ./myApp
go to Run | Edit Configurations | + | Go Remote and create a new run configuration that connects to localhost on port 2345 (or any other port you specify in delve's --listen flag.

How to build `cmd/compile` itself

Goal
I want to build cmd/compile, which is the compile command of go.
Problem
First, I cloned https://github.com/golang/go to ~/src/github.com/golang/go and modify codes in src/cmd/compile.
Second, I moved to ~/src/github.com/golang/go/src, and typed go build -o aaa -i cmd/compile.
Finally, aaa works, but it does not contain anything I modified.
As you know, in anywhere (even if ~/ or /tmp or the others), once you type go build -o aaa -i cmd/compile, you can get aaa.
But, I want make it modify, and build it.
How can I do that?
When you build the package cmd/compile, it builds the stdlib package for the current compiler, not the package in the source tree you're in.
If you're planning to work on the compiler itself, you need to bootstrap your own compiler:
Clone the go source code
Go to /src
Run ./all.bash
That will build the whole source tree, and create a new compiler for you. Once that's done, you have to use the compiler built by this process, which is under ~/src/github.com/golang/go/bin.

Go Install Binary name

go build allow to precise binary name with the -o command line option.
go install doesn't, but it deploy the binary and cache package compilation.
How to either change the binary name with go install? or cache compilation with go build?
A simple answer would be "use go install with correct package name", but please, where is the option I am missing?
You can use the -i flag to go build:
The -i flag installs the packages that are dependencies of the target.
go build -i -o binary packagename
When you type go help install you get
usage: go install [build flags] [packages]
Install compiles and installs the packages named by the import paths,
along with their dependencies.
For more about the build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
See also: go build, go get, go clean.
The only build flags allowed are
-a
force rebuilding of packages that are already up-to-date.
-n
print the commands but do not run them.
-p n
the number of programs, such as build commands or
test binaries, that can be run in parallel.
The default is the number of CPUs available, except
on darwin/arm which defaults to 1.
-race
enable data race detection.
Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-msan
enable interoperation with memory sanitizer.
Supported only on linux/amd64,
and only with Clang/LLVM as the host C compiler.
-v
print the names of packages as they are compiled.
-work
print the name of the temporary work directory and
do not delete it when exiting.
-x
print the commands.
-asmflags 'flag list'
arguments to pass on each go tool asm invocation.
-buildmode mode
build mode to use. See 'go help buildmode' for more.
-compiler name
name of compiler to use, as in runtime.Compiler (gccgo or gc).
-gccgoflags 'arg list'
arguments to pass on each gccgo compiler/linker invocation.
-gcflags 'arg list'
arguments to pass on each go tool compile invocation.
-installsuffix suffix
a suffix to use in the name of the package installation directory,
in order to keep output separate from default builds.
If using the -race flag, the install suffix is automatically set to race
or, if set explicitly, has _race appended to it. Likewise for the -msan
flag. Using a -buildmode option that requires non-default compile flags
has a similar effect.
-ldflags 'flag list'
arguments to pass on each go tool link invocation.
-linkshared
link against shared libraries previously created with
-buildmode=shared.
-pkgdir dir
install and load all packages from dir instead of the usual locations.
For example, when building with a non-standard configuration,
use -pkgdir to keep generated packages in a separate location.
-tags 'tag list'
a list of build tags to consider satisfied during the build.
For more information about build tags, see the description of
build constraints in the documentation for the go/build package.
-toolexec 'cmd args'
a program to use to invoke toolchain programs like vet and asm.
For example, instead of running asm, the go command will run
'cmd args /path/to/asm <arguments for asm>'.
Where -i and -o flags are no possible to install command and are available to build command only.
Now, The only option that I see to change the name of the Go install binary name is manually mv oldnamebinary newnamebinary. At least, this behaviour is in GO 1.6, maybe on coming releases can change.
we can run below commands to generate binary executable with the desired name and path:
optional if you want dep to be downloaded and installed
go install
to build the binary at path and name desired:
go build -o path/binary_name
example: go build -o ~/go/bin/mybinaryname
In GO 1.6+ you can rename your main file to whatever you want.
Example :
mv main.go myApp.go
Then just run go install myApp.go
Your myApp is ready to exec, and the location is in $GOROOT/bin

Go: How does go run file.go work

The commands go build and go install compile the files into binaries. Does go run compile or interpret the file? I couldn't find explanations online and may have missed it. Appreciate pointers. Thanks!
It's more or less the equivalent of running go build X.go -o /tmp/random-tmp-folder/exe && /tmp/random-tmp-folder/exe
The go run command compiles and runs a main package comprised of the .go files specified on the command line. The command is compiled to a temporary folder.
The go build and go install examine the files in the directory to determine which .go files are included in the main package.
Command go run performs project's building under the hood (so yes it builds project)
and with flag --work (go run --work main.go) you can see the location of temporary build files.
Also in official documentation (go1.11) you can find:
go run - compiles and runs the named main Go package.
go build - compiles the packages named by the import paths,
along with their dependencies, but it does not install the results.
go install - compiles and installs the packages named by the import paths.
Unlike in java, where the bytcode is created and interpreted at the execution time, go creates an executable file that is dependent on the machine being used,like in c, c++.

Resources