As I get more familiar with the Pintos environment, I want to save notes on techniques I've found improved my quality of life when debugging through the assignments. Please don't add any comments that discuss project solutions, but feel free to contribute your own favorite ways of improving the debugging process, since I'm hoping we can create a trail of breadcrumbs for future students.
One of the first things I like to do is ensure I can use the up arrow to access commands from a previous gdb session, since debugging tends to involve a lot of repetition!
echo 'set history save on' >> ~/.gdbinit
Most of the time the first thing you'll want to do when starting a gdb session is enter the debugpintos
command to connect to your pintos session. To save on typing you can add this to your command line instead, using the -ex
flag:
pintos-gdb -ex "debugpintos" kernel.o
If you wanted to get really fancy you could create a new alias to do this, but I find having it in my shell history is easy enough.
The list data structure is heavily used by the kernel so it's handy to be able to view all values with the dumplist
macro.
dumplist &ready_list thread elem
dumplist &all_list thread allelem
The first thing that threw me was a typo in E.5.2 in the debugging tools chapter. it suggests the following command to list all threads stack traces:
btthreadlist all_list allelem
This fails with Attempt to take address of value not located in memory.
, but that's just because an &
got missed out. Luckily the correct form is listed elsewhere in the document:
btthreadlist &all_list allelem
We're now passing in the address of all_list instead of the value, but I was puzzled to see the error Attempt to assign to an unmodifiable value.
when running it.
After looking at the macro code, I guessed that something had changed in the register protections in gdb since that code was written or I was in a weird state because of the page fault. I switched to using my local copy of the macros (by running gdb -x ~/pintos/src/misc/gdb-macros kernel.o
instead of just pintos-gdb kernel.o
and then experimented with the implementation of btthread. I saw in btpagefault that $eip
seemed the most critical so I made the following changes:
peteward@myth58:~/pintos$ git diff src/misc/gdb-macros
diff --git a/src/misc/gdb-macros b/src/misc/gdb-macros
index 3babb52..0c388a7 100644
--- a/src/misc/gdb-macros
+++ b/src/misc/gdb-macros
@@ -45,18 +45,13 @@ define btthread
bt
else
set $saveEIP = $eip
- set $saveESP = $esp
- set $saveEBP = $ebp
- set $esp = ((struct thread *)$arg0)->stack
- set $ebp = ((void**)$esp)[2]
- set $eip = ((void**)$esp)[4]
+ set $myESP = ((struct thread *)$arg0)->stack
+ set $eip = ((void**)$myESP)[4]
bt
set $eip = $saveEIP
- set $esp = $saveESP
- set $ebp = $saveEBP
end
end
document btthread
This executed without any errors, but didn't always show useful information for each thread, so I'm not sure it's the complete solution.
The btpagefault that automatically executes after a page fault displays the call stack for the crashing process, but it doesn't let you jump up and down the stack to inspect locals or view the source.
I found setting $eip
would let me work around this, and allow me to look at variables and code at all levels.
set $saveeip = $eip
set $eip = ((void**)$esp)[1]
Then you can run the usual commands:
bt
frame 4
list
Once you're done, you can restore the original stack pointer with:
set $eip = $saveeip
I've been modifying the macro code a bit, so to use my local copy instead of the main one in AFS I invoke gdb with:
gdb -x ~/pintos/src/misc/gdb-macros kernel.o
When gdb is stopped, you're almost always within a function. You can jump up and down the call stack using the frame
command (for example frame 3
to jump to the #3 function listed by bt
). You can get a lot of useful context about the function you're in from these commands.
To show the values of local variables, run info locals
.
To show the values of the function input arguments, run info args
.
To look at the lines of source code around the currently executing line, run list
.
https://www.scs.stanford.edu/24wi-cs212/pintos/pintos_10.html
https://cs162.org/static/proj/pintos-docs/docs/development/gdb/