Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
 Advanced debugging
techniques in different
environments
Andrii Soldatenko
• Contributor in Apache Airflow,
Golang, Pyhelm, python-sendgrid,
tutorial of aiohttp, ansible, requests,...
Problem:
Problem:
Problem: how to debug my
program?
Question to audience!
Debugging in practise:
package main
import (
"fmt"
)
func main() {
const name, age = "Andrii", 22
fmt.Println(name, "is", ...
@a_soldatenko
Interesting fact:
Go version prior 1.0
included debugger OGLE
Current versions of Go
produce DWARF
Debugging Standard 
http://dwarfstd.org/
@a_soldatenko
- delve
- GDB
Current state of go
debuggers:
Debug CLI util
.
├── github.com/me/foo
├── cmd
│ └── foo
│ └── main.go
├── pkg
│ └── baz
│ ├── bar.go
│ └── bar_test.go
$ ...
@a_soldatenko
Debugging specific
unit test
go test -test.run TestFibonacciBig
dlv test -- -test.run TestFibonacciBig
t.me/...
@a_soldatenko
Conditional breakpoint
package main
import "fmt"
func main() {
nums := []int{2, 3, 4}
for i, num := range nu...
Conditional breakpoint
(dlv) b b2 hello.go:8
Breakpoint b2 set at 0x10b71e2 for main.main() ./hello.go:8
(dlv) cond b2 num...
@a_soldatenko
Debugging unit tests:
example
dlv test -- -test.run TestFibonacciBig
(dlv) b main_test.go:6
Breakpoint 1 set...
Debugging unit tests:
breakpoint
dlv test github.com/andriisoldatenko/debugging-containerized-go-
applications/
Type 'help...
@a_soldatenko
How to set variable?
4:
=> 5: func main() {
6: a := 1
7: b := 2
8: fmt.Println(a, b)
9: }
(dlv) set a = 10
t...
Call function
(dlv) call myFunc(localVar, 4, "foo")
https://golang.org/cl/109699 runtime: support for debugger
function ca...
Call function
(dlv) call t()
> main.dummy() ./hello.go:18 (hits
goroutine(1):1 total:1) (PC:
0x10b732d)
13: }
14: }
15:
16...
@a_soldatenko
Debugging containerized
go apps
t.me/golang_for_two
Step 1: Dockerfile
$ cat Dockerfile
FROM golang:1.13
WORKDIR /go/src/app
COPY . .
RUN go get -u github.com/go-delve/delve/...
@a_soldatenko
Step 2: operation not
permitted
t.me/golang_for_two
$ docker run -it --rm my-golang-app bash
$root@03c1977b1...
@a_soldatenko
Step 3: :tada:
t.me/golang_for_two
$ docker run -it --rm 
—security-opt="apparmor=unconfined" 
—cap-add=SYS_...
@a_soldatenkot.me/golang_for_two
 Removing debugging
information from the binary
go build ldflags=-w …
@a_soldatenkot.me/golang_for_two
Remote debugging
containerized go apps
@a_soldatenko
LIVE DEMO A
t.me/golang_for_two
# Final stage
FROM alpine:3.7
# Port 8080 belongs to our application, 40000 belongs to Delve
EXPOSE 8080 40000
# Allow del...
#!/usr/bin/env bash
docker run 
-p 8080:8080 
-p 40000:40000 
--security-opt="apparmor=unconfined" 
--cap-add=SYS_PTRACE h...
$cat ~/.dlv/config.yml
substitute-path:
- {from: "/go/src/hello/", to: "/Users/
andrii/workspace/src/github.com/
andriisol...
Configure Delve
$HOME/.dlv/config.yml
Or
(dlv) config -list
dlv connect localhost:40000
(dlv) c
> main.main() /go/src/hello/hello.go:5 (hits
goroutine(1):1 total:1) (PC: 0x49b3d8)
1:...
@a_soldatenko
LIVE DEMO B
t.me/golang_for_two
@a_soldatenko
GDB
t.me/golang_for_two
@a_soldatenkot.me/golang_for_two
Starting program: /x/y/foo
Unable to find Mach task port for process-id 28885: (os/kern) ...
@a_soldatenko
[New Thread 0xe03 of process 45828]
[New Thread 0x1003 of process 45828]
warning: `/BuildRoot/Library/Caches...
@a_soldatenko
GDB: few notes!
(gdb) b main.main
Breakpoint 1 at 0x10b70f0
(gdb) c
The program is not being run.
(gdb) run
...
@a_soldatenko
GDB: few notes!
In Go 1.11, the debug information is compressed
for purpose of reduce binary size, and gdb o...
@a_soldatenko
GDB: few notes!
go build -ldflags=-compressdwarf=false -
gcflags=all="-N -l" -o hello hello.go
➜ go git:(mas...
@a_soldatenko
GDB: few notes!
(gdb) n
6 a := 1
(gdb) n
7 b := 2
(gdb) n
8 fmt.Println(a, b)
(gdb) n
1 2
9 }
(gdb)
@a_soldatenko
GDB: internals of Go
slices
@a_soldatenko
Conclusion GDB:
- GDB does not understand Go programs
well.
- The stack management, threading, and
runtime c...
@a_soldatenko
Future Reading:
- Internal Architecture of Delve - slides
- t.me/golang_for_two
Telegram channel
https://t.me/golang_for_two
Questions
? @a_soldatenkot.me/golang_for_two
Advanced debugging  techniques in different environments
Advanced debugging  techniques in different environments
Prochain SlideShare
Chargement dans…5
×

Advanced debugging  techniques in different environments

105 vues

Publié le

Advanced debugging  techniques in different environments

Publié dans : Logiciels
  • Soyez le premier à commenter

Advanced debugging  techniques in different environments

  1. 1.  Advanced debugging techniques in different environments
  2. 2. Andrii Soldatenko • Contributor in Apache Airflow, Golang, Pyhelm, python-sendgrid, tutorial of aiohttp, ansible, requests, etc. • Speaker at many conferences • blogger at t.me/golang_for_two @a_soldatenko
  3. 3. Problem:
  4. 4. Problem:
  5. 5. Problem: how to debug my program?
  6. 6. Question to audience!
  7. 7. Debugging in practise: package main import ( "fmt" ) func main() { const name, age = "Andrii", 22 fmt.Println(name, "is", age, "years old.") }
  8. 8. @a_soldatenko Interesting fact: Go version prior 1.0 included debugger OGLE
  9. 9. Current versions of Go produce DWARF Debugging Standard  http://dwarfstd.org/
  10. 10. @a_soldatenko - delve - GDB Current state of go debuggers:
  11. 11. Debug CLI util . ├── github.com/me/foo ├── cmd │ └── foo │ └── main.go ├── pkg │ └── baz │ ├── bar.go │ └── bar_test.go $ dlv debug github.com/me/foo/cmd/foo -- -arg1 valueType (dlv) break main.main Breakpoint 1 set at 0x49ecf3 for main.main() ./test.go:5 (dlv) continue
  12. 12. @a_soldatenko Debugging specific unit test go test -test.run TestFibonacciBig dlv test -- -test.run TestFibonacciBig t.me/golang_for_two
  13. 13. @a_soldatenko Conditional breakpoint package main import "fmt" func main() { nums := []int{2, 3, 4} for i, num := range nums { if num == 3 { fmt.Println(“BUG!!! index:”, i) } } } t.me/golang_for_two
  14. 14. Conditional breakpoint (dlv) b b2 hello.go:8 Breakpoint b2 set at 0x10b71e2 for main.main() ./hello.go:8 (dlv) cond b2 num == 3 (dlv) c > [b2] main.main() ./hello.go:8 (hits goroutine(1):1 total: 1) (PC: 0x10b71e2) 3: import "fmt" 4: 5: func main() { 6: nums := []int{2, 3, 4} 7: for i, num := range nums { => 8: if num == 3 { 9: fmt.Println("index:", i) 10: } 11: } 12: } (dlv) p num 3 (dlv) n
  15. 15. @a_soldatenko Debugging unit tests: example dlv test -- -test.run TestFibonacciBig (dlv) b main_test.go:6 Breakpoint 1 set at 0x115887f for github.com/andriisoldatenko/ debug_test.TestFibonacciBig() ./main_test.go:6 (dlv) c > github.com/andriisoldatenko/debug_test.TestFibonacciBig() ./ main_test.go:6 (hits goroutine(17):1 total:1) (PC: 0x115887f) 1: package main 2: 3: import "testing" 4: 5: func TestFibonacciBig(t *testing.T) { => 6: var want int64 = 55 7: got := FibonacciBig(10) 8: if got.Int64() != want { 9: t.Errorf("Invalid Fibonacci value for N: %d, got: %d, want: %d", 10, got.Int64(), want) 10: } 11: } (dlv) t.me/golang_for_two
  16. 16. Debugging unit tests: breakpoint dlv test github.com/andriisoldatenko/debugging-containerized-go- applications/ Type 'help' for list of commands. (dlv) b TestCloud1 Breakpoint 1 set at 0x113efaf for github.com/andriisoldatenko/ debugging-containerized-go-applications.TestCloud1() ./ hello_test.go:16 (dlv) c TestMy1 TestYour1 > github.com/andriisoldatenko/debugging-containerized-go- applications.TestCloud1() ./hello_test.go:16 (hits goroutine(33):1 total:1) (PC: 0x113efaf) 11: 12: func TestYour1(t *testing.T) { 13: fmt.Println("TestYour1") 14: } 15: => 16: func TestCloud1(t *testing.T) { 17: fmt.Println("TestCloud1") 18: }
  17. 17. @a_soldatenko How to set variable? 4: => 5: func main() { 6: a := 1 7: b := 2 8: fmt.Println(a, b) 9: } (dlv) set a = 10 t.me/golang_for_two
  18. 18. Call function (dlv) call myFunc(localVar, 4, "foo") https://golang.org/cl/109699 runtime: support for debugger function calls Add ability to safely call functions #119 (go-delve/delve/issues/119)
  19. 19. Call function (dlv) call t() > main.dummy() ./hello.go:18 (hits goroutine(1):1 total:1) (PC: 0x10b732d) 13: } 14: } 15: 16: 17: func dummy(){ => 18: fmt.Println("func call") 19: }
  20. 20. @a_soldatenko Debugging containerized go apps t.me/golang_for_two
  21. 21. Step 1: Dockerfile $ cat Dockerfile FROM golang:1.13 WORKDIR /go/src/app COPY . . RUN go get -u github.com/go-delve/delve/cmd/dlv CMD ["app"] $ docker build -t my-golang-app . $ docker run -it --rm my-golang-app bash
  22. 22. @a_soldatenko Step 2: operation not permitted t.me/golang_for_two $ docker run -it --rm my-golang-app bash $root@03c1977b1063:/go/src/app# dlv debug main.go could not launch process: fork/exec /go/src/app/ __debug_bin: operation not permitted
  23. 23. @a_soldatenko Step 3: :tada: t.me/golang_for_two $ docker run -it --rm —security-opt="apparmor=unconfined" —cap-add=SYS_PTRACE my-golang-app bash root@7dc3a7e8b3fc:/go/src/app# dlv debug main.go Type 'help' for list of commands. (dlv)
  24. 24. @a_soldatenkot.me/golang_for_two  Removing debugging information from the binary go build ldflags=-w …
  25. 25. @a_soldatenkot.me/golang_for_two Remote debugging containerized go apps
  26. 26. @a_soldatenko LIVE DEMO A t.me/golang_for_two
  27. 27. # Final stage FROM alpine:3.7 # Port 8080 belongs to our application, 40000 belongs to Delve EXPOSE 8080 40000 # Allow delve to run on Alpine based containers. RUN apk add --no-cache libc6-compat WORKDIR / COPY --from=build-env /server / COPY --from=build-env /go/bin/dlv / # Run delve CMD ["/dlv", "--listen=0.0.0.0:40000", "-- headless=true", "--api-version=2", "debug", "go/ src/hello", "--log" Example of Dockerfile
  28. 28. #!/usr/bin/env bash docker run -p 8080:8080 -p 40000:40000 --security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE hello-debug Docker run
  29. 29. $cat ~/.dlv/config.yml substitute-path: - {from: "/go/src/hello/", to: "/Users/ andrii/workspace/src/github.com/ andriisoldatenko/debugging-containerized- go-applications"} Let’s fix it to more readable
  30. 30. Configure Delve $HOME/.dlv/config.yml Or (dlv) config -list
  31. 31. dlv connect localhost:40000 (dlv) c > main.main() /go/src/hello/hello.go:5 (hits goroutine(1):1 total:1) (PC: 0x49b3d8) 1: package main 2: 3: import "fmt" 4: => 5: func main() { 6: a := 1 7: b := 2 8: fmt.Println(a, b) 9: } (dlv) Delve connect
  32. 32. @a_soldatenko LIVE DEMO B t.me/golang_for_two
  33. 33. @a_soldatenko GDB t.me/golang_for_two
  34. 34. @a_soldatenkot.me/golang_for_two Starting program: /x/y/foo Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8)) https://sourceware.org/gdb/wiki/PermissionsDarwin check gdb is codesigned
  35. 35. @a_soldatenko [New Thread 0xe03 of process 45828] [New Thread 0x1003 of process 45828] warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/bsd.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/darwin_vers.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/dirstat.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/dirstat_collection.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/err.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/exception.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/init.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/mach.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/stdio.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/stdlib.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/string.o': can't open to read symbols: No such file or directory. warning: `/BuildRoot/Library/Caches/com.apple.xbs/Binaries/Libc_darwin/install/TempContent/Objects/Libc.build/libsystem_darwin.dylib.build/ Objects-normal/x86_64/variant.o': can't open to read symbols: No such file or directory. Thread 2 hit Breakpoint 1, 0x0000000100000fa4 in main () (gdb) x/i $rip => 0x100000fa4 <main+4>: xor %eax,%eax (gdb) quit A debugging session is active. Inferior 1 [process 45828] will be killed. Quit anyway? (y or n) y can't open to read symbols:
  36. 36. @a_soldatenko GDB: few notes! (gdb) b main.main Breakpoint 1 at 0x10b70f0 (gdb) c The program is not being run. (gdb) run Starting program: /Users/andrii/workspace/src/ github.com/andriisoldatenko/debugging- containerized-go-applications/hello [New Thread 0xf03 of process 5994] ^C^Z [2] + 5911 suspended gdb hello
  37. 37. @a_soldatenko GDB: few notes! In Go 1.11, the debug information is compressed for purpose of reduce binary size, and gdb on the Mac does not understand compressed DWARF. (link)
  38. 38. @a_soldatenko GDB: few notes! go build -ldflags=-compressdwarf=false - gcflags=all="-N -l" -o hello hello.go ➜ go git:(master) find . -name 'runtime-gdb.py' ./src/runtime/runtime-gdb.py (gdb) source /Users/andrii/work/go/src/runtime/ runtime-gdb.py Loading Go Runtime support. ➜ debugging-containerized-go-applications git: (master) ✗ strings hello | grep gdb /usr/local/Cellar/go/1.12.7/libexec/src/runtime/ runtime-gdb.py
  39. 39. @a_soldatenko GDB: few notes! (gdb) n 6 a := 1 (gdb) n 7 b := 2 (gdb) n 8 fmt.Println(a, b) (gdb) n 1 2 9 } (gdb)
  40. 40. @a_soldatenko GDB: internals of Go slices
  41. 41. @a_soldatenko Conclusion GDB: - GDB does not understand Go programs well. - The stack management, threading, and runtime contain aspects that differ enough from the execution model GDB expects - GDB can be useful in some situations (e.g., debugging Cgo code
  42. 42. @a_soldatenko Future Reading: - Internal Architecture of Delve - slides - t.me/golang_for_two
  43. 43. Telegram channel https://t.me/golang_for_two
  44. 44. Questions ? @a_soldatenkot.me/golang_for_two

×