0% found this document useful (0 votes)
5 views20 pages

Lab 4

The document provides an overview of debugging tools and techniques for Unix-like operating systems, emphasizing commands like strace, top, htop, dmesg, and GDB. It includes tips for debugging in Xv6, such as using print statements and understanding C pointers, along with detailed instructions on using GDB for effective debugging. Additionally, it outlines a task for students to write and debug a user-space program, highlighting the importance of setting up a proper debugging environment.

Uploaded by

nourhano021
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views20 pages

Lab 4

The document provides an overview of debugging tools and techniques for Unix-like operating systems, emphasizing commands like strace, top, htop, dmesg, and GDB. It includes tips for debugging in Xv6, such as using print statements and understanding C pointers, along with detailed instructions on using GDB for effective debugging. Additionally, it outlines a task for students to write and debug a user-space program, highlighting the importance of setting up a proper debugging environment.

Uploaded by

nourhano021
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

When You or Xv6

PANIC: Then DEBUG


Like a Detective
CSCI315 Lab 4
DEBUGGING Unix-Like OSes

● Most OSes provide a useful and easy to use tools for debugging.
● In Unix-Like OSes the following commands is very useful in debugging:
○ strace: trace system calls and signals.
○ top: display the current running processes in Linux.
○ htop: the same as previous but in enhanced view for system resource
usage, and you can filter, search, and interact with processes more easily.
○ gdb: we will see more about this later.
○ dmesg: used to display all messages from the kernel.
○ Checking Logs in /var/log/: some services and kernel messages are
logged in various log files located in the /var/log/ directory.
DEBUGGING Unix-Like OSes (cont'd)

● Examples for strace:


$ strace ls // Trace the system calls made by ls.
$ strace –o strace_output.txt ls // The same as previous but put the
// output into file "strace_output.txt".
$ strace –e open,read,write ls // Select specific syscalls to trace.
DEBUGGING Unix-Like OSes (cont'd)

● Using top command:

$ top

● Using htop command:

$ htop
DEBUGGING Unix-Like OSes (cont'd)

● Checking kernel messages using dmesg command:


$ dmesg | tail –50 // Display the last 50 messages.
$ dmesg | grep "error" // Search for error messages.
● Checking Logs in /var/log/:
$ cat /var/log/syslog | tail –50 // Show the last 50 lines of syslog,
// where you can find system-related
// messages.
Some Tips for Xv6 Debugging

● Make sure you understand C and pointers.


● If you have an exercise partially working, checkpoint your progress by
committing your code. If you break something later, you can then roll back to
your checkpoint and go forward in smaller steps.
● If your code fails a test, make sure you understand why. Insert print
statements until you understand what is going on.
● In many cases, print statements will be sufficient to debug your kernel, but
sometimes it is useful to single step through code or get a stack back-trace.
The GDB debugger can help.
Let's Examine the Following C Code
#include <stdio.h>
#include <stdlib.h>

void f(void) {
int *a = malloc(16);
int *b;

printf("1: a = %p, b = %p\n", a, b);

a = (int *) a + 1;
b = (int *) ((char *) a + 1);
printf("2: a = %p, b = %p\n", a, b);
}

int
main(int ac, char **av)
{
f();
return 0;
}
What is GDB?

● GDB, the GNU Project debugger, allows you to see what is


going on inside another program while it executes -- or what
another program was doing at the moment it crashed.
● Those programs might be executing on the same machine as
GDB (native), on another machine (remote), or on a
simulator.
● GDB can run on most popular UNIX and Microsoft Windows
variants, as well as on macOS.
What is GDB? (cont'd)

● GDB can do four main kinds of things (plus other things in support of
these) to help you catch bugs in the act:
○ Start your program, specifying anything that might affect its
behavior.
○ Make your program stop on specified conditions.
○ Examine what has happened, when your program has stopped.
○ Change things in your program, so you can experiment with
correcting the effects of one bug and go on to learn about
another.
GDB in Xv6

● The Xv6 GitHub repo provides a file called ".gdbinit" which


automatically sets up GDB for use with QEMU.
● Use make qemu-gdb instead of make qemu to start QEMU with GDB.
● In another window run gdb-multiarch or gdb to run GDB.
● If you start GDB and see a warning of the form 'warning: File
".../.gdbinit" auto-loading has been declined', edit "~/.gdbinit"
to add "add-auto-load-safe-path...", as suggested by the
warning.
GDB Commands

● Run help <command-name> if you’re not sure how to use a command.


● Most used command includes:
○ c = continue: Continue program being debugged.
○ s = step: Step program until it reaches a different line of code.
When there is a function call, it steps into the called function.
○ si = stepi: Step one assembly instruction exactly.
○ next: Same as "step" except that it steps over function calls.
○ nexti: Same as "stepi" except that it steps over function calls.
GDB Commands (cont'd)

● Most used command includes (cont'd):


○ finish: Run code until the current function return.
○ b <location> = break <location>: Sets a breakpoint at the
specified location. Locations can be memory addresses or names.
○ delete | disable | enable <breakpoint_num>: Modify breakpoints.
○ p = print: Evaluates a C expression and prints the result as its
proper type. For example, you can print the value saved in the
pointer p using this command: p /x *p.
Let's DEBUG Like a Detective

● First let's switch to syscall branch, in xv6-labs-2024 directory run


the following:
$ git restore .
$ git fetch
$ git checkout syscall
$ make clean
● Now run qemu with gdb using the following:

$ make qemu-gdb
Let's DEBUG Like a Detective (cont'd)

● Now in another terminal run


the following to open gdb:
$ gdb-multiarch

● You will get the following


similar output:
Let's DEBUG Like a Detective (cont'd)

● You can use the following command to split the terminal in two,
showing where gdb is in the source code:
(gdb) layout src

● We can use the following command to set breakpoint at syscall


function:
(gdb) break syscall
Let's DEBUG Like a Detective (cont'd)

● Now, you can run the xv6 until the point in which you put the
breakpoint using the following:
(gdb) cont

● You can use the following command to print the stack of backtrace:

(gdb) backtrace
Your Detective Sense Should
Create a Comfortable Environment Like This
Edit your code here. The source code being
executed appears here.

The xv6 is running here. GDB terminal appears here.


Let's DEBUG Like a Detective (cont'd)

● Now, Looking at the backtrace output, which function called syscall?


Ans: usertrap().
● Type n a few times to step past struct proc *p = myproc(); Once past
this statement, type the following to print the proc struct in hex (/x):

(gdb) print /x *p
● What is the value of p->trapframe->a7 and what does that value
represent? Ans: 0x7 and represents the syscall number.
● What is the name of process being run and what is the process
id? Ans: initcode and process id is 1.
Task

1. Write a program in user-space and debug it. Hint: Consult your TA for details on
the program and debug requirements. Your grade (4 marks) will be based on the
quality of your questions.
2. Setting your debugging environment in a correct way. (1 mark)
3. Set a breakpoint to investigate the error. (1 mark)
4. Backtrace the stack of error. (1 mark)
5. Find and fix the error. ((Min(p->pid, 2) - 0.5) bonus marks)
Thank you!
Do you have any questions?

You might also like