GDB

GDB Debugger

1. Introduction

1
2
3
4
5
6
7

- Allows programmers to see inside and interact/modify with all components of a programs,
including information inside the registers.
- Allows programmers to walk through the program step by step, including down to 
instruction level, to debug the program.

1
2
3
4
5
6
7
8
9
10
11
## 2. tmux


- Our workspace is limited within the scope of a single terminal (a single shell) 
to interact with the operating system. 
- `tmux`: *terminal multiplexer*. 
- `tmux` allows user to open multiple terminals and organize split-views (panes) 
within these terminals within a single original terminal. 
- We can run/keep track off multiple programs within a single terminal. 

1
tmux new -s csc231

:::{image} fig/gdb/01.png :alt: A new tmux windows :class: bg-primary mb-1 :height: 600px :align: center :::

1
tmux ls

:::{image} fig/gdb/02.png :alt: List active tmux sessions :class: bg-primary mb-1 :height: 600px :align: center :::

:::{image} fig/gdb/03.png :alt: Go back to main terminal :class: bg-primary mb-1 :height: 50px :align: center :::

:::{image} fig/gdb/04.png :alt: Go back to the previous tmux session :class: bg-primary mb-1 :height: 600px :align: center :::

:::{image} fig/gdb/05.png :alt: Listing multiple tmux sessions :class: bg-primary mb-1 :height: 600px :align: center :::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


- Create a new session called `p1`.

~~~bash
tmux new -s p1
~~~

- Splits terminal into vertical panels: `Ctrl-b` then `Shift-5` (technical documents
often write this as `Ctrl-b` and `%`).

:::{image} fig/gdb/06.png
:alt: Tmux session with two vertical panels
:class: bg-primary mb-1
:height: 600px
:align: center
:::

- Splits terminal (the current pane) into horizontal panels: `Ctrl-b` then `Shift-'` 
( technical documents often write this as `Ctrl-b` and `"`).

:::{image} fig/gdb/01.png
:alt: Tmux sessions with one vertical panel and the other vertical panel splitted into two horizontal panels
:class: bg-primary mb-1
:height: 600px
:align: center
:::

- Toggle between panels: `Ctrl-b` then `Space`.
- To move from one panel to other directionally: `Ctrl-b`then the corresponding 
arrow key. 
- Typing `exit` will close the pane with the activate cursor.  
- Run `exit` multiple times to completely close out the `p1` session. Pay attention 
to not get out of the container. 

:::{image} fig/gdb/08.png :alt: Tmux with multiple panels :class: bg-primary mb-1 :height: 600px :align: center :::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


- What we did in the previous hands-on was not quite usable. 
- We need to be able to adjust the panes to the proper sizes. 
- This can be done by issuing additional commands via tmux's command line terminal.
- Run `tmux ls` to check and `tmux kill-session` to clean up all existing 
tmux sessions. 
- Create a new session called `p1`.
- Split the session horizontally.
- Windows:
  - You can adjust the size of two adjacent horizontal panes by **press and hold** `Ctrl-b` then 
the left/right arrows.
  - You can adjust the size of two adjacent vertical panes by **press and hold** `Ctrl-b` then 
the up/down arrows.
- Mac and Windows:
  - Press `Ctrl-b` then `Shift-;` to open up the command line bar at the bottom. Type in:
    - `rezise-pane -U 20` then press `Enter` to move the horitontal bar up 20 pixels
    - `rezise-pane -D 20` then press `Enter` to move the horitontal bar down 20 pixels
    - `rezise-pane -L 20` then press `Enter` to move the vertical bar left 20 pixels
    - `rezise-pane -R 20` then press `Enter` to move the vertical bar right 20 pixels
  - You can adjust the number for aesthetic purpose. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

## 3. Running and exiting gdb


- Create a new tmux session called `gdb`. 
- Run the following command in the `gdb` session.

~~~bash
cd 
git clone https://github.com/longld/peda.git
echo "source $HOME/peda/peda.py" > $HOME/.gdbinit
gdb
~~~


- To exit from gdb type `q` and hit `Enter`. 

:::{image} fig/gdb/09.png
:alt: Color-coded gdb
:class: bg-primary mb-1
:height: 600px
:align: center
:::

1
2
cd ~/csc231/intro-c
gcc -g -o hello hello.c
1
2
3
cd ~/intro-c
gdb hello
gdb-peda$ run

:::{image} fig/gdb/10.png :alt: Running gdb on hello.c :class: bg-primary mb-1 :height: 800px :align: center :::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

- This is a continue from the previous slide's tmux windows

- We need to set a `breakpoint`:
  - Could be a line number or
  - Could be a function name

~~~bash
gdb-peda$ b main
gdb-peda$ run
~~~

:::{image} fig/gdb/11.png
:alt: Set break points and run
:class: bg-primary mb-1
:height: 800px
:align: center
:::

:::{image} fig/gdb/12.png :alt: Scrolling in tmux :class: bg-primary mb-1 :height: 800px :align: center :::

1
2
3
4
5
6
7
8
9
10
11

- Type `q` or `Esc` to quit scrolling mode. 
- To continue executing the next line of code, type `n` then `Enter`. 
- Turn back into the scrolling mode and scroll back up
to observe what happens after typing `n`. 
- What is the next line of code to be executed?
- Type `n` three more times to observe the line of codes being executed
and the final warning from `gdb`. 
- Type `q` to exit from `gdb`. 

1
2
gcc -g -o malloc-1 malloc-1.c
cat -n malloc-1.c
1
2
3
gdb malloc-1
gdb-peda$ b main
gdb-peda$ run

::::{dropdown} After initial run command :::{image} fig/gdb/malloc-01.png :alt: After initial run command :class: bg-primary mb-1 :height: 800px :align: center ::: ::::

::::{dropdown} After running int main(int argc, char *argv[]) { :::{image} fig/gdb/malloc-02.png :alt: After running int main(int argc, char *argv[]) { :class: bg-primary mb-1 :height: 800px :align: center ::: ::::

::::{dropdown} After running void *p = malloc(4); :::{image} fig/gdb/malloc-02.png :alt: After running void *p = malloc(4); :class: bg-primary mb-1 :height: 800px :align: center ::: ::::

::::{dropdown} After running int *ip = (int *)p; :::{image} fig/gdb/malloc-03.png :alt: After running int *ip = (int *)p; :class: bg-primary mb-1 :height: 800px :align: center ::: ::::

::::{dropdown} After running *ip = 98765; :::{image} fig/gdb/malloc-04.png :alt: After running *ip = 98765; :class: bg-primary mb-1 :height: 800px :align: center ::: ::::

::::{dropdown} After finish :::{image} fig/gdb/malloc-05.png :alt: After finish :class: bg-primary mb-1 :height: 800px :align: center ::: ::::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114


- In the top pane, compile `array-4.c` in debugging mode. 

~~~bash
gcc -g -o array-4 array-4.c
cat -n array-4.c
~~~


- In the bottom pane, quit the current gdb session and 
rerun it on the recently created `array-4` executable as follows: 

~~~bash
gdb array-4
gdb-peda$ b main
gdb-peda$ run
~~~

::::{dropdown} After initial run command
:::{image} fig/gdb/array-01.png
:alt: After initial run command
:class: bg-primary mb-1
:height: 800px
:align: center
:::
:::: 

- The next line of code to be run is `int main(int argc, char *argv[]) {`
- Type `n` and `Enter` to run the next line of code: `int main(int argc, char *argv[]) {`
- Run the following commands and observe the outcomes: 
  - `p argc` 
  - `p argv[0]` 
  - `p argv[1]` 
  - `p argv[2]`
  - `p argv[3]` 
  - `p argv[4]` 
  - ...

::::{dropdown} After running int main(int argc, char *argv[]) {
:::{image} fig/gdb/array-02.png
:alt: After running int main(int argc, char *argv[]) {
:class: bg-primary mb-1
:height: 800px
:align: center
:::
:::: 

- Type `n` and `Enter` to run the next line of code: `size = atoi(argv[1]);`
- Observe that dreaded `Segmentation fault` notice: `SIGSEGV` 
- Type `q` to exit `gdb`.

::::{dropdown} After running size = atoi(argv[1]);
:::{image} fig/gdb/array-03.png
:alt: After running size = atoi(argv[1]);
:class: bg-primary mb-1
:height: 800px
:align: center
:::
:::: 

- Rerun gdb on `array_4` executable as follows: 

~~~
gdb array-4
gdb-peda$ b main
gdb-peda$ run 3
~~~

::::{dropdown} After initial run command
:::{image} fig/gdb/array-04.png
:alt: After initial run command
:class: bg-primary mb-1
:height: 800px
:align: center
:::
:::: 


- The next line of code to be run is `int main(int argc, char *argv[]) {`
- Type `n` and `Enter` to run the next line of code: `int main(int argc, char *argv[]) {`
- Run the following commands and observe the outcomes: 
  - `p argc` 
  - `p argv[0]` 
  - `p argv[1]` 
  - `p argv[2]`
  - `p argv[3]`
  - ...

::::{dropdown} After running int main(int argc, char *argv[]) {
:::{image} fig/gdb/array-05.png
:alt: After running int main(int argc, char *argv[]) {
:class: bg-primary mb-1
:height: 800px
:align: center
:::
:::: 

- Type `n` and `Enter` to run the next line of code: `size = atoi(argv[1]);`
- Run the following commands and observe the outcomes: 
  - `p size` 
  - `p &size`

::::{dropdown} After running size = atoi(argv[1]);
:::{image} fig/gdb/array-06.png
:alt: After running size = atoi(argv[1]);
:class: bg-primary mb-1
:height: 800px
:align: center
:::
:::: 


```