
Setting up your Go project for debug mode is a breeze. You just need to add the `-gcflags="all=-N -l"` flag to your build command.
This flag tells the Go compiler not to optimize your code, which makes it easier to debug. By not optimizing, the compiler leaves in extra debugging information that's essential for debugging.
To enable debug mode in your Go project, you need to run the `go build` command with the `-gcflags` flag. The `-gcflags` flag is used to specify flags to the Go compiler.
Readers also liked: Run Kubernetes Command in Golang
Setting Up
To set up Go for run and debug mode, you'll need to have VSCode and the official Go extension installed. The extension's Readme has instructions on how to do this.
You'll also need to install Delve, a debugger for Go. I recommend following the manual installation steps for your OS, as they worked for me on macOS.
Open your main.go file, then select the debug view and press the play button at the top of the screen to start debugging.
For another approach, see: Html Template Golang
Create Launch.json File
To create a launch.json file in VS Code, you can either create it manually in the .vscode/launch.json folder or let VS Code create it for you.
The "Run and Debug" button in VS Code should be accompanied by a link to create a launch.json file. Selecting the "Go: Launch Package" option will create the file for you.
You can configure your launch.json file to accept a --config flag and an ENV environment variable.
In your launch.json file, you can specify various settings such as the program to debug, command-line arguments, and environment variables.
A unique perspective: Golang Create
GoLand
Setting up GoLand for Golang development is a breeze. GoLand is a powerful IDE that provides a GUI for debugging and works seamlessly with Delve.
You can start the debugger by clicking on the green triangle and choosing to debug, or by right-clicking on the folder and selecting Debug. For more details on debugging with GoLand, check out JetBrains' blog.
GoLand offers the same functionality as Delve, but with a graphical interface that many developers find more user-friendly.
Curious to learn more? Check out: Vscode Golang Debugging
Pre-Requisites

To set up for debugging, you'll need to have installed VSCode and the official Go extension. Detail on how to do this is beyond the scope of this post.
You'll also need to install Delve, a debugger for Go. I'd recommend following the up-to-date manual installation steps for your OS, as they worked for me on macOS.
For another approach, see: Golang Go
Debugging Tools
You can inspect variables in the VARIABLES section of the Run view or by hovering over their source in the editor. Variable values and expression evaluation are relative to the selected stack frame in the CALL section.
To inspect variables, you can also use the DEBUG CONSOLE panel, where you can evaluate expressions and register them in the WATCH section for automatic evaluation during debugging. Acceptable expressions are either a valid Delve expression or a function call.
VS Code provides a convenient way to debug your Go code by pressing F5 or Run and Debug, which requires installing Delve as a prerequisite. To install Delve, run the combination Ctrl+Shift+P or Cmd+Shift+P, choose Go: Install/Update tools, and search for "dlv."
Worth a look: How to Run Golang File
Data Inspection
Data Inspection is a crucial aspect of debugging, and Delve debugger makes it easy to inspect variables. You can do this in the VARIABLES section of the Run view or by hovering over their source in the editor.
To access the VARIABLES section, go to the Run view, and you'll see the variables listed. However, by default, global variables are hidden, and only local variables and function arguments are shown. But don't worry, you can still inspect global variables from the DEBUG CONSOLE panel.
If you prefer to have the VARIABLES section show global variables, you can set the showGlobalVariables attribute in the launch.json configuration or in the go.delveConfig setting.
Right-clicking on a variable in the VARIABLES section presents a context menu with useful shortcuts. These include Set Value, Copy Value, Copy as Expression, and Add to Watch.
Here are the features you can access from the context menu:
- Set Value: allows you to set or modify simple string, numeric, or pointer values.
- Copy Value: copies the value to the clipboard.
- Copy as Expression: useful for querying from the REPL in the DEBUG CONSOLE panel.
- Add to Watch: automatically adds the expression to the WATCH section.
Delve debugger also imposes variable loading limits to prevent loading too many variables at once and impacting debugging latency. However, the dlv-dap mode takes a different approach, providing on-demand loading of individual variables and increased string limits depending on the context.
You can also inspect variables and evaluate expressions from the DEBUG CONSOLE panel. Acceptable expressions are either valid Delve expressions or function calls.
Vs Code
Visual Studio Code is a popular IDE among developers, according to Stack Overflow 2021. It's an integrated development environment that allows you to build, edit, and debug programs.
To debug Go code in VS Code, you'll need to install Delve as a prerequisite. You can do this by running the combination Ctrl+Shift+P or Cmd+Shift+P on Windows or Mac, choosing Go: Install/Update tools, and searching for "dlv".
Once Delve is installed, you can debug your code by pressing F5 or choosing Run and Debug on your computer. This will give you a graphical user interface to see what's happening in your code.
Running the debugger will create a new file called launch.json in your working directory. This file lets you configure the debugger and specify environment variables.
You can specify environment variables in the launch.json file using the "env": {"KEY": "xxxxxxx"} attribute. You can also specify the location of a .env file to look for when debugging.
A unique perspective: Golang Debugger
Debugging Modes
There are three debugging modes available in Go: local, remote, and attach.
Local debugging uses the legacy debug adapter by default, but you can switch to the new debug adapter by setting `debugAdapter` to `dlv-dap` in your VSCode settings.
You can also switch to legacy mode for only a subset of your launch configurations by using the `debugAdapter` attribute.
Remote debugging requires adding the `port` attribute to the launch configuration, and you must specify the absolute path to the package or binary to debug on the remote host's file system.
Attach debugging allows you to attach to a running process or debug session, and you can specify the process to debug using the `processId` attribute, either by specifying the numeric PID or the target program name.
The Go extension will show a list of matching processes at the start of the debug session if there are multiple processes matching the specified program name.
You might like: Gcloud Api Using Golang
You can also connect to an already running remote debug session using the remote mode by specifying the host and port for the external dlv --headless server.
Here are the debugging modes and their requirements:
Breakpoints
Breakpoints are a fundamental tool in debugging that help you stop and inspect variables and expressions. You can add breakpoints using the break command, and view them with the breakpoints command.
To add a breakpoint at a specific line, such as line 5, you can run a command like "break 5". Once you've added breakpoints, you can clear them all with the command clearall.
Using the continue command will run the code until it reaches the next breakpoint, or until the program terminates if there are no breakpoints.
You can also configure breakpoints in VS Code's UI, where you can set breakpoints by clicking on the editor margin or using F9 on the current line. If the breakpoints can't be set, VS Code will show the failure reason and grey out the dot.
Here are the different ways to configure breakpoints in VS Code:
- Breakpoints: you can set breakpoints by clicking on the editor margin or using F9 on the current line.
- Conditional breakpoints: you can specify breakpoint conditions.
- Function Breakpoints: breakpoints can be set based on function names, with a red triangle in the BREAKPOINTS section.
- Logpoints: a logpoint is a variant of breakpoint that logs a message to DEBUG CONSOLE and continues execution.
Shadowed variables will be marked with parentheses, and function breakpoints are shown with a red triangle in the BREAKPOINTS section.
Switch to Legacy Mode
If you need to use the legacy debug adapter for local debugging, you can add a specific setting in your VSCode settings.
By default, the legacy debug adapter is used for remote debugging, but you can explicitly set it to "dlv-dap" to override the legacy adapter default.
You can use the debugAdapter attribute to switch between "dlv-dap" and "legacy" mode for specific launch configurations.
If you switch to legacy mode because of bugs or limitations in the new debug adapter, consider opening an issue to help improve it.
For information on debugging using the legacy debug adapter, please see the old Debugging Documentation.
On a similar theme: Golang Mode
Programs and Tests
To launch and debug your project, you need to select Run > Start Debugging (F5). The launch feature uses a launch request type configuration in your launch.json file.
The program attribute in the launch configuration should be the absolute path to either the Go file, or folder containing the main package or test file. In this mode, the Go extension will start the debug session by building and launching the program.
The launched program will be terminated when the debug session ends. For remote debugging, add the port attribute to the launch configuration.
You can run and debug a program or a package test running as root by starting the debug session with root privilege. The Go extension will use the sudo command to run dlv.
Set "console": "integratedTerminal" or "console": "externalTerminal" in the launch configuration to allow the debug session to access the terminal. Alternatively, you can arrange the exec launch mode to work with a pre-launch task.
Curious to learn more? Check out: Golang Test Main
Attach
Attach is a configuration mode that allows you to debug an already running program or debug session. You can select the process to debug using one of the following options: specifying the numeric process id (PID) with the processId attribute, specifying the target program name in the processId attribute, or specifying 0 in the processId attribute and selecting the process from the drop-down menu.
For local mode type configuration, the Go extension will start dlv dap and configure it to attach to the specified process. If there are multiple processes matching the specified program name, the extension will show the list of matching processes at the start of the debug session.
To attach to a running process, you need to specify the processId attribute in the launch configuration. You can do this by adding the processId attribute to the launch configuration and specifying the numeric PID of the process.
For remote debugging, you need to add the port attribute to the launch configuration. VS Code will connect to the external user-specified dlv dap server at host:port and attach to the target there.
You can also connect to an already running remote debug session using the remote mode. Specify the host and required port for the external dlv --headless server that already took program or process id details as command-line arguments.
When you end an attach debug session, the debug UI allows you to choose to disconnect the client or stop the attached server and the target process.
You might like: Http Server Golang
Actions

Debugging can be a real challenge, but knowing the right actions to take can make all the difference. The Debug toolbar appears on top of the editor once a debug session starts.
The available commands are numerous, and it's essential to know what each one does. Here's a rundown of the available commands:
- Continue / Pause F5
- Step Over (aka next in Delve) F10
- Step Into (aka step in Delve) F11
- Step Out (aka stepout in Delve) Shift+F11 or ⇧F11
- Restart (currently this is "Stop + Start") Ctrl+Shift+F5 or ⇧⌘F5
- Stop (terminate the debugee. Available in Launch request) Shift+F5 or ⇧F5
- Disconnect (detach from the debugee. Available only in Attach request) Shift+F5 or ⇧F5
- Terminate (terminate the debugee. Available only in Attach request) Alt+Shift+F5 or ⌥⇧F5
It's worth noting that function call feature is highly experimental due to the limitation in Go runtime, and pause, stop, and disconnect will not work while a function call is running.
Troubleshooting
Troubleshooting is an essential part of debugging your Go application in run mode. Read the documentation and FAQs, as well as the Delve FAQ, to see if your problem is mentioned there.
Error messages in the DEBUG CONSOLE panel can often reveal issues with your launch.json configuration, so be sure to check that first. If you're still stuck, update Delve (dlv) to pick up the most recent bug fixes.
If you can reproduce the issue with dlv, the command line tool, from the integrated terminal, take a look at the Delve project issue tracker. Capturing logs and inspecting them can also help you identify the problem.
If similar issues were reported, check the existing debugging issues to see if anyone else has encountered the same problem. If none of these steps solve your problem, don't hesitate to open a new issue.
Delve Configuration
In Delve Configuration, you can specify the maximum number of goroutines to display. This can be done by setting the `max-goroutine` flag.
The default value for `max-goroutine` is 1000, but you can adjust it to suit your needs. For example, if you're debugging a large application, you might want to set it to a higher number, like 5000.
To configure Delve, you'll also need to specify the path to the binary you want to debug, which can be done using the `binary-path` flag. This allows Delve to attach to the correct process.
Here's an interesting read: Argo Workflow to Run Golang Binary Commands
Configure Your Project
Configure your project by creating a launch configuration file for your Go project. This file will help you customize the debugging setup beyond the default options.
To create a launch configuration file, click "create a launch.json file" in the Run view. VS Code will then create a launch.json file in the .vscode folder in your workspace or user settings.
If you already have a launch.json file for your project, you can open it using the Command Palette Open launch.json command.
To add a new configuration to an existing launch.json file, open the file using the Command Palette Open launch.json command and click the Add Configuration button to invoke the snippet IntelliSense.
There are many configuration attributes available, and IntelliSense in VS Code's launch.json editor will help you navigate these options and documentation.
To make your project ready for remote debugging, you'll need to change the mode in your launch.json file to "remote". You can also remove some of the default lines and add a remotePath attribute to match the program value.
Readers also liked: Golang Init Project
Here's an example of what your launch.json file might look like:
```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Go Remote",
"type": "go",
"request": "launch",
"mode": "remote",
"remotePath": "${fileDirname}",
"program": "${fileDirname}"
}
]
}
```
This configuration file is just a starting point, and you can customize it further to suit your needs.
You might like: Golang Json
Headless Delve with Target Specified at Server Start-Up
To connect to a headless Delve server with a target specified at server start-up, you'll need to manually start a dlv --headless server listening at host:port while specifying the target program to debug/test/exec or a process to attach to on the command-line.
This mode is useful for remote attach configurations, where you can connect to the debugger with a running target. The headless dlv server can be used with both "debugAdapter": "legacy" and "debugAdapter": "dlv-dap" (with Delve v1.7.3 or newer).
You can use the --accept-multiclient flag to make this a multi-use server that persists on disconnect from a client and allows repeated connections from any of the aforementioned clients. To resume process execution on start-up, you can use a combination of --accept-multiclient and --continue flags.
Please see dlv --help and dlv [command] --help for dlv's command-line options. Delve's command-line interface can be used via dlv connect.
Expand your knowledge: Simple Http Server Golang Github
Installation and Setup
To install and set up Go for debugging, you'll want to start with the Go extension's tool installation location. The easiest way to find this is by running the Go: Locate Configured Go Tools command from the command palette.
The Go extension searches for the dlv executable in specific directories, including ${GOPATH}/bin, ${GOBIN}, and ${PATH} (or Path in Windows). You can check which directories your extension is using by running the command.
If your Go version is 1.16 or newer, you can install dlv in any of these directories, and if you want to explicitly specify the location of the delve binary, use the go.alternateTools setting.
Manually Install Dlv
If you want to manually install dlv, you can do so by following these steps. The Go extension searches for the dlv executable in specific locations, including ${GOPATH}/bin, ${GOBIN} and ${PATH} (or Path in Windows).
To find the installation location the Go extension uses, run the Go: Locate Configured Go Tools command from the command palette (⇧+⌘+P or Ctrl+Shift+P). This will show you the location where the extension is looking for tools.

If your Go version is 1.16 or newer, you can install dlv in the default location. However, if your Go version is older than 1.16, you'll need to specify a specific commit hash, branch name, or released version instead of the latest version.
For more details about manual installation, see Delve's documentation.
See what others are reading: Golang 1
Building Go Binary
To build a Go binary, you need to pass in the necessary flags to the compiler.
Passing the flag -ldflags -extldflags -g will turn off compiler optimizations and enable debug symbols, providing a better debugging experience.
This is often necessary for certain debugging scenarios, including attaching a debugger to a running process.
Setting this flag to 0 reduces system security, so it should be used cautiously and typically only in development environments.
Debugging Flow
To debug your Go program in run mode, you need to understand the process of how the debugger works.
The Go debugger, also known as the Delve debugger, is a powerful tool that allows you to step through your code, examine variables, and set breakpoints.
You can set breakpoints in your code using the `run` command with the `-delve` flag, like this: `go run -delve main.go`.
The debugger will pause at the first breakpoint it encounters, allowing you to inspect the current state of your program.
The `goroutine` command is used to list all the goroutines in your program, including the one that's currently paused at the breakpoint.
By using the `goroutine` command, you can see which goroutine is currently running and where it's paused.
The `stack` command is used to display the call stack of the current goroutine, showing you where it's up to in the code.
The `locals` command is used to display the local variables of the current function, allowing you to examine their values.
To continue running your program, you can use the `continue` command, which will resume execution until the next breakpoint.
Note that the `continue` command will not stop at the next breakpoint, but will instead continue running until it's reached naturally.
By using the `step` command, you can step through your code line by line, examining the effects of each line of code.
For another approach, see: Golang Stack
The `step` command can be used in combination with the `goroutine` command to step through the code of a specific goroutine.
The `next` command is used to step over a function call, without entering the function.
By using the `next` command, you can skip over function calls and examine the code that follows.
The `print` command is used to print the value of a variable to the console.
The `print` command can be used in combination with the `locals` command to print the values of local variables.
The `quit` command is used to exit the debugger and return to the command line.
Note that the `quit` command will terminate the debugger and your program will continue running.
Overview and Setup
To set up Go for debugging, you'll need to use the go run command with the -c flag to compile your code in debug mode. This flag tells the Go compiler to compile your code with the -gcflags=-l flag, which disables the Go compiler's garbage collector.
Additional reading: Golang Compile for Linux
The go run command with the -c flag will create a debug binary in the current directory. The debug binary will have the same name as your source file, but with a .debug extension added to the end.
You can then run the debug binary using the go run command without the -c flag. This will allow you to run your code in debug mode and take advantage of the debugging features that come with it.
Featured Images: pexels.com


