Bug Summary

File:obj-scan-build/../ddb/db_cond.c
Location:line 102, 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(db_thread_breakpoint_t bkpt)
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
60boolean_t
61db_cond_check(db_thread_breakpoint_t bkpt)
62{
63 struct db_cond *cp;
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 */
1
Taking false branch
70 return(TRUE((boolean_t) 1));
71 db_dot = PC_REGS(DDB_REGS)((db_addr_t)((&ddb_regs))->eip);
72 db_prev = db_dot;
73 db_next = db_dot;
74 if (_setjmp(db_recover = &db_jmpbuf)) {
2
Taking true branch
75 /*
76 * in case of error, return true to enter interactive mode
77 */
78 return(TRUE((boolean_t) 1));
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((boolean_t) 1));
89 }
90 if (value == 0 || --(bkpt->tb_count) > 0)
91 return(FALSE((boolean_t) 0));
92
93 /*
94 * execute a command list if exist
95 */
96 bkpt->tb_count = bkpt->tb_init_count;
97 if ((t = db_read_token()) != tEOL1) {
98 db_unread_token(t);
99 return(db_exec_cmd_nest(0, 0));
100 }
101 return(TRUE((boolean_t) 1));
102}
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
103
104void
105db_cond_print(bkpt)
106 const db_thread_breakpoint_t bkpt;
107{
108 char *p, *ep;
109 struct db_cond *cp;
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
123void
124db_cond_cmd(void)
125{
126 int c;
127 struct db_cond *cp;
128 char *p;
129 db_expr_t value;
130 db_thread_breakpoint_t bkpt;
131
132 if (db_read_token() != tHASH13 || db_read_token() != tNUMBER2) {
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_COND10]; cp++)
154 if (cp->c_size == 0)
155 break;
156 if (cp >= &db_cond[DB_MAX_COND10])
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
182#endif /* MACH_KDB */