Familiarity with your environment is crucial for productive development and debugging. This page gives a brief overview of the JOS environment and useful GDB and Bochs commands. Don't take our word for it, though. Read the GDB and Bochs manuals. These are powerful tools that are worth knowing how to use.
Debugging tips: | Kernel User environments |
---|---|
Reference: | JOS makefile JOS obj/ GDB Bochs Emulator |
All of the tools that you need to execute and complete the labs are installed in your course virtual machine. Details TBA.
If you wish to compile and run the tools on your own machine, the information that you need is as follows. Note that we cannot guarantee that these tools will run on your computer, and we cannot support these tools on your own computer. However, the tools should run on recent versions of Linux. The tools should also run under Windows with the help of Cygwin. Install cygwin, and be sure to install the flex and bison packages (they are under the development header).
Most modern Linux distributions and BSDs have an ELF toolchain compatible with the JOS labs. That is, the system-standard gcc, as, ld and objdump should just work. The lab Makefile should automatically detect this. If the makefile fails to detect your build tools, you can specify their location by adding the following line to conf/env.mk:
GCCPREFIX=
If you are using something other than standard x86 linux or BSD, you will need the GNU C compiler toolchain, configured and built as a cross-compiler for the target 'i386-jos-elf', as well as the GNU debugger, configured for the i386-jos-elf toolchain. You can download versions that are known to work with JOS via the following links, although more recent versions of gcc and binutils, and GDB should work too:
Once you've unpacked these archives, run the following commands as root:
# cd binutils-2.19
# ./configure --target=i386-jos-elf --disable-nls
# make
# make install
# cd ../gcc-4.1.2
# ./configure --target=i386-jos-elf --disable-nls --without-headers \
--with-newlib --disable-threads --disable-shared \
--disable-libmudflap --disable-libssp
# make
# make install
# cd ../gdb-7.2a
# ./configure --target=i386-jos-elf --program-prefix=i386-jos-elf- \
--disable-werror
# make
# make install
Then you'll have in /usr/local/bin a bunch of binaries with names like i386-jos-elf-gcc. The lab makefile should detect this toolchain and use it in preference to your machine's default toolchain. If this doesn't work, there are instructions on how to override the toolchain inside the GNUmakefile in the labs.
The standard version of gdb does not correctly handle the transition to long mode during JOS boot, yielding a "Packet too long" error. The patch below will fix this:
For the VM environment, we have pre-patched gdb packages you should install. For debugging 64-bit code on a 32-bit platform, you need both gdb and gdb-multiarch. Below we post patched Ubuntu 10.04 packages.
Download and install these packages on your course VM with the following commands
# wget http://www.cs.stonybrook.edu/~porter/courses/cse506/f12/gdb_7.2-1ubuntu11jos_i386.deb
# wget http://www.cs.stonybrook.edu/~porter/courses/cse506/f12/gdb-multiarch_7.2-1ubuntu11jos_i386.deb
# sudo dpkg -i gdb_7.2-1ubuntu11jos_i386.deb gdb-multiarch_7.2-1ubuntu11jos_i386.deb
To build gdb against another version on Ubuntu or Debian, e.g., for home use, follow these steps:
dpkg-source -x gdb-xxxxx.dsc (the .dsc you installed)
cd gdb-xxx (a newly created directory)
sudo apt-get build-dep gdb
download gdb-7.2-arch-remote-change.patch
patch -p1 < gdb-7.2-arch-remote-change.patch
sudo debian/rules binary
Bochs is a modern and fast PC emulator. Bochs is also the first emulator to support emulation of vmx and extended page tables.
We recommend using the most recent version (2.6.2) of bochs for this assignment. An ubuntu .deb file is available here.
GDB is your friend. Use the bochs-gdb target (or its bochs-gdb-nox variant) to make BOCHS wait for GDB to attach. See the GDB reference below for some commands that are useful when debugging kernels.
If you're getting unexpected interrupts, exceptions, or triple faults, you can ask BOCHS to generate a detailed log of interrupts using the -d argument.
To debug virtual memory issues, try the BOCHS monitor commands info mem (for a high-level overview) or info pg (for lots of detail). Note that these commands only display the current page table.
(Lab 4+) To debug multiple CPUs, use GDB's thread-related commands like thread and info threads.
GDB also lets you debug user environments, but there are a few things you need to watch out for, since GDB doesn't know that there's a distinction between multiple user environments, or between user and kernel.
You can start JOS with a specific user environment using make run-name (or you can edit kern/init.c directly). To make BOCHS wait for GDB to attach, use the run-name-gdb variant.
You can symbolically debug user code, just like you can kernel code, but you have to tell GDB which symbol table to use with the symbol-file command, since it can only use one symbol table at a time. The provided .gdbinit loads the kernel symbol table, obj/kern/kernel. The symbol table for a user environment is in its ELF binary, so you can load it using symbol-file obj/user/name. Don't load symbols from any .o files, as those haven't been relocated by the linker (libraries are statically linked into JOS user binaries, so those symbols are already included in each user binary). Make sure you get the right user binary; library functions will be linked at different EIPs in different binaries and GDB won't know any better!
(Lab 4+) Since GDB is attached to the virtual machine as a whole, it sees clock interrupts as just another control transfer. This makes it basically impossible to step through user code because a clock interrupt is virtually guaranteed the moment you let the VM run again. The stepi command works because it suppresses interrupts, but it only steps one assembly instruction. Breakpoints generally work, but watch out because you can hit the same EIP in a different environment (indeed, a different binary altogether!).
gdb obj/kern/kernel
target remote localhost:1234
When building JOS, the makefile also produces some additional output files that may prove useful while debugging:
See the GDB manual for a full guide to GDB commands. Here are some particularly useful commands for 6.828, some of which don't typically come up outside of OS development.
BOCHS represents each virtual CPU as a thread in GDB, so you can use all of GDB's thread-related commands to view or manipulate BOCHS's virtual CPUs.
BOCHS includes a built-in monitor that can inspect and modify the machine state in useful ways. To enter the monitor, press Ctrl-a c in the terminal running BOCHS. Press Ctrl-a c again to switch back to the serial console.
For a complete reference to the monitor commands, see the bochs manual. Here are some particularly useful commands:
r|reg|regs|registers List of CPU integer registers and their contents
sreg Show segment registers and their contents
dreg Show debug registers and their contents
creg Show control registers and their contents
info cpu List of all CPU registers and their contents
info eflags Show decoded EFLAGS register
info break Information about current breakpoint status
info tab Show paging address translation
info device Show state of the specified device
show [string]
Toggles show symbolic info (calls to begin with).
show - shows current show mode
show mode - show, when processor switch mode
show int - show, when interrupt is happens
show call - show, when call is happens
show ret - show, when iret is happens
show off - toggles off symbolic info
show dbg-all - turn on all show flags
show dbg-none - turn off all show flags
BOCHS also takes some useful command line arguments, which can be
passed into the JOS makefile using the BOCHSEXTRA variable.
Last updated: 2025-04-11 21:09:30 -0400 [validate xhtml]