Reputation: 21
When I ran the following command in src/userprog
, pintos -- fs-disk=10 -p tests/userprog/args-single:args-single -- -q -f run 'args-single onearg'
, it produced the output below. Could you possibly infer the reason for the kernel panic?
[error message]
SeaBIOS (version 1.13.0-1ubuntu1.1)
Booting from Hard Disk...
PPiiLLoo hhddaa1
1
LLooaaddiinngg.......................
Kernel command line: fs-disk=10 -p tests/userprog/args-single:args-single -- -q'
Pintos booting with 3,968 kB RAM...
367 pages available in kernel pool.
367 pages available in user pool.
Calibrating timer... 419,430,400 loops/s.
hda: 1,008 sectors (504 kB), model "QM00001", serial "QEMU HARDDISK"
hda1: 196 sectors (98 kB), Pintos OS kernel (20)
Kernel PANIC at ../../filesys/filesys.c:22 in filesys_init(): No file system de.
Call stack: 0xc0029c06 0x5f737973Page fault at 0x656c6966: not present error re.
Interrupt 0x0e (#PF Page-Fault Exception) at eip=0xc002728e
cr2=656c6966 error=00000000
eax=0000000b ebx=c0037cd0 ecx=00000481 edx=000003d4
esi=656c6966 edi=c0032704 esp=c0032704 ebp=c000ef18
cs=0008 ds=0010 es=0010 ss=7973
Kernel PANIC recursion at ../../userprog/exception.c:100 in kill().
[filesys.c]
void
filesys_init (bool format)
{
fs_device = block_get_role (BLOCK_FILESYS);
if (fs_device == NULL)
PANIC ("No file system device found, can't initialize file system.");
inode_init ();
free_map_init ();
if (format)
do_format ();
free_map_open ();
}
[exception.c]
/* Handler for an exception (probably) caused by a user process. */
static void
kill (struct intr_frame *f)
{
/* This interrupt is one (probably) caused by a user process.
For example, the process might have tried to access unmapped
virtual memory (a page fault). For now, we simply kill the
user process. Later, we'll want to handle page faults in
the kernel. Real Unix-like operating systems pass most
exceptions back to the process via signals, but we don't
implement them. */
/* The interrupt frame's code segment value tells us where the
exception originated. */
switch (f->cs)
{
case SEL_UCSEG:
/* User's code segment, so it's a user exception, as we
expected. Kill the user process. */
printf ("%s: dying due to interrupt %#04x (%s).\n",
thread_name (), f->vec_no, intr_name (f->vec_no));
intr_dump_frame (f);
thread_exit ();
case SEL_KCSEG:
/* Kernel's code segment, which indicates a kernel bug.
Kernel code shouldn't throw exceptions. (Page faults
may cause kernel exceptions--but they shouldn't arrive
here.) Panic the kernel to make the point. */
intr_dump_frame (f);
PANIC ("Kernel bug - unexpected interrupt in kernel");
default:
/* Some other code segment? Shouldn't happen. Panic the
kernel. */
printf ("Interrupt %#04x (%s) in unknown segment %04x\n",
f->vec_no, intr_name (f->vec_no), f->cs);
thread_exit ();
}
}
I've been trying to implement argument passing in userprog/process.c. While no errors occur during compilation, I'm finding it difficult to determine where to start modifying for the above command. Do I need to create a separate disk to run it?
[process.c]
bool
load (const char *file_name, void (**eip) (void), void **esp)
{
...
char* file_token[64]; //128byte->max 64tokens
int argc=0;
char* ptr;
char* next_ptr;
//* tokenize filename*//
char* file_name_copy = (char*)palloc_get_page(0);
strlcpy(file_name_copy,file_name, strlen(file_name)+1);
ptr = strtok_r(file_name_copy, " ", &next_ptr);
while (ptr != NULL) {
file_token[argc++] = ptr;
ptr = strtok_r(NULL, " ", &next_ptr);
}
//* push data *//
char* token_address[64];
int token_len = -1;
for (int i = argc-1; i>=0; i--){
token_len = strlen(file_token[i]) +1; // include \0
*esp -=token_len;
strlcpy(*esp, file_token[i], token_len);
token_address[i] = (char*)*esp;
}
//* word align *//
while ((uint32_t)*esp % 4 != 0) { //align to 4byte
*esp -= sizeof(uint32_t);
memset(*esp,(uint32_t)0,sizeof(uint32_t));
}
//* null pointer *//
*esp -= sizeof(char*);
char* null_pointer = 0;
//**esp=null_pointer;
memcpy(*esp,&null_pointer,sizeof(char*));
//* push address *//
for (int i = argc - 1; i >= 0; i--) {
*esp -= sizeof(char*);
memcpy(*esp, &token_address[i], sizeof(char*));
//**esp = token_address[i];
}
//* push argv[0] and argc *//
char** argv_address = *esp;
*esp -= sizeof(char*);
memcpy(*esp, &argv_address, sizeof(char*));
*esp -= sizeof(int);
memcpy(*esp, &argc, sizeof(int));
*esp -= 4;
// free memory
palloc_free_page(file_name_copy);
...
}
Upvotes: 1
Views: 186