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

Annotation of prex-old/sys/kern/debug.c, Revision 1.1.1.1

1.1       nbrk        1: /*-
                      2:  * Copyright (c) 2005-2007, Kohsuke Ohtani
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. Neither the name of the author nor the names of any co-contributors
                     14:  *    may be used to endorse or promote products derived from this software
                     15:  *    without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * debug.c - kernel debug services
                     32:  */
                     33:
                     34: #include <kernel.h>
                     35: #include <task.h>
                     36: #include <ipc.h>
                     37: #include <thread.h>
                     38: #include <device.h>
                     39: #include <page.h>
                     40: #include <kmem.h>
                     41: #include <vm.h>
                     42: #include <irq.h>
                     43:
                     44: #ifdef DEBUG
                     45:
                     46: #ifdef printk
                     47: #undef printk
                     48: #endif
                     49: #ifdef panic
                     50: #undef panic
                     51: #endif
                     52:
                     53: #ifdef CONFIG_DMESG
                     54: #define LOG_SIZE       2048            /* size of ring buffer for log */
                     55: #define LOG_MASK       (LOG_SIZE-1)
                     56:
                     57: static void log_save(char *buf);
                     58:
                     59: static char log_buf[LOG_SIZE];         /* buffer for message log */
                     60: static u_long log_start;               /* start index of log_buf */
                     61: static u_long log_end;                 /* end index of log_buf */
                     62: static u_long log_len;                 /* length of logged char */
                     63: #endif
                     64:
                     65: static char msg_buf[MSGBUFSZ];         /* temporary buffer for message */
                     66: static void (*alt_print)(char *);      /* alternate print handler */
                     67:
                     68: /*
                     69:  * Print out the specified string with a variable argument.
                     70:  *
                     71:  * An actual output is displayed via the platform specific device by
                     72:  * diag_print() routine in kernel. As an alternate option, the device
                     73:  * driver can replace the print routine by using debug_attach().
                     74:  * All printk() inside the kernel are defined as a macro.
                     75:  * The printk() macro is compiled only when the debug option is
                     76:  * enabled (NDEBUG=0).
                     77:  */
                     78: void
                     79: printk(const char *fmt, ...)
                     80: {
                     81:        va_list args;
                     82:
                     83:        irq_lock();
                     84:        va_start(args, fmt);
                     85:        vsprintf(msg_buf, fmt, args);
                     86: #ifdef CONFIG_DMESG
                     87:        log_save(msg_buf);
                     88: #endif
                     89:        if (alt_print != NULL)
                     90:                alt_print(msg_buf);
                     91:        else
                     92:                diag_print(msg_buf);
                     93:        va_end(args);
                     94:        irq_unlock();
                     95: }
                     96:
                     97: /*
                     98:  * Kernel assertion.
                     99:  *
                    100:  * assert() is called only when the expression is false in ASSERT()
                    101:  * macro. ASSERT() macro is compiled only when the debug option is
                    102:  * enabled.
                    103:  */
                    104: void
                    105: assert(const char *file, int line, const char *exp)
                    106: {
                    107:        irq_lock();
                    108:        printk("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);
                    109:        BREAKPOINT();
                    110:        for (;;)
                    111:                machine_idle();
                    112:        /* NOTREACHED */
                    113: }
                    114:
                    115: /*
                    116:  * Kernel panic.
                    117:  *
                    118:  * panic() is called for a fatal kernel error. It shows specified
                    119:  * message, and stops CPU. If the kernel is not debug version,
                    120:  * panic() macro will reset the system instead of calling this
                    121:  * routine.
                    122:  */
                    123: void
                    124: panic(const char *fmt, ...)
                    125: {
                    126:        va_list args;
                    127:
                    128:        irq_lock();
                    129:        printk("\nKernel panic: ");
                    130:        va_start(args, fmt);
                    131:        vsprintf(msg_buf, fmt, args);
                    132:        printk(msg_buf);
                    133:        va_end(args);
                    134:        printk("\n");
                    135:        irq_unlock();
                    136:        BREAKPOINT();
                    137:        for (;;)
                    138:                machine_idle();
                    139:        /* NOTREACHED */
                    140: }
                    141:
                    142: #ifdef CONFIG_DMESG
                    143: /*
                    144:  * Save diag message to ring buffer
                    145:  */
                    146: static void
                    147: log_save(char *buf)
                    148: {
                    149:        char *p;
                    150:
                    151:        for (p = buf; *p != '\0'; p++) {
                    152:                log_buf[log_end & LOG_MASK] = *p;
                    153:                log_end++;
                    154:                if (log_end - log_start > LOG_SIZE)
                    155:                        log_start = log_end - LOG_SIZE;
                    156:                if (log_len < LOG_SIZE)
                    157:                        log_len++;
                    158:        }
                    159:        /* Store end tag */
                    160:        log_buf[log_end & LOG_MASK] = -1;
                    161: }
                    162: #endif
                    163:
                    164: /*
                    165:  * Return infomation about log
                    166:  */
                    167: int
                    168: log_get(char **buf, size_t *size)
                    169: {
                    170:
                    171: #ifdef CONFIG_DMESG
                    172:        *buf = log_buf;
                    173:        *size = LOG_SIZE;
                    174:        return 0;
                    175: #else
                    176:        return -1;
                    177: #endif
                    178: }
                    179:
                    180: #if defined(CONFIG_DMESG) && defined (CONFIG_KDUMP)
                    181: static void
                    182: log_dump(void)
                    183: {
                    184:        int i, len;
                    185:        u_long index;
                    186:        char c;
                    187:
                    188:        index = log_start;
                    189:        len = log_len;
                    190:        if (log_len == LOG_SIZE) {
                    191:                /* Skip first line */
                    192:                while (log_buf[index & LOG_MASK] != '\n') {
                    193:                        index++;
                    194:                        len--;
                    195:                }
                    196:        }
                    197:        for (i = 0; i < len; i++) {
                    198:                c = log_buf[index & LOG_MASK];
                    199:                printk("%c", c);
                    200:                index++;
                    201:        }
                    202: }
                    203: #endif
                    204:
                    205: /*
                    206:  * Dump system information.
                    207:  *
                    208:  * A keyboard driver may call this routine if a user presses
                    209:  * a predefined "dump" key.
                    210:  * Since interrupt is locked in this routine, there is no need
                    211:  * to lock the interrupt/scheduler in each dump function.
                    212:  */
                    213: int
                    214: debug_dump(int item)
                    215: {
                    216: #ifdef CONFIG_KDUMP
                    217:        int err = 0;
                    218:
                    219:        printk("\n");
                    220:        irq_lock();
                    221:        switch (item) {
                    222:        case DUMP_THREAD:
                    223:                thread_dump();
                    224:                break;
                    225:        case DUMP_TASK:
                    226:                task_dump();
                    227:                break;
                    228:        case DUMP_OBJECT:
                    229:                object_dump();
                    230:                break;
                    231:        case DUMP_TIMER:
                    232:                timer_dump();
                    233:                break;
                    234:        case DUMP_IRQ:
                    235:                irq_dump();
                    236:                break;
                    237:        case DUMP_DEVICE:
                    238:                device_dump();
                    239:                break;
                    240:        case DUMP_VM:
                    241:                page_dump();
                    242:                kmem_dump();
                    243:                vm_dump();
                    244:                break;
                    245: #ifdef CONFIG_DMESG
                    246:        case DUMP_MSGLOG:
                    247:                log_dump();
                    248:                break;
                    249: #endif
                    250:        default:
                    251:                err = 1;
                    252:                break;
                    253:        }
                    254:        irq_unlock();
                    255:        return err;
                    256: #else
                    257:        return ENOSYS;
                    258: #endif
                    259: }
                    260:
                    261: /*
                    262:  * Attach an alternate print handler.
                    263:  * A device driver can hook the function to display message.
                    264:  */
                    265: void
                    266: debug_attach(void (*fn)(char *))
                    267: {
                    268:        ASSERT(fn);
                    269:        alt_print = fn;
                    270: }
                    271:
                    272: #else /* !DEBUG */
                    273:
                    274: /*
                    275:  * Stubs for the release build.
                    276:  */
                    277: int
                    278: debug_dump(int item)
                    279: {
                    280:        return ENOSYS;
                    281: }
                    282:
                    283: void
                    284: debug_attach(void (*fn)(char *))
                    285: {
                    286: }
                    287: #endif /* !DEBUG */

CVSweb