Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Debugging Go Code with GDB

Debugging Go Code with GDB

Font Apex Sans

Shintaro Kaneko

June 21, 2015
Tweet

More Decks by Shintaro Kaneko

Other Decks in Technology

Transcript

  1. Debugging Go Code with GDB
    kaneshin
    Go Conference 2015 summer

    View Slide

  2. Shintaro Kaneko (kaneshin)
    - Senior Engineer @ eureka
    kaneshin
    kaneshinth
    shintaro.kaneko

    View Slide

  3. View Slide

  4. What is eureka?

    View Slide

  5. How do you Debug Go code?

    View Slide

  6. Print Debugging?

    View Slide

  7. func  main()  {  
      v  :=  map[string]string{"key":  "value"}  
      fmt.Println("DEBUG",  v)  
      for  _,  d  :=  range  v  {  
        ..  
      }  
    }

    View Slide

  8. func  main()  {  
      v  :=  map[string]string{"key":  "value"}  
      fmt.Println("DEBUG",  v)  
      for  _,  d  :=  range  v  {  
        ..  
      }  
    }

    View Slide

  9. View Slide

  10. The Disadvantages of
    Print Debugging
    fmt.Print

    View Slide

  11. Ad-hoc
    Code is temporarily added

    View Slide

  12. func  main()  {  
      v  :=  map[string]string{"key":  "value"}  
      for  _,  d  :=  range  v  {  
        ..  
      }  
    }
    If problems occur

    View Slide

  13. func  main()  {  
      v  :=  map[string]string{"key":  "value"}  
      fmt.Println("DEBUG",  v)  
      for  _,  d  :=  range  v  {  
        ..  
      }  
      fmt.Println("DEBUG",  v)  
    }
    Add code temporarily

    View Slide

  14. func  main()  {  
      v  :=  map[string]string{"key":  "value"}  
      //  fmt.Println("DEBUG",  v)  
      for  _,  d  :=  range  v  {  
        ..  
      }  
      //  fmt.Println("DEBUG",  v)  
    }
    Disable/Remove code as soon as solved

    View Slide

  15. View Slide

  16. Lost buffer in case of a crash

    View Slide

  17.   r,  w,  _  :=  os.Pipe()  
      os.Stdout  =  w  
      oc  :=  make(chan  string)  
      go  func()  {  
        var  buf  bytes.Buffer  
        io.Copy(&buf,  r)  
        oc  <-­‐  buf.String()  
      }()
    Pipe STDOUT

    View Slide

  18.   r,  w,  _  :=  os.Pipe()  
      os.Stdout  =  w  
      oc  :=  make(chan  string)  
      go  func()  {  
        var  buf  bytes.Buffer  
        io.Copy(&buf,  r)  
        oc  <-­‐  buf.String()  
      }()
    In case of io.Copy crash

    View Slide

  19.   r,  w,  _  :=  os.Pipe()  
      os.Stdout  =  w  
      oc  :=  make(chan  string)  
      go  func()  {  
        var  buf  bytes.Buffer  
        io.Copy(&buf,  r)  
        oc  <-­‐  buf.String()  
      }()
    Maybe you add print code..
    fmt.Println(buf)  
    fmt.Println(buf)

    View Slide

  20. View Slide

  21. Can’t interrupt processing program

    View Slide

  22. func  main()  {  
      v  :=  map[string]string{"key":  "value",  ..}  
      for  _,  d  :=  range  v  {  
        ..  
        ..  
      }  
    }
    If problems occur

    View Slide

  23. func  main()  {  
      v  :=  map[string]string{"key":  "value",  ..}  
      for  _,  d  :=  range  v  {  
        ..  
        fmt.Println("DEBUG",  d)  
        ..  
      }  
    }
    Add code temporarily

    View Slide

  24. DEBUG  value  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    DEBUG  ..  
    The Stream of the log..

    View Slide

  25. View Slide

  26. No more!

    View Slide

  27. Do you debug with GDB,
    don’t you?

    View Slide

  28. The Advantages of GDB
    over Print Debugging

    View Slide

  29. Printable Variables directly
    Doesn’t need to add temp code

    View Slide

  30. Interruptible/Attachable
    processing program

    View Slide

  31. Remote debugging

    View Slide

  32. How to execute GDB?

    View Slide

  33. How to execute GDB?
    ‣ It’s very easy to debug code
    ‣ See "Debugging Go Code with GDB"
    ‣ https://golang.org/doc/gdb
    ‣ GDB debugger ver 7.1+
    ‣ To inspect a live process or a core dump from DWARF
    ‣ Go ver 1.4+
    ‣ Go v1.2~1.3.3 are not working (DWARF has been missing)

    View Slide

  34. How to execute GDB?
    ‣ Compile Go Code to contain useful debugging information
    ‣ Pass `-gcflags "-N -l"` to disable optimizations of compile
    ‣ For example: `go build -gcflags "-N -l" /path/to/repo`
    ‣ Pass `-ldflags "-w"` to omit the debug information
    ‣ For example: `go build -ldflags "-w" /path/to/repo`

    View Slide

  35. $  go  build  -­‐o  fib  github.com/kaneshin/go-­‐fibonacci                
    $  go  build  -­‐gcflags  "-­‐N  -­‐l"  -­‐o  fib-­‐none  \  
                                       github.com/kaneshin/go-­‐fibonacci    
    $  go  build  -­‐ldflags  "-­‐w"  -­‐o  fib-­‐omit  \  
                                       github.com/kaneshin/go-­‐fibonacci      
       
    $  ls  -­‐al  |  grep  fib  
    -­‐rwxr-­‐xr-­‐x      1  root  root  6452704  Jun  20  11:19  fib*  
    -­‐rwxr-­‐xr-­‐x      1  root  root  6452744  Jun  20  11:24  fib-­‐none*  
    -­‐rwxr-­‐xr-­‐x      1  root  root  5128473  Jun  20  11:19  fib-­‐omit*

    View Slide

  36. $ gdb main.go
    to execute GDB

    View Slide

  37. I’m not talking about
    How to USE gdb
    I will if there is a next time

    View Slide

  38. ͜͜·Ͱத൫
    ͪΐͬͱ͚ͩ೔ຊޠ͕ग़͖ͯ·͢

    View Slide

  39. Struggled with GDB

    View Slide

  40. 1. Broken DWARF
    2. An old GDB is in my GDB
    3. Runtime Bug (runtime.py)
    4. Web Application Framework: Revel

    View Slide

  41. 1. Broken DWARF

    View Slide

  42. Broken DWARF
    ‣ Go 1.4+͸मਖ਼ࡁΈ
    ‣ Go 1.3.x Ͱ͸ਖ਼͍͠஋͕දࣔ͞Εͳ͍

    View Slide

  43. Broken DWARF
    ‣ Go 1.4+͸मਖ਼ࡁΈ
    ‣ Go 1.3.x Ͱ͸ਖ਼͍͠஋͕දࣔ͞Εͳ͍
       num  :=  r.URL.Query().Get("num")  
       n,  err  :=  strconv.Atoi(num)  
    >  if  err  !=  nil  {  
               fmt.Fprintln(os.Stderr,  err)

    View Slide

  44. Broken DWARF
    ‣ Go 1.4+͸मਖ਼ࡁΈ
    ‣ Go 1.3.x Ͱ͸ਖ਼͍͠஋͕දࣔ͞Εͳ͍
    (gdb)  info  locals  
    val  =  833358128335  
    n  =  3  
    num  =  0xc20803e4d3  "1000"  
    err  =  {tab  =  0xc20802e170,  data  =  0xc20802e160}  
    (gdb)    
       num  :=  r.URL.Query().Get("num")  
       n,  err  :=  strconv.Atoi(num)  
    >  if  err  !=  nil  {  
               fmt.Fprintln(os.Stderr,  err)

    View Slide

  45. Broken DWARF
    ‣ Go 1.4+͸मਖ਼ࡁΈ
    ‣ Go 1.3.x Ͱ͸ਖ਼͍͠஋͕දࣔ͞Εͳ͍
    (gdb)  info  locals  
    val  =  833358128335  
    n  =  3  
    num  =  0xc20803e4d3  "1000"  
    err  =  {tab  =  0xc20802e170,  data  =  0xc20802e160}  
    (gdb)    
       num  :=  r.URL.Query().Get("num")  
       n,  err  :=  strconv.Atoi(num)  
    >  if  err  !=  nil  {  
               fmt.Fprintln(os.Stderr,  err)

    View Slide

  46. 2. An old GDB is in my MBA

    View Slide

  47. 2. An old GDB is in my MBA
    ‣ Actually it was my fault.
    ‣ Be careful if you will install GDB

    View Slide

  48. 2. An old GDB is in my MBA
    ‣ Actually it was my fault.
    ‣ Be careful if you will install GDB
    How to Install GDB on OS X (Needs to sign your certification)
       $  brew  install  homebrew/dupes/gdb

    View Slide

  49. 2. An old GDB is in my MBA
    ‣ Actually it was my fault.
    ‣ Be careful if you will install GDB
    How to Install GDB on OS X (Needs to sign your certification)
       $  brew  install  homebrew/dupes/gdb  
       $  gdb  -­‐v  

    View Slide

  50. 2. An old GDB is in my MBA
    ‣ Actually it was my fault.
    ‣ Be careful if you will install GDB
    How to Install GDB on OS X (Needs to sign your certification)
       $  brew  install  homebrew/dupes/gdb  
       $  gdb  -­‐v  
       GNU  gdb  6.3.50-­‐20050815  (Apple  version  gdb-­‐1824)  
       (Wed  Feb    6  22:51:23  UTC  2013)  

    View Slide

  51. 2. An old GDB is in my MBA
    ‣ Actually it was my fault.
    ‣ Be careful if you will install GDB
    How to Install GDB on OS X (Needs to sign your certification)
       $  brew  install  homebrew/dupes/gdb  
       $  gdb  -­‐v  
       GNU  gdb  6.3.50-­‐20050815  (Apple  version  gdb-­‐1824)  
       (Wed  Feb    6  22:51:23  UTC  2013)  

    View Slide

  52. 2. An old GDB is in my MBA
       $  which  gdb  
       /usr/bin/gdb  

    View Slide

  53. 2. An old GDB is in my MBA
       $  which  gdb  
       /usr/bin/gdb  
         
       $  `brew  -­‐-­‐prefix  gdb`/bin/gdb  -­‐v  
       GNU  gdb  (GDB)  7.9.1  

    View Slide

  54. 3. Runtime Bug

    View Slide

  55. 3. Runtime Bug
    ‣ See "gdb: No struct type named runtime.rtype #9326"
    ‣ https://github.com/golang/go/issues/9326
    gdb  main.go  -­‐d  $GOROOT  
    ...  
    (gdb)  source  /usr/local/go/src/runtime/runtime-­‐gdb.py    
    Loading  Go  Runtime  support.  
    Traceback  (most  recent  call  last):  
       File  "/usr/local/go/src/runtime/runtime-­‐gdb.py",  line  205,  in    
           _rctp_type  =  gdb.lookup_type("struct  runtime.rtype").pointer()  
    gdb.error:  No  struct  type  named  runtime.rtype.

    View Slide

  56. 3. Runtime Bug
    ‣ See "gdb: No struct type named runtime.rtype #9326"
    ‣ https://github.com/golang/go/issues/9326
    gdb  main.go  -­‐d  $GOROOT  
    ...  
    (gdb)  source  /usr/local/go/src/runtime/runtime-­‐gdb.py    
    Loading  Go  Runtime  support.  
    Traceback  (most  recent  call  last):  
       File  "/usr/local/go/src/runtime/runtime-­‐gdb.py",  line  205,  in    
           _rctp_type  =  gdb.lookup_type("struct  reflect.rtype").pointer()  
    gdb.error:  No  struct  type  named  runtime.rtype.

    View Slide

  57. 4. WAF: Revel

    View Slide

  58. 4. WAF: Revel
    ‣ Revel is kind of Web Application Framework
    ‣ See "How to debug app with GDB?" #921
    ‣ https://github.com/revel/revel/issues/921

    View Slide

  59. GDBͱͷ૬ੑѱ͘ͳ͍Ͱ͔͢ʁ

    View Slide

  60. GDBͱͷ૬ੑѱ͘ͳ͍Ͱ͔͢ʁ
    ͦ΋ͦ΋ɺGoͷGDBαϙʔτ͕ऑ͍͔ΒͶ

    View Slide

  61. GDBͱͷ૬ੑѱ͘ͳ͍Ͱ͔͢ʁ
    ͦ΋ͦ΋ɺGoͷGDBαϙʔτ͕ऑ͍͔ΒͶ
    revelʹ͸ revel.DEBUG.Printf ͱ͍͏ૉ੖Β͍͠
    Printؔ਺͕͋Δ͔Β

    View Slide

  62. Printσόοάͯ͠Ͷˑ

    View Slide

  63. View Slide

  64. View Slide

  65. OK, RevelͰGDBఘΊΔΘ

    View Slide

  66. ·ͱΊ
    ‣ Print Debugging͸΍Ίͨ΄͏͕͍͍͚Ͳ…
    ‣ GDBͱGo͸·ͩൃల్্
    ‣ ਖ਼௚Ϗϧυ͕଎͍
    ‣ Web Application ͱ૬ੑ͕ѱ͍

    View Slide

  67. ·ͱΊ
    ‣ Print Debugging͸΍Ίͨ΄͏͕͍͍͚Ͳ…
    ‣ GDBͱGo͸·ͩൃల్্
    ‣ ਖ਼௚Ϗϧυ͕଎͍
    ‣ Web Application ͱ૬ੑ͕ѱ͍
    ‣ RevelΛ૬౰͍͡Γ·ͨ͠ɻ͕ɺRevelͷ։ൃ͕ਐΉͷ͕ਏ͍

    View Slide

  68. ·ͱΊ
    ‣ Print Debugging͸΍Ίͨ΄͏͕͍͍͚Ͳ…
    ‣ GDBͱGo͸·ͩൃల్্
    ‣ ਖ਼௚Ϗϧυ͕଎͍
    ‣ Web Application ͱ૬ੑ͕ѱ͍
    ‣ RevelΛ૬౰͍͡Γ·ͨ͠ɻ͕ɺRevelͷ։ൃ͕ਐΉͷ͕ਏ͍
    ‣ GDB࢖͏ʹͯ͠΋೜଱ڧ͘ͳ͍ͱਏ͍

    View Slide

  69. Copyright © 2009-2015 eureka, Inc. All rights reserved.
    Thank you

    View Slide