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. func  main()  {     v  :=  map[string]string{"key":  "value"}  

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

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

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

      fmt.Println("DEBUG",  v)     for  _,  d  :=  range  v  {       ..     }     fmt.Println("DEBUG",  v)   } Add code temporarily
  5. 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
  6.   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
  7.   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
  8.   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)
  9. func  main()  {     v  :=  map[string]string{"key":  "value",  ..}

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

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

     ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   DEBUG  ..   The Stream of the log..
  12. 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)
  13. 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`
  14. $  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*
  15. 1. Broken DWARF 2. An old GDB is in my

    GDB 3. Runtime Bug (runtime.py) 4. Web Application Framework: Revel
  16. 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)
  17. 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)
  18. 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)
  19. 2. An old GDB is in my MBA ‣ Actually

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

     which  gdb      /usr/bin/gdb  
  25. 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  
  26. 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.
  27. 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.
  28. 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
  29. ·ͱΊ ‣ Print Debugging͸΍Ίͨ΄͏͕͍͍͚Ͳ… ‣ GDBͱGo͸·ͩൃల్্ ‣ ਖ਼௚Ϗϧυ͕଎͍ ‣ Web

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

    Application ͱ૬ੑ͕ѱ͍ ‣ RevelΛ૬౰͍͡Γ·ͨ͠ɻ͕ɺRevelͷ։ൃ͕ਐΉͷ͕ਏ͍ ‣ GDB࢖͏ʹͯ͠΋೜଱ڧ͘ͳ͍ͱਏ͍