[BACK]Return to debug.c CVS log [TXT][DIR] Up to [local] / prex-old / sys / kern

Diff for /prex-old/sys/kern/debug.c between version 1.1.1.1 and 1.1.1.1.2.1

version 1.1.1.1, 2008/06/03 10:38:46 version 1.1.1.1.2.1, 2008/08/13 17:12:31
Line 1 
Line 1 
 /*-  /*-
  * Copyright (c) 2005-2007, Kohsuke Ohtani   * Copyright (c) 2005-2008, Kohsuke Ohtani
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 33 
Line 33 
   
 #include <kernel.h>  #include <kernel.h>
 #include <task.h>  #include <task.h>
 #include <ipc.h>  
 #include <thread.h>  #include <thread.h>
 #include <device.h>  
 #include <page.h>  
 #include <kmem.h>  
 #include <vm.h>  #include <vm.h>
 #include <irq.h>  #include <irq.h>
   
 #ifdef DEBUG  #ifdef DEBUG
   
 #ifdef printk  /*
 #undef printk   * diag_print() is provided by architecture dependent layer.
 #endif   */
 #ifdef panic  typedef void (*prtfn_t)(char *);
 #undef panic  static prtfn_t  print_func = &diag_print;
 #endif  
   
 #ifdef CONFIG_DMESG  static char     dbg_msg[DBGMSG_SIZE];
 #define LOG_SIZE        2048            /* size of ring buffer for log */  
 #define LOG_MASK        (LOG_SIZE-1)  
   
 static void log_save(char *buf);  /*
    * dmesg support
    */
   static char     log_buf[LOGBUF_SIZE];
   static u_long   log_head;
   static u_long   log_tail;
   static u_long   log_len;
   
 static char log_buf[LOG_SIZE];          /* buffer for message log */  #define LOGINDEX(x)     ((x) & (LOGBUF_SIZE - 1))
 static u_long log_start;                /* start index of log_buf */  
 static u_long log_end;                  /* end index of log_buf */  
 static u_long log_len;                  /* length of logged char */  
 #endif  
   
 static char msg_buf[MSGBUFSZ];          /* temporary buffer for message */  
 static void (*alt_print)(char *);       /* alternate print handler */  
   
 /*  /*
  * Print out the specified string with a variable argument.   * Print out the specified string.
  *   *
  * An actual output is displayed via the platform specific device by   * An actual output is displayed via the platform
  * diag_print() routine in kernel. As an alternate option, the device   * specific device by diag_print() routine in kernel.
  * driver can replace the print routine by using debug_attach().   * As an alternate option, the device driver can
  * All printk() inside the kernel are defined as a macro.   * replace the print routine by using debug_attach().
  * The printk() macro is compiled only when the debug option is  
  * enabled (NDEBUG=0).  
  */   */
 void  void
 printk(const char *fmt, ...)  printf(const char *fmt, ...)
 {  {
         va_list args;          va_list args;
           int i;
           char c;
   
         irq_lock();          irq_lock();
         va_start(args, fmt);          va_start(args, fmt);
         vsprintf(msg_buf, fmt, args);  
 #ifdef CONFIG_DMESG          vsprintf(dbg_msg, fmt, args);
         log_save(msg_buf);  
 #endif          /* Print out */
         if (alt_print != NULL)          (*print_func)(dbg_msg);
                 alt_print(msg_buf);  
         else          /*
                 diag_print(msg_buf);           * Record to log buffer
            */
           for (i = 0; i < DBGMSG_SIZE; i++) {
                   c = dbg_msg[i];
                   if (c == '\0')
                           break;
                   log_buf[LOGINDEX(log_tail)] = c;
                   log_tail++;
                   if (log_len < LOGBUF_SIZE)
                           log_len++;
                   else
                           log_head = log_tail - LOGBUF_SIZE;
           }
         va_end(args);          va_end(args);
         irq_unlock();          irq_unlock();
 }  }
Line 97 
Line 101 
 /*  /*
  * Kernel assertion.   * Kernel assertion.
  *   *
  * assert() is called only when the expression is false in ASSERT()   * assert() is called only when the expression is false in
  * macro. ASSERT() macro is compiled only when the debug option is   * ASSERT() macro. ASSERT() macro is compiled only when
  * enabled.   * the debug option is enabled.
  */   */
 void  void
 assert(const char *file, int line, const char *exp)  assert(const char *file, int line, const char *exp)
 {  {
   
         irq_lock();          irq_lock();
         printk("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);          printf("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);
         BREAKPOINT();          BREAKPOINT();
         for (;;)          for (;;)
                 machine_idle();                  machine_idle();
Line 115 
Line 120 
 /*  /*
  * Kernel panic.   * Kernel panic.
  *   *
  * panic() is called for a fatal kernel error. It shows specified   * panic() is called for a fatal kernel error. It shows
  * message, and stops CPU. If the kernel is not debug version,   * specified message, and stops CPU.
  * panic() macro will reset the system instead of calling this  
  * routine.  
  */   */
 void  void
 panic(const char *fmt, ...)  panic(const char *msg)
 {  {
         va_list args;  
   
         irq_lock();          irq_lock();
         printk("\nKernel panic: ");          printf("\nKernel panic: %s\n", msg);
         va_start(args, fmt);  
         vsprintf(msg_buf, fmt, args);  
         printk(msg_buf);  
         va_end(args);  
         printk("\n");  
         irq_unlock();          irq_unlock();
         BREAKPOINT();          BREAKPOINT();
         for (;;)          for (;;)
Line 139 
Line 136 
         /* NOTREACHED */          /* NOTREACHED */
 }  }
   
 #ifdef CONFIG_DMESG  
 /*  /*
  * Save diag message to ring buffer   * Copy log to user buffer.
  */   */
 static void  
 log_save(char *buf)  
 {  
         char *p;  
   
         for (p = buf; *p != '\0'; p++) {  
                 log_buf[log_end & LOG_MASK] = *p;  
                 log_end++;  
                 if (log_end - log_start > LOG_SIZE)  
                         log_start = log_end - LOG_SIZE;  
                 if (log_len < LOG_SIZE)  
                         log_len++;  
         }  
         /* Store end tag */  
         log_buf[log_end & LOG_MASK] = -1;  
 }  
 #endif  
   
 /*  
  * Return infomation about log  
  */  
 int  int
 log_get(char **buf, size_t *size)  debug_getlog(char *buf)
 {  {
           u_long i, len, index;
 #ifdef CONFIG_DMESG          int err = 0;
         *buf = log_buf;  
         *size = LOG_SIZE;  
         return 0;  
 #else  
         return -1;  
 #endif  
 }  
   
 #if defined(CONFIG_DMESG) && defined (CONFIG_KDUMP)  
 static void  
 log_dump(void)  
 {  
         int i, len;  
         u_long index;  
         char c;          char c;
   
         index = log_start;          irq_lock();
           index = log_head;
         len = log_len;          len = log_len;
         if (log_len == LOG_SIZE) {          if (len >= LOGBUF_SIZE) {
                 /* Skip first line */                  /*
                 while (log_buf[index & LOG_MASK] != '\n') {                   * Overrun found. Discard broken message.
                    */
                   while (len > 0 && log_buf[LOGINDEX(index)] != '\n') {
                         index++;                          index++;
                         len--;                          len--;
                 }                  }
         }          }
         for (i = 0; i < len; i++) {          for (i = 0; i < LOGBUF_SIZE; i++) {
                 c = log_buf[index & LOG_MASK];                  if (i < len)
                 printk("%c", c);                          c = log_buf[LOGINDEX(index)];
                   else
                           c = '\0';
                   if (umem_copyout(&c, buf, 1)) {
                           err = EFAULT;
                           break;
                   }
                 index++;                  index++;
                   buf++;
         }          }
           irq_unlock();
           return err;
 }  }
 #endif  
   
 /*  /*
  * Dump system information.   * Dump system information.
  *   *
  * A keyboard driver may call this routine if a user presses   * A keyboard driver may call this routine if a user
  * a predefined "dump" key.   * presses a predefined "dump" key.  Since interrupt is
  * Since interrupt is locked in this routine, there is no need   * locked in this routine, there is no need to lock the
  * to lock the interrupt/scheduler in each dump function.   * interrupt/scheduler in each dump function.
  */   */
 int  int
 debug_dump(int item)  debug_dump(int item)
 {  {
 #ifdef CONFIG_KDUMP  
         int err = 0;          int err = 0;
   
         printk("\n");  
         irq_lock();          irq_lock();
         switch (item) {          switch (item) {
         case DUMP_THREAD:          case DUMP_THREAD:
Line 225 
Line 195 
         case DUMP_TASK:          case DUMP_TASK:
                 task_dump();                  task_dump();
                 break;                  break;
         case DUMP_OBJECT:  
                 object_dump();  
                 break;  
         case DUMP_TIMER:  
                 timer_dump();  
                 break;  
         case DUMP_IRQ:  
                 irq_dump();  
                 break;  
         case DUMP_DEVICE:  
                 device_dump();  
                 break;  
         case DUMP_VM:          case DUMP_VM:
                 page_dump();  
                 kmem_dump();  
                 vm_dump();                  vm_dump();
                 break;                  break;
 #ifdef CONFIG_DMESG  
         case DUMP_MSGLOG:  
                 log_dump();  
                 break;  
 #endif  
         default:          default:
                 err = 1;                  err = ENOSYS;
                 break;                  break;
         }          }
         irq_unlock();          irq_unlock();
         return err;          return err;
 #else  
         return ENOSYS;  
 #endif  
 }  }
   
 /*  /*
  * Attach an alternate print handler.   * Attach to a print handler.
  * A device driver can hook the function to display message.   * A device driver can hook the function to display message.
  */   */
 void  void
 debug_attach(void (*fn)(char *))  debug_attach(void (*fn)(char *))
 {  {
         ASSERT(fn);          ASSERT(fn);
         alt_print = fn;  
 }  
   
 #else /* !DEBUG */          print_func = fn;
   
 /*  
  * Stubs for the release build.  
  */  
 int  
 debug_dump(int item)  
 {  
         return ENOSYS;  
 }  }
   
 void  
 debug_attach(void (*fn)(char *))  
 {  
 }  
 #endif /* !DEBUG */  #endif /* !DEBUG */

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.1.2.1

CVSweb