Lab 3. Stack/Procedure Call
For the activities in this lab, first launch your Linux.
Perform a git pull
on your repository to make sure it is up to date. Also,
print the Question Sheet in hard copy.
After this lab, you will learn:
- The basics of using GDB to debug.
- How procedure call (i.e., function call) is implemented in programs:
- How local variables are stored/organized.
- How input arguments are passed to functions.
- How a function returns to where it was called after finishing running the function.
Answer the questions in the Question Sheet as you go through the lab!
Part 1. Examine Program with GDB
Install GEF (GDB Enhanced Features)
GEF (pronounced ʤɛf - "Jeff") is the old school GDB but with fancy features. To install GEF,
- Go to the
lab3
folder. - Run the command:
sh setup_gef.sh
- Run the following command line:
sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'
- Install
gdb-multiarch
by runningsudo apt update && sudo apt -y install gdb-multiarch
Understand the GEF Interface
Once the installation finished, you can go to lab3/part1
folder. Then type
vim part1.c
to quick examine the source code to understand the functions in
the code.
Quit vim
and back to the terminal. Then run make run-gdb
to execute the code in GDB. If the installation is successful, you should be able to see some colorful output similar to the screenshot shown below:
From top to bottom, you should see the four panels which show 1) registers, 2) stack, 3) ARM code and 4) C code. Those panels will be updated instantly while the coding is running.
Stack Panel
The stack is the memory space that stores the information for function calls,
including local variables, input arguments, etc. As shown in the picture below,
GEF labels two kinds of addresses for data stored on the stack.
All addresses are in hexadecimal. The absolute address is the address of the
data in the entire memory space. The relative address is the address with
respect to the stack pointer register $sp
. For example, a relative address
0x0004
means the address is sp + 4
.
ARM Panel
The ARM panel shows the Assembly code of the program.
The Assembly code (a.k.a., instructions) is stored in the memory space. Therefore, you can see the memory address of instructions labelled. Also, the green arrow indicates the current line that is about to run but not running yet.
Source Code Panel
This panel shows the C code of the program. You can see the line number of the code. Also, similar to the ARM panel, the green arrow indicates the current line that is about to run but not running yet.
Debug with GEF/GDB
Once the program is running in gdb
(by typing make run-gdb
), we can use various commands to debug the code.
Check this GDB Quick Reference for usages/instructions of various GDB commands.
- list breakpoints (
info break
ori b
) - set breakpoints (
b main
orb filename.c:line
) - run the program again once breakpoints are set (
run
) In this lab, you don't need this command as my script will automatically run the program for you. - stepping through C code (
next
,n
,step
,s
).next
acts like Eclipse's "step over".step
acts like Eclipse's "step into". Check GDB Quick Reference for detailed instructions. - running between breakpoints (
continue
,c
) - examine a variable
len
using print:print len
- examine register
r0
using print:print $r0
- exit gdb (
quit
)
Try out these commands and answer the questions on the Question Sheet in Part1.
Part 2: Stack/Procedure Call: Local Variables
The goal of this part of the lab is to discover how local variables in functions are organized.
cd
into thelab3/part2
directory.- Open the
do_nothing.c
file usingvim
. - Pay attention to the values of the local variable
a
andb
in bothmain
anddo_nothing
function. They have the same variable names but with different values. How? Let's find out. - Type
make do_nothing.s
to generate the Assembly code. Open thedo_nothing.s
file usingvim
. And skim thru the code to get a rough idea of the various numbers that are stored in memory space. - Type
make run-gdb
to execute the program ingdb
. Set break points in the following places:
There are questions you need to answer on the Question Sheet for EACH of the break points below. Please complete all questions for a break point before running to the next break point in GDB.
- The beginning of
main
: Line 9 (It may have been set already by default) - After assigning
a
,b
inmain
: Line 11 - The beginning of
do_nothing
: Line 4 - The end of
do_nothing
: Line 6 - The end of
main
: Line 12
- The beginning of
Run the code and answer the questions on the Question Sheet in Part2.
Part 3: Stack/Procedure Call: Function Input Arguments
The goal of this part of the lab is to discover input arguments are passed to functions.
cd
into thelab3/part3
directory.- Open the
add.c
file usingvim
. - Pay attention to the values of the input arguments
a
andb
ofadd
function passed frommain
. - Type
make add.s
to generate the Assembly code. Open theadd.s
file usingvim
. And skim thru the code to get a rough idea of the various local variables that are stored in memory space. - Type
make run-gdb
to execute the program ingdb
. Set break points in the following places:
There are questions you need to answer on the Question Sheet for EACH of the break points below. Please complete all questions for a break point before running to the next break point in GDB.
- Right before calling
add
function inmain
: Line 12 - The beginning of
add
: Line 4 - The end of
add
: Line 7
- Right before calling
Run the code and answer the questions on the Question Sheet in Part3.
Part 4: Stack/Procedure Call: Function Return
The goal of this part of the lab is to discover how a function returns to where it was called after finishing running the function.
cd
into thelab3/part4
directory.- Open the
simple.c
file usingvim
. Skim thru the code to get a basic idea of the functions. - Pay attention to callers and callees of different functions, i.e., which function(s) is called by which function(s).
- Type
make simple.s
to generate the Assembly code. Open thesimple.s
file usingvim
. Pay attention to thebl
andbx
instructions that are used to branch to/from different functions. - Type
make run-gdb
to execute the program ingdb
. Set break points in the following places:
There are questions you need to answer on the Question Sheet for EACH of the break points below. Please complete all questions for a break point before running to the next break point in GDB.
- Right before calling the
add
function inmain
: Line 17 - At the beginning of the
add
function: Line 8 - Right before calling the
do_nothing
function inadd
: Line 10 - At the beginning of the
do_nothing
function: Line 4 - At the end of the
do_nothing
function: Line 5
- Right before calling the
Run the code and answer the questions on the Question Sheet in Part4.
Finishing the Lab
- Scan and Upload the signed Question Sheet to GradeScope.