|
|
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.