1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | #if MACH_KDB1 |
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> |
35 | #include <ddb/db_cond.h> |
36 | #include <ddb/db_expr.h> |
37 | #include <ddb/db_output.h> |
38 | |
39 | #include <kern/debug.h> |
40 | |
41 | |
42 | #define DB_MAX_COND10 10 /* maximum conditions to be set */ |
43 | |
44 | int db_ncond_free = DB_MAX_COND10; |
45 | struct db_cond { |
46 | int c_size; |
47 | char c_cond_cmd[DB_LEX_LINE_SIZE256]; |
48 | } db_cond[DB_MAX_COND10]; |
49 | |
50 | void |
51 | db_cond_free(bkpt) |
52 | db_thread_breakpoint_t bkpt; |
53 | { |
54 | if (bkpt->tb_cond > 0) { |
55 | db_cond[bkpt->tb_cond-1].c_size = 0; |
56 | db_ncond_free++; |
57 | bkpt->tb_cond = 0; |
58 | } |
59 | } |
60 | |
61 | boolean_t |
62 | db_cond_check(bkpt) |
63 | db_thread_breakpoint_t bkpt; |
64 | { |
65 | struct db_cond *cp; |
66 | db_expr_t value; |
67 | int t; |
68 | jmp_buf_t db_jmpbuf; |
69 | extern jmp_buf_t *db_recover; |
70 | |
71 | if (bkpt->tb_cond <= 0) |
| |
72 | return(TRUE((boolean_t) 1)); |
73 | db_dot = PC_REGS(DDB_REGS)((db_addr_t)((&ddb_regs))->eip); |
74 | db_prev = db_dot; |
75 | db_next = db_dot; |
76 | if (_setjmp(db_recover = &db_jmpbuf)) { |
| |
77 | |
78 | |
79 | |
80 | return(TRUE((boolean_t) 1)); |
81 | } |
82 | |
83 | |
84 | |
85 | |
86 | cp = &db_cond[bkpt->tb_cond - 1]; |
87 | db_switch_input(cp->c_cond_cmd, cp->c_size); |
88 | if (!db_expression(&value)) { |
89 | db_printf("error: condition evaluation error\n"); |
90 | return(TRUE((boolean_t) 1)); |
91 | } |
92 | if (value == 0 || --(bkpt->tb_count) > 0) |
93 | return(FALSE((boolean_t) 0)); |
94 | |
95 | |
96 | |
97 | |
98 | bkpt->tb_count = bkpt->tb_init_count; |
99 | if ((t = db_read_token()) != tEOL1) { |
100 | db_unread_token(t); |
101 | return(db_exec_cmd_nest(0, 0)); |
102 | } |
103 | return(TRUE((boolean_t) 1)); |
104 | } |
| 3 | | Address of stack memory associated with local variable 'db_jmpbuf' is still referred to by the global variable 'db_recover' upon returning to the caller. This will be a dangling reference |
|
105 | |
106 | void |
107 | db_cond_print(bkpt) |
108 | const db_thread_breakpoint_t bkpt; |
109 | { |
110 | char *p, *ep; |
111 | struct db_cond *cp; |
112 | |
113 | if (bkpt->tb_cond <= 0) |
114 | return; |
115 | cp = &db_cond[bkpt->tb_cond-1]; |
116 | p = cp->c_cond_cmd; |
117 | ep = p + cp->c_size; |
118 | while (p < ep) { |
119 | if (*p == '\n' || *p == 0) |
120 | break; |
121 | db_putchar(*p++); |
122 | } |
123 | } |
124 | |
125 | void |
126 | db_cond_cmd(void) |
127 | { |
128 | int c; |
129 | struct db_cond *cp; |
130 | char *p; |
131 | db_expr_t value; |
132 | db_thread_breakpoint_t bkpt; |
133 | |
134 | if (db_read_token() != tHASH13 || db_read_token() != tNUMBER2) { |
135 | db_printf("#<number> expected instead of \"%s\"\n", db_tok_string); |
136 | db_error(0); |
137 | return; |
138 | } |
139 | if ((bkpt = db_find_breakpoint_number(db_tok_number, 0)) == 0) { |
140 | db_printf("No such break point #%d\n", db_tok_number); |
141 | db_error(0); |
142 | return; |
143 | } |
144 | |
145 | |
146 | |
147 | if (bkpt->tb_cond > 0) { |
148 | cp = &db_cond[bkpt->tb_cond - 1]; |
149 | db_cond_free(bkpt); |
150 | } else { |
151 | if (db_ncond_free <= 0) { |
152 | db_error("Too many conditions\n"); |
153 | return; |
154 | } |
155 | for (cp = db_cond; cp < &db_cond[DB_MAX_COND10]; cp++) |
156 | if (cp->c_size == 0) |
157 | break; |
158 | if (cp >= &db_cond[DB_MAX_COND10]) |
159 | panic("bad db_cond_free"); |
160 | } |
161 | for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char()); |
162 | for (p = cp->c_cond_cmd; c >= 0; c = db_read_char()) |
163 | *p++ = c; |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd); |
173 | if (!db_expression(&value)) { |
174 | |
175 | db_flush_lex(); |
176 | return; |
177 | } |
178 | db_flush_lex(); |
179 | db_ncond_free--; |
180 | cp->c_size = p - cp->c_cond_cmd; |
181 | bkpt->tb_cond = (cp - db_cond) + 1; |
182 | } |
183 | |
184 | #endif /* MACH_KDB */ |