Bug Summary

File:obj-scan-build/../ddb/db_cond.c
Location:line 104, column 1
Description: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

Annotated Source Code

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 Software.Distribution@CS.CMU.EDU
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#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
44int db_ncond_free = DB_MAX_COND10; /* free condition */
45struct db_cond {
46 int c_size; /* size of cond */
47 char c_cond_cmd[DB_LEX_LINE_SIZE256]; /* cond & cmd */
48} db_cond[DB_MAX_COND10];
49
50void
51db_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
61boolean_t
62db_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) /* no condition */
1
Taking false branch
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)) {
2
Taking true branch
77 /*
78 * in case of error, return true to enter interactive mode
79 */
80 return(TRUE((boolean_t) 1));
81 }
82
83 /*
84 * switch input, and evalutate condition
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 * execute a command list if exist
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
106void
107db_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
125void
126db_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 * if the break point already has a condition, free it first
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 * switch to saved data and call db_expression to check the condition.
166 * If no condition is supplied, db_expression will return false.
167 * In this case, clear previous condition of the break point.
168 * If condition is supplied, set the condition to the permanent area.
169 * Note: db_expression will not return here, if the condition
170 * expression is wrong.
171 */
172 db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd);
173 if (!db_expression(&value)) {
174 /* since condition is already freed, do nothing */
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 */