MIT6.828: Why do I get a pagefault when I use pipe the first time in my xv6 operating system?

  Kiến thức lập trình

I am now self-learning mit6.828, this course is about studying operating system xv6. This system boot with initiating memory system, user environment system, trap system ,multiprocessors and a file system(a user environment that manipulate 3GB disk space). After booting up, it starts the shell interface. My system should have no problems until here as I past all the tests in previous labs and this lab except for the last test int lab5 which test the pipe function.

The shell works well with syscalls (e.g., cat, echo), and I/O redirection(‘<‘ and ‘>’). However, the pipe function has problem whenever I execute the first pipe command.
Example:

  • After init the system and start the shell, I type the “echo hello | cat” command.

init: starting sh
The parent envid is 00002004, the child envid is 00002001
$ echo hello | cat

-The result is that the system trigger a pagefault at address 0x00000070 or 0x00000000 sometimes. This address looks suspicious but I don’t know why.

[00002002] SPAWN: /cat
The faulting addr is 00806000
The faulting addr is 00000070
[00002003] user panic in sh at lib/fork.c:25: pgfault: bad faulting access

-If I do an empty pipe before “echo hello | cat” command, everything works fine then.

init: running sh
init: starting sh
The parent envid is 00002003, the child envid is 00002001
$ |

The system return to shell instead fo panic because the arguments before pipe and after pipe are null arguments.
EMPTY COMMAND
[00002002] exiting gracefully

After this empty pipe, the rest of pipe commands work fine
$ echo hello | cat
hello

Below is the code of pipe in shell
case ‘|’: // Pipe
// p[1] ——–>
// |
// p[0] <——-
// p[1] will be the output of the prog 1 e.g.,”echo hello”,
// and p[0] will be the input of prog 2 e.g., “cat”;
if ((r = pipe(p)) < 0) {
cprintf(“pipe: %e”, r);
exit();
}
if (debug)
cprintf(“PIPE: %d %dn”, p[0], p[1]);
//Create a child to execute the command after ‘|’ e.g.,”cat”
//The mother will execute the command before ‘|’ e.g.,”echo hello”
if ((r = fork()) < 0) {
cprintf(“fork: %e”, r);
exit();
}
//For the child process(“cat”), it replaces its stdin with pipe[0].
if (r == 0) {
if (p[0] != 0) {
dup(p[0], 0);
close(p[0]);
}
close(p[1]);
debug = 1;
goto again;
} else {
//For the parent, it replaces its stdout with pipe[1].
pipe_child = r;
if (p[1] != 1) {
dup(p[1], 1);
close(p[1]);
}
close(p[0]);
goto runit;
}
break;

New contributor

Kesu is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT