Debugging Go Code with GDB

Debugging Go Code with GDB

Font Apex Sans

A75c909334d4dc6c7dca7bd915eebdbf?s=128

Shintaro Kaneko

June 21, 2015
Tweet

Transcript

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

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

    shintaro.kaneko
  3. None
  4. What is eureka?

  5. How do you Debug Go code?

  6. Print Debugging?

  7. func  main()  {     v  :=  map[string]string{"key":  "value"}  

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

      fmt.Println("DEBUG",  v)     for  _,  d  :=  range  v  {       ..     }   }
  9. None
  10. The Disadvantages of Print Debugging fmt.Print

  11. Ad-hoc Code is temporarily added

  12. func  main()  {     v  :=  map[string]string{"key":  "value"}  

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

      fmt.Println("DEBUG",  v)     for  _,  d  :=  range  v  {       ..     }     fmt.Println("DEBUG",  v)   } Add code temporarily
  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
  15. None
  16. Lost buffer in case of a crash

  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
  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
  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)
  20. None
  21. Can’t interrupt processing program

  22. func  main()  {     v  :=  map[string]string{"key":  "value",  ..}

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

        for  _,  d  :=  range  v  {       ..       fmt.Println("DEBUG",  d)       ..     }   } Add code temporarily
  24. DEBUG  value   DEBUG  ..   DEBUG  ..   DEBUG

     ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   The Stream of the log..
  25. None
  26. No more!

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

  28. The Advantages of GDB over Print Debugging

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

  30. Interruptible/Attachable processing program

  31. Remote debugging

  32. How to execute GDB?

  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)
  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`
  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*
  36. $ gdb main.go to execute GDB

  37. I’m not talking about How to USE gdb I will

    if there is a next time
  38. ͜͜·Ͱத൫ ͪΐͬͱ͚ͩ೔ຊޠ͕ग़͖ͯ·͢

  39. Struggled with GDB

  40. 1. Broken DWARF 2. An old GDB is in my

    GDB 3. Runtime Bug (runtime.py) 4. Web Application Framework: Revel
  41. 1. Broken DWARF

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

  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)
  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)
  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)
  46. 2. An old GDB is in my MBA

  47. 2. An old GDB is in my MBA ‣ Actually

    it was my fault. ‣ Be careful if you will install GDB
  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
  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  
  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)  
  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)  
  52. 2. An old GDB is in my MBA    $

     which  gdb      /usr/bin/gdb  
  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  
  54. 3. Runtime Bug

  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  <module>          _rctp_type  =  gdb.lookup_type("struct  runtime.rtype").pointer()   gdb.error:  No  struct  type  named  runtime.rtype.
  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  <module>          _rctp_type  =  gdb.lookup_type("struct  reflect.rtype").pointer()   gdb.error:  No  struct  type  named  runtime.rtype.
  57. 4. WAF: Revel

  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
  59. GDBͱͷ૬ੑѱ͘ͳ͍Ͱ͔͢ʁ

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

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

  62. Printσόοάͯ͠Ͷˑ

  63. None
  64. None
  65. OK, RevelͰGDBఘΊΔΘ

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

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

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

    Application ͱ૬ੑ͕ѱ͍ ‣ RevelΛ૬౰͍͡Γ·ͨ͠ɻ͕ɺRevelͷ։ൃ͕ਐΉͷ͕ਏ͍ ‣ GDB࢖͏ʹͯ͠΋೜଱ڧ͘ͳ͍ͱਏ͍
  69. Copyright © 2009-2015 eureka, Inc. All rights reserved. Thank you