devsoc-unsw / devsoc-unsw/structs.sh

enh(debugger): preemptive local variable initialisation

Open
#760 3 comments 1 reaction 1 assignee Claimed by @EzyCzy View on GitHub
Dominant language
TypeScript
Stars
40
Forks
9
PR merge metrics
No merged PRs in 30d

Description

Recall that in C, local variable declarations are interleaved with other statements, as shown in the example below.
```c
#include

#define print printf("doing something...\n")

int main(int argc, char **argv)
{
print;
int uninitted_int;
print;
int initted_int = 2;
print;
int *uninitted_intp;
print;
int *initted_intp = &initted_int;
print;
uninitted_int = 1;
print;
uninitted_intp = &uninitted_int;
print;
}
```

However, when a function is called and its stack frame is set up, **all** local variables are allocated **immediately**. They are, however, not but not initialised. They are initialised only when they are "initialised" in the C source, as shown in the example below.

```
(.venv) ‹[para]› ~/Code/structs.sh/debugger = gcc src/debugger/test/test_uninit.c -g -o a
(.venv) ‹[para]› ~/Code/structs.sh/debugger = gdb -q a
Reading symbols from a...
(gdb) start
------
7 print;
(gdb) info locals
uninitted_int = 65535
initted_int = -136153344
uninitted_intp = 0xffffffffeb98
initted_intp = 0x20
(gdb) n
doing something...
9 print;
(gdb) n
doing something...
10 int initted_int = 2;
(gdb) n
11 print;
(gdb) info locals
uninitted_int = 65535
initted_int = 2
uninitted_intp = 0xffffffffeb98
initted_intp = 0x20
(gdb)
```

The core issue is that the debugger will preemptively list all local vars. Most of which will be uninitialised and that is problematic since (1) uninitialised data can confuse the end users (students) when they see junk values like `-136153344` and (2) uninitialised pointers will confuse `debugger.trace()` into trying to find, say, the next linked list node at some garbage memory location like `0x20`.

**Your task** is to see that all local variables are preemptively zero-initialised immediately after a function call.

# Hint 1

- You can use `-stack-list-variables --thread 1 --frame 0 --all-values` to find variables from the topmost frame. It returns **both** arguments and locals, so you must filter out objects that contain `arg="1"`.
- You can use `-var-create * ` to create a GDB variable bound to a C variable.
- You can then use `-var-assign ` to assign it a value (for this issue, assign it zero)
- Don't forget to `-var-delete ` for posterity
- Refer to `debugger.var_details()` for how to generate and manage variable names

Example:

```
(.venv) ‹[para]› ~/Code/structs.sh/debugger = gdb -q a --interpreter=mi4
------
(gdb)
start
------
(gdb)
------
(gdb)
-stack-list-variables --thread 1 --frame 0 --all-values
^done,variables=[{name="argc",arg="1",value="1"},{name="argv",arg="1",value="0xffffffffeb98"},{name="uninitted_int",value="65535"},{name="initted_int",value="-136153344"},{name="uninitted_intp",value="0xffffffffeb98"},{name="initted_intp",value="0x20"}]
(gdb)
-var-create x * uninitted_int
^done,name="x",numchild="0",value="65535",type="int",thread-id="1",has_more="0"
(gdb)
-var-assign x 0
^done,value="0"
(gdb)
-var-delete x
^done,ndeleted="1"
(gdb)
-stack-list-variables --thread 1 --frame 0 --all-values
^done,variables=[{name="argc",arg="1",value="1"},{name="argv",arg="1",value="0xffffffffeb98"},{name="uninitted_int",value="0"},{name="initted_int",value="-136153344"},{name="uninitted_intp",value="0xffffffffeb98"},{name="initted_intp",value="0x20"}]
(gdb)
------
```

# Hint 2

- You can detect when you've entered a function by listening to asynchronous exec `(*)` outputs
- Refer to `src/demo.py` on how to use `@debug.on_oob` to catch them

Example:

```
(.venv) ‹[para]› ~/Code/structs.sh/debugger = gdb -q a --interpreter=mi4
------
(gdb)
-break-insert main
------
(gdb)
-exec-run
------
(gdb)
------
*stopped,reason="breakpoint-hit",disp="keep",bkptno="1",frame={addr="0x0000aaaaaaaa0764",func="main",args=[{name="argc",value="1"},{name="argv",value="0xffffffffeb98"}],file="src/debugger/test/test_uninit.c",fullname="/home/tosha/Code/structs.sh/debugger/src/debugger/test/test_uninit.c",line="7",arch="aarch64"},thread-id="1",stopped-threads="all",core="0"
(gdb)
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.