|
|
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: #if MACH_KDB
28:
29: #include <machine/db_machdep.h>
30: #include <machine/setjmp.h>
31:
32: #include <ddb/db_lex.h>
33: #include <ddb/db_break.h>
34: #include <ddb/db_command.h>
1.1.1.3 root 35: #include <ddb/db_cond.h>
36: #include <ddb/db_expr.h>
37: #include <ddb/db_output.h>
1.1 root 38:
1.1.1.3 root 39: #include <kern/debug.h>
1.1 root 40:
41:
42: #define DB_MAX_COND 10 /* maximum conditions to be set */
43:
44: int db_ncond_free = DB_MAX_COND; /* free condition */
45: struct db_cond {
46: int c_size; /* size of cond */
47: char c_cond_cmd[DB_LEX_LINE_SIZE]; /* cond & cmd */
48: } db_cond[DB_MAX_COND];
49:
50: void
1.1.1.4 ! root 51: db_cond_free(db_thread_breakpoint_t bkpt)
1.1 root 52: {
53: if (bkpt->tb_cond > 0) {
54: db_cond[bkpt->tb_cond-1].c_size = 0;
55: db_ncond_free++;
56: bkpt->tb_cond = 0;
57: }
58: }
59:
60: boolean_t
1.1.1.4 ! root 61: db_cond_check(db_thread_breakpoint_t bkpt)
1.1 root 62: {
1.1.1.4 ! root 63: struct db_cond *cp;
1.1 root 64: db_expr_t value;
65: int t;
66: jmp_buf_t db_jmpbuf;
67: extern jmp_buf_t *db_recover;
68:
69: if (bkpt->tb_cond <= 0) /* no condition */
70: return(TRUE);
71: db_dot = PC_REGS(DDB_REGS);
72: db_prev = db_dot;
73: db_next = db_dot;
74: if (_setjmp(db_recover = &db_jmpbuf)) {
75: /*
76: * in case of error, return true to enter interactive mode
77: */
78: return(TRUE);
79: }
80:
81: /*
82: * switch input, and evalutate condition
83: */
84: cp = &db_cond[bkpt->tb_cond - 1];
85: db_switch_input(cp->c_cond_cmd, cp->c_size);
86: if (!db_expression(&value)) {
87: db_printf("error: condition evaluation error\n");
88: return(TRUE);
89: }
90: if (value == 0 || --(bkpt->tb_count) > 0)
91: return(FALSE);
92:
93: /*
94: * execute a command list if exist
95: */
96: bkpt->tb_count = bkpt->tb_init_count;
97: if ((t = db_read_token()) != tEOL) {
98: db_unread_token(t);
99: return(db_exec_cmd_nest(0, 0));
100: }
101: return(TRUE);
102: }
103:
104: void
105: db_cond_print(bkpt)
1.1.1.4 ! root 106: const db_thread_breakpoint_t bkpt;
1.1 root 107: {
1.1.1.4 ! root 108: char *p, *ep;
! 109: struct db_cond *cp;
1.1 root 110:
111: if (bkpt->tb_cond <= 0)
112: return;
113: cp = &db_cond[bkpt->tb_cond-1];
114: p = cp->c_cond_cmd;
115: ep = p + cp->c_size;
116: while (p < ep) {
117: if (*p == '\n' || *p == 0)
118: break;
119: db_putchar(*p++);
120: }
121: }
122:
123: void
1.1.1.4 ! root 124: db_cond_cmd(void)
1.1 root 125: {
1.1.1.4 ! root 126: int c;
! 127: struct db_cond *cp;
! 128: char *p;
1.1 root 129: db_expr_t value;
130: db_thread_breakpoint_t bkpt;
131:
132: if (db_read_token() != tHASH || db_read_token() != tNUMBER) {
133: db_printf("#<number> expected instead of \"%s\"\n", db_tok_string);
134: db_error(0);
135: return;
136: }
137: if ((bkpt = db_find_breakpoint_number(db_tok_number, 0)) == 0) {
138: db_printf("No such break point #%d\n", db_tok_number);
139: db_error(0);
140: return;
141: }
142: /*
143: * if the break point already has a condition, free it first
144: */
145: if (bkpt->tb_cond > 0) {
146: cp = &db_cond[bkpt->tb_cond - 1];
147: db_cond_free(bkpt);
148: } else {
149: if (db_ncond_free <= 0) {
150: db_error("Too many conditions\n");
151: return;
152: }
153: for (cp = db_cond; cp < &db_cond[DB_MAX_COND]; cp++)
154: if (cp->c_size == 0)
155: break;
156: if (cp >= &db_cond[DB_MAX_COND])
157: panic("bad db_cond_free");
158: }
159: for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char());
160: for (p = cp->c_cond_cmd; c >= 0; c = db_read_char())
161: *p++ = c;
162: /*
163: * switch to saved data and call db_expression to check the condition.
164: * If no condition is supplied, db_expression will return false.
165: * In this case, clear previous condition of the break point.
166: * If condition is supplied, set the condition to the permanent area.
167: * Note: db_expression will not return here, if the condition
168: * expression is wrong.
169: */
170: db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd);
171: if (!db_expression(&value)) {
172: /* since condition is already freed, do nothing */
173: db_flush_lex();
174: return;
175: }
176: db_flush_lex();
177: db_ncond_free--;
178: cp->c_size = p - cp->c_cond_cmd;
179: bkpt->tb_cond = (cp - db_cond) + 1;
180: }
181:
1.1.1.2 root 182: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.