Table of Contents

Debugger Support

Student: Adriana Szekeres
Mentor: Arun Thomas
git repository: minix-debugger and pkgsrc

Abstract

The project involves porting GNU Debugger to MINIX 3 and implementing core dumping support for MINIX 3.

Current Status

GDB's functionality

DoneFunctionalityComments
backtrace Had just a problem: it tried to read from I, instead of D (even though I&D are not separate, reading the stack with I doesn't work, because the stack is not executable: safety measure!)
breakpoint Had some problems with signaling - it received SIGEMT instead of SIGTRAP
next/step Had some problems when setting the step - it receives signal 28 instead of SIGTRAP - I made a hack to make it work, but I still must investigate
print It displays correctly the value of variables
x The x commands work correctly
info/list/etc. Simple commands
attaching to a running process gdb attach works correclty, however gdb> attach (the attach command from inside GDB) has some issues wich I am not sure are related to the port
hardware watchpoints Needs access to debug registers (for MINIX they are currently not accesible in userspace)
gcore ported
testsuite I tried to port dejagnu, but it needs the setpgrp (or setpgid) funtion, which is not available in the current port of nbsd libc
gdbserver Started porting it; seems to use tcsetpgrp, but we'll see the outcome

GDB is mostly functional, however there still remain the following issues that need to be fixed:
- Function tcsetpgrp is broken, therefore GDB cannot be put in the background process group ⇒ SIGINT (generated by Ctrl+C) is delivered also to GDB (not as a captured signal, but as an actual signal)

Reported problems

SolvedProblemComments
Interactively entered commands aren't visible while typing (usability) Example: Run gdb and type “help.” Only “(gdb) _” will be seen, instead of “(gdb) help_.”
Command results begin on the same line as the input (usability) Example: Run gdb, type “help,” and press enter. The first two lines returned are “(gdb) List of classes of commands: \n,” but should be “(gdb) help \n List of commands:.”

Core dump support

Done Item Percentage Complete Comments
ELF core files support 90%

The logic for deciding when a core dump is to be performed (which signals trigger this, etc.), has already been done in PM. When a core dump is triggered, an ELF core file named “core.pid” is created into the working dir (from where the executable was loaded). The ELF file contains the program segments plus a NOTE segment which contains specific information, interpreted by GDB (e.g.the registers). To interpret the core file, you can use gdb (gdb executable core_file). The MINIX elf core format (the NOTE segment) is documented in src/common/include/sys/elf_core.h

TODOs
- stack is too big, 64 MB, even though it is not all used - Ben suggested to change the VM code that reports the segment size
- limit the size of the core file somehow?
- option to turn the core dump on (linux uses ulimit, but we don't have that on MINIX)?
- modify in readelf to recognize MINIX specific NOTE types
- re-port gcore GDB command for the new elf core format done
- implemented a new command in MINIX, gcore, that dumps the core for a given pid, in the same elf format as used for core dumping support. It uses the T_DUMPCORE flag with ptrace, inspired from netbsd, [3] done
- …

Status Reports

Week 1:

- GDB 7.2 not compatible with binutils 2.17 (GDB's 7.2 BFD supports elf with a different symbol - TODO: post some details)
- Started porting GDB 6.8 (the most recent with the same BFD as binutils 2.17)
- reading an interesting guide to porting GDB [1] (but it is just for porting architectures), also GDB Internals [2].

Week 2:

- GDB 6.8 compiles, except for one error (defs.h and curses.h both define the function fatal) - for now, just rename curses.h in /usr/pkg/gcc44/../include-fixed/curses.h and /usr/include/curses.h before configuring GDB - I made three patches to compile GDB with ./configure –disable-tui && make.

Week 3:

- I fixed the reading from registers and stack. Backtrace now works (it also reads the function arguments correctly from the stack). I must do though more testing. I noticed some problems in reading the symbols which I have to solve.

Week 4 & 5:

I fixed the signal handling (MINIX sends a SIGEMT instead of a SIGTRAP when executing an int 3 instruction; also, during a next/step command, it sends signal 28, instead of SIGTRAP - for now I put a hack there until I understand the reason and it works). What still needs to be fixed:
- the signal hack (still have to check in infrun.c)
- reading from memory (x commands)

Week 6:

GDB is mostly functional, with some remaining issues that need to be fixed. The problem with the stack is GDB's itself problem (maybe some lack of symbol information), not the porting problem (I get the same ??, with the same example on my Ubuntu).

I tried to make a new pkgsrc package for GDB-6.8 but I am facing some compilation errors with pkgsrc. I will try to push the package as soon as possible. Until now, it can be taken from the git repository (the kernel must also be recompiled as there are two new syscalls).

Week 7:

I made a package for GDB to be integrated with pkgsrc. There are still some issues to be fixed, like conflicts between libraries. I also checked the gcore functionality for GDB, but it doesn't work as it is target specific and I must look into it. I also tried to port dejagnu to run the testsuite, but it needs tcl-expect which needs function setpgrp (which is a bit difficult to implement as MINIX lacks job control). So I will focus on making the package work cleanly and then will switch to gcore functionality.

Week 8:

Started working on the gcore functionality inside GDB. Basically it required the implementation of a function that returns the mapping of the program segments in memory. I studied a bit the ELF format (not that complicated as I thought). The function basically reads from /proc/pid/map. However, there is the same problem with reading from I or D. To solve the stack issue, I made GDB read only from D space, because I didn't see when would it read from I, but now it seems this is not longer valid so we have to modify some things in GDB. I will ask on the GDB developers forum, in case I missed something with “GDB on separate I&D systems”.

Week 9:

The gcore command is ported. However, there is an issue. It reads the whole 64MB of stack and it takes much to dump a core. I will switch to core dump in MINIX (I added a header in include/sys, procfs.h, it is an interface between the core dumps generated by the OS and GDB).

Week 10:

I implemented the core dumping support. There are still some minor issues to be solved. After I fix them, I will return to the stack issue (although, it takes only several seconds to dump the core - as I vircopy CLICKSIZE bytes at a time, but for the gcore command in GDB it takes almost an hour, as it uses sys_trace without the T_GETRANGE optimization, so copies sizeof(long) bytes at a time, hence lots of calls to sys_trace are needed).

Week 11:

Using “procfs.h” header was not acceptable, so I had to teach BFD to parse correctly the core file. (The default parsing functions in BFD required the procfs.h header). Mostly, the file that needed to be modified was bfd/elf.c and I implemented something similar to NETBSD. However, I kept to minimum the information that we put into the NOTE segment of the core file. This information could be enriched with information about, for example, threads (when MINIX will support them).

Design

The project consists of two parts: porting GDB to MINIX and implementing core dumping support for MINIX.

The first part should be in principle straight-forward (try to compile and fix the incompatibilities on the fly) as MINIX already has GCC, the ptrace system call, BFD (read/write various object formats), which are needed by GDB. I’ve looked a bit on the ptrace call implementation (part in PM – trace.c – part in kernel, system task – do_trace.c) and it seems that it supports a fair amount of the functionality of the ptrace system call (even ATTACH and DETACH). Porting GDB doesn’t need much of a design, except for the cases when OS-specific functionality is needed or must be implemented. One example could have been the ptrace system call. I don’t know now if there are more major impediments to a straight-forward port of GDB. A good reference for this part is [0] in which there are explained many problems that can appear when porting code to MINIX.

To get an idea on how to implement the second part, dumping support for MINIX, I’ve looked in the previous versions of MINIX, <= 3.1.2, which had core dumping functionality implemented in the PM server, where the signaling mechanisms are implemented (signal.c). There, they used kernel calls to the system task to acquire the relevant information about the process (ex. stack pointer). After 3.1.2, the core dumping was planned to be moved to the VFS, in pm_dumpcore() function. I am not much familiar with the core dumping file format but I assume it must be the same as an executable and must contain all the process’s memory segments, as listed by the dumpcore command implemented in MINIX (commands/simple/dumpcore.c), plus the registries values (to know what was the state of the process). I looked a bit into GDB’s gcore command implementation which makes extensive use of BDF. Basically, gcore’s functionality must also be implemented in pm_dumpcore().The plan would be first to port GDB, and get familiar with its implementation, especially the gcore command, as this would help for the second part of the project. I expect that much of the GDB’s functionality to be ported until the first mid-term evaluation (15 July). Some code that doesn’t compile and is not critical (ex. gdb thread debugging facility) could be skipped/commented at first to get the important part working as soon as possible.

Schedule

Include the timeline from your proposal here and all deliverables and milestones.

Pre-Coding Period (Apr 25 - May 22)

Week 1 (May 23 - May 29):

Week 2 (May 30 - Jun 5):

study GDB’s internals and make a tentative to port it and identify the major drawbacks (e.g. if it needs more functionality to be implemented in MINIX). Also, identify the critical parts that must be ported right away and which parts could be skipped for the moment.

Week 3 (Jun 6 - Jun 12):

Week 4 (Jun 13 - Jun 19):

Week 5 (Jun 20 - Jun 26):

Week 6 (Jun 27 - Jul 3):

Week 7 (Jul 4 - Jul 10) - MIDTERM:

work on porting GDB, solve the problems that appear. (At the end of week 7 we should have a functional GDB port)

Week 8 (Jul 11 - Jul 17):

study the core dump file format (this will be needed for the core dump functionality)

Week 9 (Jul 18 - Jul 24):

make a design for the core dump functionality for MINIX. (e.g. which signals will trigger the core-dump; where should it be implemented (vfs or fs), the format of the file; etc.)

Week 10 (Jul 25 - Jul 31):

Week 11 (Aug 1 - Aug 7):

Week 12 (Aug 8 - Aug 14):

implement and test the new functionality

Week 13 (Aug 15 - Aug 21) - FINAL:

finish the testing and documentation

Resources