|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: ! 27: #include "mach_kdb.h" ! 28: #if MACH_KDB ! 29: ! 30: #include <machine/db_machdep.h> ! 31: #include <machine/setjmp.h> ! 32: ! 33: #include <ddb/db_lex.h> ! 34: #include <ddb/db_break.h> ! 35: #include <ddb/db_command.h> ! 36: ! 37: ! 38: ! 39: #define DB_MAX_COND 10 /* maximum conditions to be set */ ! 40: ! 41: int db_ncond_free = DB_MAX_COND; /* free condition */ ! 42: struct db_cond { ! 43: int c_size; /* size of cond */ ! 44: char c_cond_cmd[DB_LEX_LINE_SIZE]; /* cond & cmd */ ! 45: } db_cond[DB_MAX_COND]; ! 46: ! 47: void ! 48: db_cond_free(bkpt) ! 49: db_thread_breakpoint_t bkpt; ! 50: { ! 51: if (bkpt->tb_cond > 0) { ! 52: db_cond[bkpt->tb_cond-1].c_size = 0; ! 53: db_ncond_free++; ! 54: bkpt->tb_cond = 0; ! 55: } ! 56: } ! 57: ! 58: boolean_t ! 59: db_cond_check(bkpt) ! 60: db_thread_breakpoint_t bkpt; ! 61: { ! 62: register struct db_cond *cp; ! 63: db_expr_t value; ! 64: int t; ! 65: jmp_buf_t db_jmpbuf; ! 66: extern jmp_buf_t *db_recover; ! 67: ! 68: if (bkpt->tb_cond <= 0) /* no condition */ ! 69: return(TRUE); ! 70: db_dot = PC_REGS(DDB_REGS); ! 71: db_prev = db_dot; ! 72: db_next = db_dot; ! 73: if (_setjmp(db_recover = &db_jmpbuf)) { ! 74: /* ! 75: * in case of error, return true to enter interactive mode ! 76: */ ! 77: return(TRUE); ! 78: } ! 79: ! 80: /* ! 81: * switch input, and evalutate condition ! 82: */ ! 83: cp = &db_cond[bkpt->tb_cond - 1]; ! 84: db_switch_input(cp->c_cond_cmd, cp->c_size); ! 85: if (!db_expression(&value)) { ! 86: db_printf("error: condition evaluation error\n"); ! 87: return(TRUE); ! 88: } ! 89: if (value == 0 || --(bkpt->tb_count) > 0) ! 90: return(FALSE); ! 91: ! 92: /* ! 93: * execute a command list if exist ! 94: */ ! 95: bkpt->tb_count = bkpt->tb_init_count; ! 96: if ((t = db_read_token()) != tEOL) { ! 97: db_unread_token(t); ! 98: return(db_exec_cmd_nest(0, 0)); ! 99: } ! 100: return(TRUE); ! 101: } ! 102: ! 103: void ! 104: db_cond_print(bkpt) ! 105: db_thread_breakpoint_t bkpt; ! 106: { ! 107: register char *p, *ep; ! 108: register struct db_cond *cp; ! 109: ! 110: if (bkpt->tb_cond <= 0) ! 111: return; ! 112: cp = &db_cond[bkpt->tb_cond-1]; ! 113: p = cp->c_cond_cmd; ! 114: ep = p + cp->c_size; ! 115: while (p < ep) { ! 116: if (*p == '\n' || *p == 0) ! 117: break; ! 118: db_putchar(*p++); ! 119: } ! 120: } ! 121: ! 122: void ! 123: db_cond_cmd() ! 124: { ! 125: register c; ! 126: register struct db_cond *cp; ! 127: register char *p; ! 128: db_expr_t value; ! 129: db_thread_breakpoint_t bkpt; ! 130: ! 131: if (db_read_token() != tHASH || db_read_token() != tNUMBER) { ! 132: db_printf("#<number> expected instead of \"%s\"\n", db_tok_string); ! 133: db_error(0); ! 134: return; ! 135: } ! 136: if ((bkpt = db_find_breakpoint_number(db_tok_number, 0)) == 0) { ! 137: db_printf("No such break point #%d\n", db_tok_number); ! 138: db_error(0); ! 139: return; ! 140: } ! 141: /* ! 142: * if the break point already has a condition, free it first ! 143: */ ! 144: if (bkpt->tb_cond > 0) { ! 145: cp = &db_cond[bkpt->tb_cond - 1]; ! 146: db_cond_free(bkpt); ! 147: } else { ! 148: if (db_ncond_free <= 0) { ! 149: db_error("Too many conditions\n"); ! 150: return; ! 151: } ! 152: for (cp = db_cond; cp < &db_cond[DB_MAX_COND]; cp++) ! 153: if (cp->c_size == 0) ! 154: break; ! 155: if (cp >= &db_cond[DB_MAX_COND]) ! 156: panic("bad db_cond_free"); ! 157: } ! 158: for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char()); ! 159: for (p = cp->c_cond_cmd; c >= 0; c = db_read_char()) ! 160: *p++ = c; ! 161: /* ! 162: * switch to saved data and call db_expression to check the condition. ! 163: * If no condition is supplied, db_expression will return false. ! 164: * In this case, clear previous condition of the break point. ! 165: * If condition is supplied, set the condition to the permanent area. ! 166: * Note: db_expression will not return here, if the condition ! 167: * expression is wrong. ! 168: */ ! 169: db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd); ! 170: if (!db_expression(&value)) { ! 171: /* since condition is already freed, do nothing */ ! 172: db_flush_lex(); ! 173: return; ! 174: } ! 175: db_flush_lex(); ! 176: db_ncond_free--; ! 177: cp->c_size = p - cp->c_cond_cmd; ! 178: bkpt->tb_cond = (cp - db_cond) + 1; ! 179: } ! 180: ! 181: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.