User Tools

Site Tools


developersguide:debugging

Debugging code in Minix

Unfortunately that is a lot of what you do while programming. This page collects some tips.

Serial in/out

For debugging and diagnostics, it is smart to always have serial out enabled to another machine (whether in a VM or not). It becomes easy to log your own in-kernel/-driver/-server printf()s, and to interrogate the system about its state. See SerialOut for full details.

GDB from the outside

GDB within Minix isn't fully supported.

It is very convenient to debug Minix itself by attaching GDB to an emulator running it. VM-specific examples and general instructions follow.

Example 1: qemu/kvm

  • In short, let the linaro qemu start with the gdbserver (-s is a convenient shorthand for -gdb tcp::1234).
  • Add -S if you don't want it to start executing right away, i.e. start as if it were in a breakpoint.
  • Then attach to it with a gdb running elsewhere (there in the following).

Example 2: VMware

  • Edit the .vmx file describing your virtual MINIX to append the following
debugStub.listen.guest32 = "TRUE"
debugStub.hideBreakpoints = "TRUE" # Allows gdb breakpoints to work
	# really, prevent VMware (and GDB) to write INT3 into guest memory
#debugStub.listen.guest32.remote = "TRUE"
	# Allows debugging from a different computer / VM instead of localhost.
	# The IP for remote debugging will be that of the host.
#monitor.debugOnStartGuest32 = "TRUE"
	# Breaks into debug stub on first instruction (warning: in BIOS!)
	# This will halt the VM at the very first instruction at 0xFFFF0,
	# you could set the next breakpoint to break *0x7c00 to break
	# when the bootloader is loaded by the BIOS

Emulator independant

Once you did the above

  • Start the virtual machine
  • Connect the external gdb to listening host on port 8832
 (gdb) target remote localhost:8832

Then you can already start following the thing here, instruction by instruction.

  • Have the executables you want debugged available there, so you can load them so gdb knows its symbols (and source line numbers if compiled with -g). then you have source line info.
  • Compiling executables (and their libraries) you want debugged with -g helps a lot - it gives more source code line info and less weird optimization things happen. Specify DBG=-g on the make line to enable this, verify it does what you want by adding MAKEVERBOSE=2.
  • Load the executables' symbols into gdb so stacktraces etc. can be decoded nicely.
  • Virtual addresses are usually not unique, so setting breakpoints and such won't work unless you specifically compile the executable you are interested in to be linked at a unique location. This already is true for the kernel of course.

Making addresses unique

Setting breakpoints and watchpoints is easier if all addresses are unique. But because the same virtual address space is shared between many processes, this isn't usually true. To make your process get loaded at a unique location, tell the linker to link it to a high address. To do that, add -Wl,-Ttext=0x800000 to the gcc link command line. E.g. in the VFS Makefile:

LDADD+=        -lsys -ltimers -lexec -lmthread -Wl,-Ttext=0x800000
developersguide/debugging.txt · Last modified: 2014/11/13 09:20 by lionelsambuc