noa18
noa18

Reputation: 21

how to solve kernel panic in pintos project

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

Answers (0)

Related Questions