|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * HISTORY ! 27: * ! 28: * Revision 1.1.1.1 1998/09/22 21:05:47 wsanchez ! 29: * Import of Mac OS X kernel (~semeria) ! 30: * ! 31: * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez ! 32: * Import of OSF Mach kernel (~mburg) ! 33: * ! 34: * Revision 1.2.18.1 1997/03/27 18:46:29 barbou ! 35: * ri-osc CR1558: enable use of breakpoint counts even when no ! 36: * condition given. ! 37: * [1995/09/20 15:24:24 bolinger] ! 38: * [97/02/25 barbou] ! 39: * ! 40: * Revision 1.2.6.2 1996/01/09 19:15:34 devrcs ! 41: * Change 'register c' to 'register int c'. ! 42: * [1995/12/01 21:42:00 jfraser] ! 43: * ! 44: * Merged '64-bit safe' changes from DEC alpha port. ! 45: * [1995/11/21 18:02:54 jfraser] ! 46: * ! 47: * Revision 1.2.6.1 1994/09/23 01:18:27 ezf ! 48: * change marker to not FREE ! 49: * [1994/09/22 21:09:37 ezf] ! 50: * ! 51: * Revision 1.2.2.4 1993/08/11 20:37:33 elliston ! 52: * Add ANSI Prototypes. CR #9523. ! 53: * [1993/08/11 03:32:57 elliston] ! 54: * ! 55: * Revision 1.2.2.3 1993/07/27 18:26:59 elliston ! 56: * Add ANSI prototypes. CR #9523. ! 57: * [1993/07/27 18:11:12 elliston] ! 58: * ! 59: * Revision 1.2.2.2 1993/06/09 02:19:53 gm ! 60: * Added to OSF/1 R1.3 from NMK15.0. ! 61: * [1993/06/02 20:56:04 jeffc] ! 62: * ! 63: * Revision 1.2 1993/04/19 16:01:51 devrcs ! 64: * Changes from mk78: ! 65: * Changed errant call of db_error in db_cond_cmd() to db_printf/db_error. ! 66: * [92/05/20 jfriedl] ! 67: * [93/02/02 bruel] ! 68: * ! 69: * Revision 1.1 1992/09/30 02:00:58 robert ! 70: * Initial revision ! 71: * ! 72: * $EndLog$ ! 73: */ ! 74: /* CMU_HIST */ ! 75: /* ! 76: * Revision 2.2 91/10/09 15:59:09 af ! 77: * Revision 2.1.3.1 91/10/05 13:05:38 jeffreyh ! 78: * Created to support conditional break point and command execution. ! 79: * [91/08/29 tak] ! 80: * ! 81: * Revision 2.1.3.1 91/10/05 13:05:38 jeffreyh ! 82: * Created to support conditional break point and command execution. ! 83: * [91/08/29 tak] ! 84: * ! 85: */ ! 86: /* CMU_ENDHIST */ ! 87: /* ! 88: * Mach Operating System ! 89: * Copyright (c) 1991,1990 Carnegie Mellon University ! 90: * All Rights Reserved. ! 91: * ! 92: * Permission to use, copy, modify and distribute this software and its ! 93: * documentation is hereby granted, provided that both the copyright ! 94: * notice and this permission notice appear in all copies of the ! 95: * software, derivative works or modified versions, and any portions ! 96: * thereof, and that both notices appear in supporting documentation. ! 97: * ! 98: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 99: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 100: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 101: * ! 102: * Carnegie Mellon requests users of this software to return to ! 103: * ! 104: * Software Distribution Coordinator or [email protected] ! 105: * School of Computer Science ! 106: * Carnegie Mellon University ! 107: * Pittsburgh PA 15213-3890 ! 108: * ! 109: * any improvements or extensions that they make and grant Carnegie Mellon ! 110: * the rights to redistribute these changes. ! 111: */ ! 112: /* ! 113: */ ! 114: ! 115: #include <machine/db_machdep.h> ! 116: #include <machine/setjmp.h> ! 117: #include <kern/misc_protos.h> ! 118: ! 119: #include <ddb/db_lex.h> ! 120: #include <ddb/db_break.h> ! 121: #include <ddb/db_command.h> ! 122: #include <ddb/db_cond.h> ! 123: #include <ddb/db_expr.h> ! 124: #include <ddb/db_output.h> /* For db_printf() */ ! 125: ! 126: #define DB_MAX_COND 10 /* maximum conditions to be set */ ! 127: ! 128: int db_ncond_free = DB_MAX_COND; /* free condition */ ! 129: struct db_cond { ! 130: int c_size; /* size of cond */ ! 131: char c_cond_cmd[DB_LEX_LINE_SIZE]; /* cond & cmd */ ! 132: } db_cond[DB_MAX_COND]; ! 133: ! 134: void ! 135: db_cond_free(db_thread_breakpoint_t bkpt) ! 136: { ! 137: if (bkpt->tb_cond > 0) { ! 138: db_cond[bkpt->tb_cond-1].c_size = 0; ! 139: db_ncond_free++; ! 140: bkpt->tb_cond = 0; ! 141: } ! 142: } ! 143: ! 144: boolean_t ! 145: db_cond_check(db_thread_breakpoint_t bkpt) ! 146: { ! 147: register struct db_cond *cp; ! 148: db_expr_t value; ! 149: int t; ! 150: jmp_buf_t db_jmpbuf; ! 151: extern jmp_buf_t *db_recover; ! 152: ! 153: if (bkpt->tb_cond <= 0) { /* no condition */ ! 154: if (--(bkpt->tb_count) > 0) ! 155: return(FALSE); ! 156: bkpt->tb_count = bkpt->tb_init_count; ! 157: return(TRUE); ! 158: } ! 159: db_dot = PC_REGS(DDB_REGS); ! 160: db_prev = db_dot; ! 161: db_next = db_dot; ! 162: if (_setjmp(db_recover = &db_jmpbuf)) { ! 163: /* ! 164: * in case of error, return true to enter interactive mode ! 165: */ ! 166: return(TRUE); ! 167: } ! 168: ! 169: /* ! 170: * switch input, and evalutate condition ! 171: */ ! 172: cp = &db_cond[bkpt->tb_cond - 1]; ! 173: db_switch_input(cp->c_cond_cmd, cp->c_size); ! 174: if (!db_expression(&value)) { ! 175: db_printf("error: condition evaluation error\n"); ! 176: return(TRUE); ! 177: } ! 178: if (value == 0 || --(bkpt->tb_count) > 0) ! 179: return(FALSE); ! 180: ! 181: /* ! 182: * execute a command list if exist ! 183: */ ! 184: bkpt->tb_count = bkpt->tb_init_count; ! 185: if ((t = db_read_token()) != tEOL) { ! 186: db_unread_token(t); ! 187: return(db_exec_cmd_nest(0, 0)); ! 188: } ! 189: return(TRUE); ! 190: } ! 191: ! 192: void ! 193: db_cond_print(db_thread_breakpoint_t bkpt) ! 194: { ! 195: register char *p, *ep; ! 196: register struct db_cond *cp; ! 197: ! 198: if (bkpt->tb_cond <= 0) ! 199: return; ! 200: cp = &db_cond[bkpt->tb_cond-1]; ! 201: p = cp->c_cond_cmd; ! 202: ep = p + cp->c_size; ! 203: while (p < ep) { ! 204: if (*p == '\n' || *p == 0) ! 205: break; ! 206: db_putchar(*p++); ! 207: } ! 208: } ! 209: ! 210: void ! 211: db_cond_cmd(void) ! 212: { ! 213: register int c; ! 214: register struct db_cond *cp; ! 215: register char *p; ! 216: db_expr_t value; ! 217: db_thread_breakpoint_t bkpt; ! 218: ! 219: if (db_read_token() != tHASH || db_read_token() != tNUMBER) { ! 220: db_printf("#<number> expected instead of \"%s\"\n", db_tok_string); ! 221: db_error(0); ! 222: return; ! 223: } ! 224: if ((bkpt = db_find_breakpoint_number(db_tok_number, 0)) == 0) { ! 225: db_printf("No such break point #%d\n", db_tok_number); ! 226: db_error(0); ! 227: return; ! 228: } ! 229: /* ! 230: * if the break point already has a condition, free it first ! 231: */ ! 232: if (bkpt->tb_cond > 0) { ! 233: cp = &db_cond[bkpt->tb_cond - 1]; ! 234: db_cond_free(bkpt); ! 235: } else { ! 236: if (db_ncond_free <= 0) { ! 237: db_error("Too many conditions\n"); ! 238: return; ! 239: } ! 240: for (cp = db_cond; cp < &db_cond[DB_MAX_COND]; cp++) ! 241: if (cp->c_size == 0) ! 242: break; ! 243: if (cp >= &db_cond[DB_MAX_COND]) ! 244: panic("bad db_cond_free"); ! 245: } ! 246: for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char()); ! 247: for (p = cp->c_cond_cmd; c >= 0; c = db_read_char()) ! 248: *p++ = c; ! 249: /* ! 250: * switch to saved data and call db_expression to check the condition. ! 251: * If no condition is supplied, db_expression will return false. ! 252: * In this case, clear previous condition of the break point. ! 253: * If condition is supplied, set the condition to the permanent area. ! 254: * Note: db_expression will not return here, if the condition ! 255: * expression is wrong. ! 256: */ ! 257: db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd); ! 258: if (!db_expression(&value)) { ! 259: /* since condition is already freed, do nothing */ ! 260: db_flush_lex(); ! 261: return; ! 262: } ! 263: db_flush_lex(); ! 264: db_ncond_free--; ! 265: cp->c_size = p - cp->c_cond_cmd; ! 266: bkpt->tb_cond = (cp - db_cond) + 1; ! 267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.