{"id":6599,"date":"2015-08-28T12:15:10","date_gmt":"2015-08-28T09:15:10","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=6599"},"modified":"2015-12-16T11:24:41","modified_gmt":"2015-12-16T09:24:41","slug":"using-gdb-debugger-go","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/","title":{"rendered":"Using the gdb Debugger with Go"},"content":{"rendered":"<p>Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add print statements to determine subjective application state at specific intervals, however it\u2019s much more difficult to respond dynamically to conditions developing in your code with this method.<\/p>\n<p>Debuggers provide an incredibly powerful troubleshooting mechanism. Adding code for troubleshooting can subtly affect how an application runs. Debuggers can give a much more accurate view of your code in the wild.<\/p>\n<p>A number of debuggers exist for Go, some <a href=\"https:\/\/github.com\/mailgun\/godebug\">inject code at compile time<\/a> to support an interactive terminal which negates some of the benefit of using a debugger. The gdb debugger allows you to inspect your compiled binaries, provided they were linked with debug information, without altering the source code. This is quite a powerful feature, since you can pull a build artifact from your deployment pipeline and debug it interactively. You can read more about this in the <a href=\"https:\/\/golang.org\/doc\/gdb\">official Golang docs<\/a>, so this guide will give a quick overview into the basic usage of the gdb debugger for Go applications.<\/p>\n<p>There seem to have been a number of changes in <strong>gdb<\/strong> since this was <a href=\"https:\/\/golang.org\/doc\/gdb\">announced<\/a>, most notably the replacement of <strong>-&gt;<\/strong> operator with <strong>.<\/strong> for accessing object attributes. Keep in mind that there may be subtle changes like this between versions of <strong>gdb<\/strong> and Go. This guide was written using <strong>gdb<\/strong> version 7.7.1 and go version 1.5beta2.<\/p>\n<h2>Getting Started with gdb Debugging<\/h2>\n<p>To experiment with <strong>gdb<\/strong> I\u2019m using a test application, the complete source code for which can be found on in <a href=\"https:\/\/github.com\/bfosberry\/gdb_sandbox\">gdb_sandbox on Github<\/a>. Let\u2019s start with a really simple application:<\/p>\n<pre class=\" brush:php\">package main\r\n\r\nimport ( \r\n    \"fmt\" \r\n)\r\n\r\nfunc main() { \r\n    for i := 0; i &lt; 5; i++ {\r\n        fmt.Println(\"looping\") \r\n    } \r\n    fmt.Println(\"Done\") \r\n}<\/pre>\n<p>We can run this code and see some very predictable output:<\/p>\n<pre class=\" brush:php\">$ go run main.go\r\nlooping\r\nlooping\r\nlooping\r\nlooping\r\nlooping\r\nDone<\/pre>\n<p>Let\u2019s debug the application. First, build the Go binary and then execute <strong>gdb<\/strong> with the binary path as an argument. Depending on your setup, you\u2019ll also need to load Go runtime support via a <strong>source<\/strong> command. At this point we\u2019ll be in the <strong>gdb<\/strong> shell, and we can set up breakpoints before executing our binary.<\/p>\n<pre class=\" brush:php\">$ go build -gcflags \"-N -l\" -o gdb_sandbox main.go \r\n$ ls\r\ngdb_sandbox  main.go  README.md\r\n$ gdb gdb_sandbox\r\n....\r\n(gdb) source \/usr\/local\/src\/go\/src\/runtime\/runtime-gdb.py\r\nLoading Go Runtime support.<\/pre>\n<p>First off, let\u2019s put a breakpoint (b) inside the for loop and take a look at what state our code has in each loop execution. We can then use the print (p) command to inspect a variable from the current context and the list (l) and backtrace (bt) commands to take a look at the code around the current step. The application execution can be stepped using next (n) or we can just continue to the next breakpoint (c).<\/p>\n<pre class=\" brush:php\">(gdb) b main.go:9 \r\nBreakpoint 1 at 0x400d35: file \/home\/bfosberry\/workspace\/gdb_sandbox\/main.go, line 9. \r\n(gdb) run \r\nStarting program: \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/gdb_sandbox Breakpoint 1, main.main () at \r\n\/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:9 \r\n9         fmt.Println(\"looping\") \r\n(gdb) l \r\n4         \"fmt\" \r\n5         ) \r\n6  \r\n7 func main() {\r\n8         for i := 0; i &lt; 5; i++ { \r\n9         fmt.Println(\"looping\") \r\n10        }` \r\n11        fmt.Println(\"Done\") \r\n12 } \r\n(gdb) p i \r\n$1 = 0 \r\n(gdb) n \r\nlooping \r\nBreakpoint 1, main.main () at \r\n\/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:9 \r\n9        fmt.Println(\"looping\") \r\n(gdb) p i \r\n$2 = 1 \r\n(gdb) bt\r\n# 0 main.main () at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:9<\/pre>\n<p>You can set breakpoints using a relative file and line number reference, a <strong>GOPATH<\/strong> file and line number reference, or a package and function reference. The following are also valid breakpoints:<\/p>\n<pre class=\" brush:php\">(gdb) b github.com\/bfosberry\/gdb_sandbox\/main.go:9\r\n(gdb) b 'main.main'<\/pre>\n<h2>Structs<\/h2>\n<p>We can make the code a little more complex to show the benefits of live debugging. We will use the function <strong>f<\/strong> to generate a simple pair, x and y, where y = f(x) when x is even, otherwise = x.<\/p>\n<pre class=\" brush:php\">type pair struct { \r\n    x int \r\n    y int \r\n}\r\n\r\nfunc handleNumber(i int) *pair { \r\n    val := i \r\n    if i%2 == 0 { \r\n        val = f(i) \r\n    } \r\n    return &amp;pair{ \r\n       x: i, \r\n       y: val, \r\n    } \r\n}\r\n\r\nfunc f(int x) int { \r\n    return x*x + x \r\n}<\/pre>\n<p>Also we can change the looping code to call these new functions.<\/p>\n<pre class=\" brush:php\">p := handleNumber(i)\r\n    fmt.Printf(\"%+v\\n\", p)\r\n    fmt.Println(\"looping\")<\/pre>\n<p>Let\u2019s say we need to debug the value of <strong>y<\/strong>. We can start by setting a breakpoint where <strong>y<\/strong> is being set and then step through the code. Using <strong>info args<\/strong> we can check function parameters, and as before <strong>bt<\/strong> gives us the current backtrace.<\/p>\n<pre class=\" brush:php\">(gdb) b 'main.f' \r\n(gdb) run \r\nStarting program: \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/gdb_sandbox\r\n\r\nBreakpoint 1, main.f (x=0, ~anon1=833492132160) \r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:33 \r\n33       return x*x + x \r\n(gdb) info args \r\nx = 0 \r\n(gdb) continue \r\nBreakpoint 1, main.f (x=0, ~anon1=833492132160) \r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:33 \r\n33       return x*x + x \r\n(gdb) info args \r\nx = 2 \r\n(gdb) bt\r\n#0 main.f (x=2, ~anon1=1) \r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:33\r\n#1 0x0000000000400f0e in main.handleNumber (i=2, ~anon1=0x1)\r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:24\r\n#2 0x0000000000400c47 in main.main ()\r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:14<\/pre>\n<p>Since we\u2019re in a condition where the value of <strong>y<\/strong> is being set based on the function <strong>f<\/strong>, we can set out of this function context and examine code farther up the stack. While the application is running we can set another breakpoint at a higher level and examine the state there.<\/p>\n<pre class=\" brush:php\">(gdb) b main.go:26 \r\nBreakpoint 2 at 0x400f22: file \r\n\/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go, line 26. \r\n(gdb) continue \r\nContinuing.\r\n\r\nBreakpoint 2, main.handleNumber (i=2, ~anon1=0x1) \r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:28 \r\n28             y: val, \r\n(gdb) l \r\n23         if i%2 == 0 { \r\n24             val = f(i) \r\n25         } \r\n26         return &amp;pair{ \r\n27             x: i, \r\n28             y: val, \r\n29         } \r\n30     } \r\n31  \r\n32 func f(x int) int { \r\n(gdb) p val \r\n$1 = 6 \r\n(gdb) p i \r\n$2 = 2<\/pre>\n<p>If we continue at this point we will bypass breakpoint 1 in function <strong>f<\/strong>, and we will trigger the breakpoint in the <strong>handleNumber<\/strong> function immediately since the function <strong>f<\/strong> is only executed for every second value of <strong>i<\/strong>. We can avoid this by disabling breakpoint 2 temporarily.<\/p>\n<pre class=\" brush:php\">(gdb) disable breakpoint 2 \r\n(gdb) continue \r\nContinuing. \r\n&amp;{x:2 y:6} \r\nlooping \r\n&amp;{x:3 y:3} \r\nlooping \r\n[New LWP 15200] \r\n[Switching to LWP 15200]\r\n\r\nBreakpoint 1, main.f (x=4, ~anon1=1) \r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:33 \r\n33         return x*x + x \r\n(gdb)<\/pre>\n<p>We can also clear and delete breakpoints using <strong>clear<\/strong> and <strong>delete breakpoint NUMBER<\/strong> respectively. By dynamically creating and toggling breakpoints we can efficiently traverse application flow.<\/p>\n<h2>Slices and Pointers<\/h2>\n<p>Few applications will be as simple as pure numerical or string values, so let\u2019s make the code a little more complex. By adding a slice of pointers to the <strong>main<\/strong> function and storing generated pairs, we could potentially plot them later.<\/p>\n<pre class=\" brush:php\">var pairs []*pair\r\n    for i := 0; i &lt; 10; i++ {\r\n        p := handleNumber(i)\r\n        fmt.Printf(\"%+v\\n\", p)\r\n        pairs = append(pairs, p)\r\n        fmt.Println(\"looping\")\r\n        }<\/pre>\n<p>This time around let\u2019s examine the slice or pairs as it gets built. First of all we\u2019ll need to examine the slice by converting it to an array. Since <strong>handleNumber<\/strong> returns a *<strong>pair<\/strong> type, we\u2019ll need to dereference the pointers and access the struct attributes.<\/p>\n<pre class=\" brush:php\">(gdb) b main.go:18 \r\nBreakpoint 1 at 0x400e14: file \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go, line 18. \r\n(gdb) run \r\nStarting program: \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/gdb_sandbox &amp;{x:0 y:0}\r\n\r\nBreakpoint 1, main.main () at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:18 \r\n18         fmt.Println(\"looping\") \r\n(gdb) p pairs \r\n$1 = []*main.pair = {0xc82000a3a0} \r\n(gdb) p pairs[0] \r\nStructure has no component named operator[]. \r\n(gdb) p pairs.array \r\n$2 = (struct main.pair **) 0xc820030028 \r\n(gdb) p pairs.array[0] \r\n$3 = (struct main.pair *) 0xc82000a3a0 \r\n(gdb) p *pairs.array[0] \r\n$4 = {x = 0, y = 0} \r\n(gdb) p (*pairs.array[0]).x \r\n$5 = 0 \r\n(gdb) p (*pairs.array[0]).y \r\n$6 = 0 \r\n(gdb) continue \r\nContinuing. \r\nlooping \r\n&amp;{x:1 y:1}\r\n\r\nBreakpoint 1, main.main () at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:18 \r\n18         fmt.Println(\"looping\") \r\n(gdb) p (pairs.array[1][5]).y \r\n$7 = 1 \r\n(gdb) continue \r\nContinuing. \r\nlooping \r\n&amp;{x:2 y:6}\r\n\r\nBreakpoint 1, main.main () at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:18 \r\n18         fmt.Println(\"looping\") \r\n(gdb) p (pairs.array[2][6]).y \r\n$8 = 6 \r\n(gdb)<\/pre>\n<p>You\u2019ll notice that while <strong>gdb<\/strong> does identify the fact that <strong>pairs<\/strong> is a slice, we can\u2019t directly access attributes. In order to access the members of the slice we need to convert it to an array via <strong>pairs.array<\/strong>. We can check the length and capacity of the slice though:<\/p>\n<pre class=\" brush:php\">(gdb) p $len(pairs)\r\n$12 = 3\r\n(gdb) p $cap(pairs)\r\n$13 = 4<\/pre>\n<p>At this point we can run the loop a few times and monitor the increasing value of <strong>x<\/strong> and <strong>y<\/strong> across different members of the slice. Something to note here is that struct attributes can be accessed via the pointer, so <code>p pairs.array[2].y<\/code> works just as well.<\/p>\n<h2>Goroutines<\/h2>\n<p>Now that we can access structs and slices, let\u2019s make the application even more complicated. Let\u2019s add some goroutines into the mix by updating our main function to process each number in parallel and pass the results back through a channel:<\/p>\n<pre class=\" brush:php\">pairs := []*pair{}\r\n    pairChan := make(chan *pair)\r\n    wg := sync.WaitGroup{}\r\n        for i := 0; i &lt; 10; i++ {\r\n          wg.Add(1)\r\n          go func(val int) {\r\n            p := handleNumber(val)\r\n            fmt.Printf(\"%+v\\n\", p)\r\n            pairChan &lt;- p\r\n            wg.Done()\r\n            }(i)\r\n    }\r\n    go func() {\r\n            for p := range pairChan {\r\n              pairs = append(pairs, p)\r\n            }\r\n    }()\r\n    wg.Wait()\r\n    close(pairChan)<\/pre>\n<p>If we wait for the WaitGroup to complete and inspect the resulting <strong>pairs<\/strong> slice, we can expect the contents to be exactly the same, although perhaps in a different order. The real power of <strong>gdb<\/strong> here comes from inspecting goroutines in flight:<\/p>\n<pre class=\" brush:php\">(gdb) b main.go:43 \r\nBreakpoint 1 at 0x400f7f: file \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go, line 43. \r\n(gdb) run \r\nStarting program: \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/gdb_sandbox\r\n\r\nBreakpoint 1, main.handleNumber (i=0, ~r1=0x0) \r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:43 \r\n43         y: val, \r\n(gdb) l \r\n38     if i%2 == 0 { \r\n39         val = f(i) \r\n40     } \r\n41     return &amp;pair{ \r\n42         x: i, \r\n43         y: val, \r\n44     } \r\n45 } \r\n46  \r\n47 func f(x int) int { \r\n(gdb) info args \r\ni = 0 \r\n~r1 = 0x0 \r\n(gdb) p val \r\n$1 = 0<\/pre>\n<p>You\u2019ll notice that we placed a breakpoint in a section of code which is executed within a goroutine. From here we can inspect local variables as well as look at other goroutines in progress:<\/p>\n<pre class=\" brush:php\">(gdb) info goroutines \r\n  1 waiting runtime.gopark \r\n  2 waiting runtime.gopark \r\n  3 waiting runtime.gopark \r\n  4 waiting runtime.gopark \r\n* 5 running main.main.func1 \r\n  6 runnable main.main.func1 \r\n  7 runnable main.main.func1 \r\n  8 runnable main.main.func1 \r\n  9 runnable main.main.func1 \r\n* 10 running main.main.func1 \r\n  11 runnable main.main.func1 \r\n  12 runnable main.main.func1 \r\n  13 runnable main.main.func1 \r\n  14 runnable main.main.func1 \r\n  15 waiting runtime.gopark \r\n(gdb) goroutine 11 bt\r\n#0 main.main.func1 (val=6, pairChan=0xc82001a180, &amp;wg=0xc82000a3a0)\r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:19\r\n#1 0x0000000000454991 in runtime.goexit () at \/usr\/local\/go\/src\/runtime\/asm_amd64.s:1696\r\n#2 0x0000000000000006 in ?? ()\r\n#3 0x000000c82001a180 in ?? ()\r\n#4 0x000000c82000a3a0 in ?? ()\r\n#5 0x0000000000000000 in ?? ()\r\n(gdb) goroutine 11 l \r\n48         return x*x + x \r\n49     } \r\n(gdb) goroutine 11 info args \r\nval = 6 \r\npairChan = 0xc82001a180 \r\n&amp;wg = 0xc82000a3a0 \r\n(gdb) goroutine 11 p val \r\n$2 = 6<\/pre>\n<p>The first thing we do here is list all running goroutines and identify one of our handlers. We can then view a backtrace and essentially send any debug commands to that goroutine. The backtrace and listing clearly do not match, how backtrace does seem to be accurate. <strong>info args<\/strong> on that goroutine shows us local variables, as well as variables available in the main function, outside the scope of the goroutine function which are prepended with an <strong>&amp;<\/strong>.<\/p>\n<h2>Conclusion<\/h2>\n<p>When it comes to debugging applications, <strong>gdb<\/strong> can be incredibly powerful. This is still a fairly fresh integration, and not everything works perfectly. Using the latest stable <strong>gdb<\/strong>, with go1.5beta2, many things are still broken:<\/p>\n<h3>Interfaces<\/h3>\n<p>According to the <a href=\"https:\/\/github.com\/mailgun\/godebug\">go blog post<\/a>, go interfaces should be supported, allowing you to dynamically cast then to their base types in <strong>gdb<\/strong>. This seems to be broken.<\/p>\n<h3>Interface{} types<\/h3>\n<p>There is no current way to convert an interface{} to its type.<\/p>\n<h3>Listing a different goroutine<\/h3>\n<p>Listing surrounding code from within another goroutine causes the line number to drift, eventually resulting in <strong>gdb<\/strong> thinking the current line is beyond the bounds of the file and throwing an error:<\/p>\n<pre class=\" brush:php\">(gdb) info goroutines \r\n  1 waiting runtime.gopark \r\n  2 waiting runtime.gopark \r\n  3 waiting runtime.gopark \r\n  4 waiting runtime.gopark \r\n* 5 running main.main.func1 \r\n  6 runnable main.main.func1 \r\n  7 runnable main.main.func1 \r\n  8 runnable main.main.func1 \r\n  9 runnable main.main.func1 \r\n* 10 running main.main.func1 \r\n  11 runnable main.main.func1 \r\n  12 runnable main.main.func1 \r\n  13 runnable main.main.func1 \r\n  14 runnable main.main.func1 \r\n  15 waiting runtime.gopark \r\n(gdb) goroutine 11 bt\r\n#0 main.main.func1 (val=6, pairChan=0xc82001a180, &amp;wg=0xc82000a3a0)\r\n    at \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go:19\r\n#1 0x0000000000454991 in runtime.goexit () at \/usr\/local\/go\/src\/runtime\/asm_amd64.s:1696\r\n#2 0x0000000000000006 in ?? ()\r\n#3 0x000000c82001a180 in ?? ()\r\n#4 0x000000c82000a3a0 in ?? ()\r\n#5 0x0000000000000000 in ?? ()\r\n(gdb) goroutine 11 l \r\n48         return x*x + x \r\n49     } \r\n(gdb) goroutine 11 l \r\nPython Exception &lt;class 'gdb.error'&gt; Line number 50 out of range; \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go has 49 lines.: \r\nError occurred in Python command: Line number 50 out of range; \/home\/bfosberry\/.go\/src\/github.com\/bfosberry\/gdb_sandbox\/main.go has 49 lines.<\/pre>\n<h3>Goroutine debugging is unstable<\/h3>\n<p>Handling goroutines general tends to be unstable; I managed to cause a number of segfaults executing simple commands. At this stage you should be prepared to deal with some issues.<\/p>\n<h3>Configuring <strong>gdb<\/strong> with Go support can be troublesome<\/h3>\n<p>Running <strong>gdb<\/strong> with Go support can be troublesome, getting the right combination of paths and build flags, and <strong>gdb<\/strong> auto-loading functionality doesn\u2019t seem to work correctly. First of all, loading Go runtime support via a <strong>gdb<\/strong> init file initializes incorrectly. This may need to be loaded manually via a source command once the debugging shell has been initialized as described in this guide.<\/p>\n<h2>When should I use a debugger?<\/h2>\n<p>So when is it useful to use <strong>gdb<\/strong>? Using print statement and debugging code is a much more targeted approach.<\/p>\n<ul>\n<li>When changing the code is not an option.<\/li>\n<li>When debugging a problem where the source is not known, and dynamic breakpoints may be beneficial.<\/li>\n<li>When working with many goroutines where the ability to pause and inspect program state would be beneficial.<\/li>\n<\/ul>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/blog.codeship.com\/using-gdb-debugger-with-go\/\">Using the gdb Debugger with Go<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/wcg\/\">WCG partner<\/a> Florian Motlik at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add print statements to determine subjective application state at specific intervals, however it\u2019s much more difficult to respond dynamically to conditions developing in your code with this method. Debuggers provide an incredibly powerful &hellip;<\/p>\n","protected":false},"author":121,"featured_media":927,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[213],"class_list":["post-6599","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-go"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using the gdb Debugger with Go - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using the gdb Debugger with Go - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-08-28T09:15:10+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-12-16T09:24:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Brendan Fosberry\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@brendanfosberry\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Brendan Fosberry\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/\"},\"author\":{\"name\":\"Brendan Fosberry\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/1f4fc9c4817554c610890f685d463d77\"},\"headline\":\"Using the gdb Debugger with Go\",\"datePublished\":\"2015-08-28T09:15:10+00:00\",\"dateModified\":\"2015-12-16T09:24:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/\"},\"wordCount\":1383,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"keywords\":[\"Go\"],\"articleSection\":[\"Web Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/\",\"name\":\"Using the gdb Debugger with Go - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"datePublished\":\"2015-08-28T09:15:10+00:00\",\"dateModified\":\"2015-12-16T09:24:41+00:00\",\"description\":\"Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Dev\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/web-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Using the gdb Debugger with Go\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/1f4fc9c4817554c610890f685d463d77\",\"name\":\"Brendan Fosberry\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1cc6c7714b253bea2b04d1f62633323f16a9609845b4e3333dfdc69cfa28213b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1cc6c7714b253bea2b04d1f62633323f16a9609845b4e3333dfdc69cfa28213b?s=96&d=mm&r=g\",\"caption\":\"Brendan Fosberry\"},\"description\":\"Brendan Fosberry is a software engineer at @codeship. He has a background in Datacenter Automation and Docker services and can usually be found fiddling in Go, Ruby or C#.\",\"sameAs\":[\"http:\/\/blog.codeship.com\/\",\"https:\/\/x.com\/brendanfosberry\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/brendan-fosberry\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using the gdb Debugger with Go - Web Code Geeks - 2026","description":"Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/","og_locale":"en_US","og_type":"article","og_title":"Using the gdb Debugger with Go - Web Code Geeks - 2026","og_description":"Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add","og_url":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2015-08-28T09:15:10+00:00","article_modified_time":"2015-12-16T09:24:41+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","type":"image\/jpeg"}],"author":"Brendan Fosberry","twitter_card":"summary_large_image","twitter_creator":"@brendanfosberry","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Brendan Fosberry","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/"},"author":{"name":"Brendan Fosberry","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/1f4fc9c4817554c610890f685d463d77"},"headline":"Using the gdb Debugger with Go","datePublished":"2015-08-28T09:15:10+00:00","dateModified":"2015-12-16T09:24:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/"},"wordCount":1383,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","keywords":["Go"],"articleSection":["Web Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/","url":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/","name":"Using the gdb Debugger with Go - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","datePublished":"2015-08-28T09:15:10+00:00","dateModified":"2015-12-16T09:24:41+00:00","description":"Troubleshooting an application can be fairly complex, especially when dealing with highly concurrent languages like Go. It can be fairly simple to add","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/web-development\/using-gdb-debugger-go\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Web Dev","item":"https:\/\/www.webcodegeeks.com\/category\/web-development\/"},{"@type":"ListItem","position":3,"name":"Using the gdb Debugger with Go"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/1f4fc9c4817554c610890f685d463d77","name":"Brendan Fosberry","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/1cc6c7714b253bea2b04d1f62633323f16a9609845b4e3333dfdc69cfa28213b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1cc6c7714b253bea2b04d1f62633323f16a9609845b4e3333dfdc69cfa28213b?s=96&d=mm&r=g","caption":"Brendan Fosberry"},"description":"Brendan Fosberry is a software engineer at @codeship. He has a background in Datacenter Automation and Docker services and can usually be found fiddling in Go, Ruby or C#.","sameAs":["http:\/\/blog.codeship.com\/","https:\/\/x.com\/brendanfosberry"],"url":"https:\/\/www.webcodegeeks.com\/author\/brendan-fosberry\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/6599","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/121"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=6599"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/6599\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/927"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=6599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=6599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=6599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}