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

Debuggers in depth

Debuggers in depth

1. How computers run programs: how program counters, stack pointers and the call stack work
2. How processes can be controlled: We will talk about Linux, but all OSes have some way of allowing that
3. How the compiled binary maps back to the original source: symbols
4. How goroutines differ from threads: A debugger's point of view

Avatar for Sourya Vatsyayan

Sourya Vatsyayan

May 16, 2020

Other Decks in Programming

Transcript

  1. package main import "fmt" func main() { !// main.main numbers

    !:= make([]int, 5) for i !:= 0; i < 5; i!++ { numbers = append(numbers, i) } numbers = append(numbers, 123) englishNumbers !:= []string{“zero", “one", “two", “three", “four", "one-twenty- three"} for i !:= 0; i < len(englishNumbers); i!++ { fmt.Printf("%d: %s\n", numbers[i], englishNumbers[i]) } }
  2. !// expected output 0: zero 1: one 2: two 3:

    three 4: four 123: one-twenty-three !// real output 0: zero 0: one 0: two 0: three 0: four 0: one-twenty-three
  3. All debuggers really do is let us control the execution

    of programs And let us read/write memory and registers.
  4. Computers have CPUs -> Registers - Program Counter - Stack

    pointer - Base pointer - Stack frame
  5. We could think of any program as a stack machine.

    !// d = (2-x) * (y+5)
 push 2
 push x
 sub
 push y
 push 5
 add
 multiply
 pop d
  6. Stuff in runtime.main
 —————————
 Return address
 —————————
 Stuff in main.main


    —————————
 Call main.f
 Resize stack if needed()
 Go back to calling main.f <— delve
 —————————
 BP —> SP —> Stack frame
  7. - debug_line: file:line mapped to the instruction - debug_frame: the

    stack traces - debug_info: trees of types, variables, functions What do we need
  8. A Curious Case for append - Cannot be “stepped into”

    - Not a “real” function - Some runtime operations may be included with compiled code
  9. How are goroutines different - Stack maybe resized - To

    do so, there are runtime calls - Other debuggers are not aware of the runtime - Delve takes care of that