|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * Mach Operating System 3: * Copyright (c) 1991,1990 Carnegie Mellon University 4: * All Rights Reserved. 1.1.1.2 ! root 5: * 1.1 root 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. 1.1.1.2 ! root 11: * 1.1 root 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. 1.1.1.2 ! root 15: * 1.1 root 16: * Carnegie Mellon requests users of this software to return to 1.1.1.2 ! root 17: * 1.1 root 18: * Software Distribution Coordinator or [email protected] 19: * School of Computer Science 20: * Carnegie Mellon University 21: * Pittsburgh PA 15213-3890 1.1.1.2 ! root 22: * 1.1 root 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: 1.1.1.2 ! root 181: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.