"Fossies" - the Fresh Open Source Software Archive 
Member "dbg-2.15.5/dbg_bp.c" (21 Apr 2007, 11255 Bytes) of package /linux/www/old/dbg-2.15.5.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "dbg_bp.c" see the
Fossies "Dox" file reference documentation.
1 /***************************************************************************
2 dbg_bp.c - description
3 -------------------
4 begin : Wed Sep 12 2001
5 copyright : (C) 2001 by Dmitri Dmitrienko
6 : (C) 2002, 2007 NuSphere Corp.
7 www : http://dd.cron.ru
8 : http://www.nusphere.com/
9 author : written by Dmitri Dmitrienko
10 license : This source file is subject to version 3.0 of
11 the License, that is bundled with this package
12 in the file LICENSE, and is available at through
13 the world-wide-web at http://www.nusphere.com/dbg
14 ***************************************************************************/
15
16 #include "php.h"
17
18 #include "php_dbg.h"
19 #include "dbg_cmd.h"
20
21 int bp_no_cmp(const void *p1, const void *p2) {
22 int bp_no1 = ((bp_item *) ((*(zend_llist_element **)(p1))->data) )->bp_no;
23 int bp_no2 = ((bp_item *) ((*(zend_llist_element **)(p2))->data) )->bp_no;
24 if (bp_no1 > bp_no2) return 1;
25 else if (bp_no1 == bp_no2) return 0;
26 return -1;
27 }
28
29 bp_item *find_bp_item_by_no(int bp_no TSRMLS_DC1(DBG)) {
30 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
31 if (data->bp_no == bp_no) return data;
32 });
33 return NULL;
34 }
35
36 void bp_array_free(bpl_array* arr) {
37 if (arr->item) {
38 efree(arr->item);
39 arr->item = NULL;
40 }
41 memset(arr, 0, sizeof(*arr));
42 }
43
44 inline void bp_array_clear(bpl_array* arr) {
45 arr->count = 0;
46 }
47
48 void bp_array_add(bpl_array* arr, bp_item* item) {
49 if (arr->count >= arr->limit) {
50 arr->limit += 4;
51 arr->item = erealloc(arr->item, arr->limit * sizeof(*(arr->item)));
52 }
53 if (!arr->item) return;
54 arr->item[arr->count].item = item;
55 arr->item[arr->count].line_no = item->line_no;
56 arr->count += 1;
57 }
58
59 int bp_array_cmp(const void *elem1, const void *elem2) {
60 int l1 = ((bpl_arr_item *)elem1)->line_no;
61 int l2 = ((bpl_arr_item *)elem2)->line_no;
62 if (l1 > l2) return 1;
63 else if (l1 == l2) return 0;
64 return -1;
65 }
66
67 void bp_array_sort(bpl_array* arr) {
68 if (arr->count <= 1) return;
69 qsort(arr->item, arr->count, sizeof(*(arr->item)), bp_array_cmp);
70 }
71
72 inline int bp_array_find(bpl_array* bp_arr, int line_no, bpl_arr_item ** start_item) {
73 int L, H, i, c, cnt, lno;
74 bpl_arr_item *bpit, *p;
75
76 *start_item = NULL;
77 if (!bp_arr || !(bpit = bp_arr->item)) return 0;
78
79 L = 0;
80 cnt = bp_arr->count;
81 H = cnt - 1;
82
83 while (L <= H) {
84 i = (L + H) >> 1;
85 lno = bpit[i].line_no;
86 if (lno < line_no) {
87 L = i + 1;
88 } else {
89 H = i - 1;
90 if (lno == line_no) {
91 p = &bpit[i];
92 while (i > 0) {
93 p--;i--;
94 if (p->line_no != line_no) {
95 p++;i++;
96 break;
97 }
98 }
99 *start_item = p;
100 c = 1;
101 p++;i++;
102 while (i < cnt && p->line_no == line_no) {
103 p++;i++;
104 c++;
105 }
106 return c;
107 };
108 }
109 }
110 return 0;
111 }
112
113 void dbg_do_resolve_bp(bp_item* bp TSRMLS_DC1(DBG)) {
114 int mod_no;
115 int l_no = bp->line_no;
116 int found = 0;
117
118 if (bp->mod_no == 0 && bp->mod_name != NULL) {
119 bp->mod_no = DBG_FINDMODULE(bp->mod_name);
120 }
121 mod_no = bp->mod_no;
122 if (mod_no == 0) return;
123
124 LLIST_FOREACH(DBG(ctxlines_list), ctxlines_item,
125 if (data->mod_no == mod_no && l_no >= data->start_line_no && l_no < data->start_line_no + data->lines_cnt) {
126 DBG_TRACE(("found %d:%d:%d\n", mod_no, data->start_line_no, data->lines_cnt));
127 found = 1;
128 break;
129 }
130 );
131 if (found) {
132 DBG_TRACE(("resolved %d:%d\n", mod_no, l_no));
133 bp->state &= ~BPS_UNRESOLVED;
134 }
135 }
136
137 void dbg_resolve_bp(TSRMLS_D1(DBG)) {
138
139 DBG_TRACE(("dbg_resolve_bp\n"));
140 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
141 if (data->state & BPS_UNRESOLVED)
142 dbg_do_resolve_bp(data TSRMLS_CC1(DBG));
143 });
144 }
145
146 void dbg_rebuild_bplist_mod(mod_item* mod TSRMLS_DC1(DBG)) {
147 int mod_no = (mod) ? (mod->mod_no) : 0;
148 if (mod_no == 0) return;
149
150 bp_array_clear(&mod->bp_arr);
151 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
152 if (data->mod_no == mod_no && (data->state & ~BPS_UNRESOLVED)==BPS_ENABLED) {
153 bp_array_add(&mod->bp_arr, data);
154 }
155 });
156 bp_array_sort(&mod->bp_arr);
157 DBG(breakpoint_list_inv) = 0;
158 }
159
160 void dbg_rebuild_bplist(TSRMLS_D1(DBG)) {
161 DBG_TRACE(("dbg_rebuild_bplist()\n"));
162 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
163 if ((data->state & ~BPS_UNRESOLVED) == BPS_DELETED) {
164 DBG_TRACE(("removing deleted bp.%d\n", data->bp_no));
165 zend_llist_del_element(&DBG(breakpoint_list), data, cmpll);
166 }
167 });
168 dbg_resolve_bp(TSRMLS_C1(DBG));
169 LLIST_FOREACH(DBG(mod_list), mod_item,
170 dbg_rebuild_bplist_mod(data TSRMLS_CC1(DBG));
171 );
172 bp_array_clear(&DBG(global_bp_arr));
173 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
174 if (data->mod_no == 0 && data->mod_name == NULL) {
175 bp_array_add(&DBG(global_bp_arr), data);
176 }
177 });
178 bp_array_sort(&DBG(global_bp_arr));
179 }
180
181 static inline int chk_hit_bp(bp_item *bpit TSRMLS_DC3(DBG, E, C)) {
182 int is_hit = 1, is_failed, failedtocompile = 0;
183
184 if (bpit->state != BPS_ENABLED) return 0;
185
186 if (bpit->condition) {
187 zval buf, *pbuf;
188
189 is_hit = 0;
190 memset(&buf, 0, sizeof(buf));
191 Z_TYPE_P(&buf) = IS_STRING;
192 buf.refcount++;
193 DBG(in_eval)++;
194 is_failed = 1;
195 {
196 DBG_CTX_SAVE
197 DBG_CTX_TRY {
198
199 if (DBG(eval_error)) {
200 efree(DBG(eval_error));
201 DBG(eval_error) = NULL;
202 }
203 if (zend_eval_string(bpit->condition, &buf, "dbg_bp_condition()" TSRMLS_CC2(C, E)) == SUCCESS && !DBG(eval_error)) {
204 pbuf = &buf;
205 convert_to_boolean_ex(&pbuf);
206 is_hit = (*pbuf).value.lval;
207 }
208 } DBG_CTX_CATCH {
209 DBG_CTX_RESTORE
210 } DBG_CTX_ENDTRY
211 }
212 DBG(in_eval)--;
213 }
214 if (is_hit) {
215 DBG_TRACE(("bp#%d hit\n", bpit->bp_no));
216 bpit->hitcount++;
217 bpit->isunderhit = 1;
218 if (bpit->hitcount <= bpit->skiphits) is_hit = 0;
219 if (bpit->istemp) bpit->state = BPS_DELETED;
220 }
221 return is_hit;
222 }
223
224 inline int dbg_chk_bp_hits(TSRMLS_D2(DBG, E)) {
225 int mod_bpcnt, i, hitc;
226 bpl_arr_item *mod_bpit, *p;
227 mod_item* mod = DBG(curr_mod);
228
229 TSRMLS_FETCH1_NOP(C);
230
231 if (!mod) return 0;
232 mod_bpcnt = bp_array_find(&mod->bp_arr, DBG(curr_line_no), &mod_bpit);
233 hitc = 0;
234 for (i=0, p=mod_bpit; i<mod_bpcnt; i++,p++) {
235 if (chk_hit_bp(p->item TSRMLS_CC3(DBG, E, C))) hitc++;
236 }
237 for (i=0, p=DBG(global_bp_arr).item; i<DBG(global_bp_arr).count; i++, p++) {
238 if (chk_hit_bp(p->item TSRMLS_CC3(DBG, E, C))) hitc++;
239 }
240 return hitc;
241 }
242
243 inline void dbg_reset_bp_isunderhit(TSRMLS_D1(DBG)) {
244 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
245 data->isunderhit = 0;
246 });
247 }
248
249 inline void dbg_mark_del_temp_breakpoints(TSRMLS_D1(DBG)) {
250 DBG_TRACE(("dbg_mark_del_temp_breakpoints()\n"));
251 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
252 if (data->istemp) {
253 DBG_TRACE(("mark bp.%d as deleted\n",data->bp_no));
254 data->state = BPS_DELETED;
255 DBG(breakpoint_list_inv) = 1;
256 }
257 });
258 }
259
260 inline int listout_bp_item(dbg_packet *pack, bp_item *bpitem, int bp_no) {
261 dbg_bpl_body body;
262 if (bpitem) {
263 body.bp_no = bp_no;
264 body.hitcount = bpitem->hitcount;
265 body.icondition = dbg_packet_add_string(pack, bpitem->condition);
266 body.imod_name = dbg_packet_add_string(pack, bpitem->mod_name);
267 body.istemp = bpitem->istemp;
268 body.line_no = bpitem->line_no;
269 body.mod_no = bpitem->mod_no;
270 body.skiphits = bpitem->skiphits;
271 body.state = bpitem->state;
272 body.isunderhit = bpitem->isunderhit;
273 DBG_TRACE(("list bp.%d, state=%d\n", bpitem->bp_no, bpitem->state));
274 } else {
275 memset(&body, 0, sizeof(body));
276 body.bp_no = bp_no;
277 }
278 dbg_packet_add_frame(pack, FRAME_BPL, &body, sizeof(body));
279 return sizeof(body);
280 }
281
282 void dbg_add_bp_reply(dbg_packet *pack TSRMLS_DC1(DBG)) {
283 dbg_mark_del_temp_breakpoints(TSRMLS_C1(DBG));
284 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
285 listout_bp_item(pack, data, data->bp_no);
286 });
287 }
288
289
290 typedef int (*qsort_func_t)(const void *, const void *);
291
292 void dbg_llist_sort(zend_llist *l, qsort_func_t comp_func) {
293 int list_size=0, i;
294
295 zend_llist_element **elements;
296 zend_llist_element *element, **ptr;
297
298 for (element=l->head; element; element=element->next) {
299 list_size++;
300 }
301
302 if (list_size == 0) {
303 return;
304 }
305
306 elements = (zend_llist_element **) emalloc(list_size*sizeof(zend_llist_element *));
307
308 ptr = &elements[0];
309
310 for (element=l->head; element; element=element->next) {
311 *ptr++ = element;
312 }
313
314 qsort(elements, list_size, sizeof(zend_llist_element *), (int (*)(const void *, const void *)) comp_func);
315
316 l->head = elements[0];
317 elements[0]->prev = NULL;
318
319 for (i=1; i<list_size; i++) {
320 elements[i]->prev = elements[i-1];
321 elements[i-1]->next = elements[i];
322 }
323 elements[i - 1]->next = NULL;
324 l->tail = elements[i - 1];
325 efree(elements);
326 }
327
328 int dbg_set_breakpoint(dbg_bps_request* req, dbg_packet *pack, dbg_packet *inpack TSRMLS_DC2(DBG, E)) {
329 bp_item *pitem = NULL, item;
330 char *mod_name = NULL, *condition = NULL;
331 int sz, prev_bp_no1, bp_no;
332 /* UPDATE | DELETE */
333 if (req->bp_no != 0) {
334 DBG_TRACE(("updating bp#%d, st:%d, line:%d, skip:%d\n", req->bp_no, req->state, req->line_no, req->skiphits));
335 bp_no = req->bp_no;
336 pitem = find_bp_item_by_no(bp_no TSRMLS_CC1(DBG));
337 if (pitem) {
338 pitem->state = req->state | BPS_UNRESOLVED;
339 if ((req->state & ~BPS_UNRESOLVED) != BPS_DELETED) {
340 pitem->line_no = req->line_no;
341 pitem->skiphits = req->skiphits;
342 if (pitem->condition) {
343 efree(pitem->condition);
344 pitem->condition = NULL;
345 }
346 if (dbg_packet_findstring(inpack, req->icondition , &condition, &sz)) {
347 pitem->condition = estrdup(condition);
348 DBG_TRACE(("updating condition bp#%d, cond:'%s'\n", req->bp_no, SON(condition)));
349 }
350 }
351 }
352 } else {
353 /* SET */
354 if (!dbg_packet_findstring(inpack, req->icondition, &condition, &sz))
355 condition = NULL;
356
357 if (req->imod_name!=0 || req->mod_no!=0 || req->line_no!=0) {
358 dbg_packet_findstring(inpack, req->imod_name, &mod_name, &sz);
359
360 if (req->mod_no==0) { /* by mod_name */
361 if (mod_name==NULL || strlen(mod_name) == 0)
362 return listout_bp_item(pack, NULL, 0);
363 req->mod_no = DBG_FINDMODULE(mod_name);
364 }
365
366 if (req->mod_no!=0) { /* by mod_no */
367 mod_name = dbg_mod_name_by_no(req->mod_no TSRMLS_CC1(DBG));
368 if (mod_name == NULL)
369 return listout_bp_item(pack, NULL, 0);
370 }
371 }
372
373
374 prev_bp_no1 = 1;
375 bp_no = 1;
376 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
377 if (data->bp_no > prev_bp_no1) {
378 bp_no = prev_bp_no1;
379 break;
380 }
381 prev_bp_no1 = data->bp_no + 1;
382 bp_no = prev_bp_no1;
383 });
384
385 DBG_TRACE(("set bp#%d mod:'%s'(%d), line:%d, cond:'%s', tmp:%d, st:%d\n", bp_no, SON(mod_name), req->mod_no, req->line_no, condition, req->istemp, req->state));
386
387 item.bp_no = bp_no;
388 item.condition = (condition && strlen(condition) > 0) ? estrdup(condition) : NULL;
389 item.hitcount = 0;
390 item.istemp = req->istemp;
391 item.isunderhit = 0;
392 item.line_no = req->line_no;
393 item.mod_name = (mod_name && strlen(mod_name) > 0) ? estrdup(mod_name) : NULL;
394 item.skiphits = req->skiphits;
395 item.mod_no = req->mod_no;
396 item.state = req->state | BPS_UNRESOLVED;
397 zend_llist_add_element(&DBG(breakpoint_list), &item);
398 }
399
400 DBG(breakpoint_list_inv) = 1;
401 dbg_rebuild_bplist(TSRMLS_C1(DBG));
402 dbg_llist_sort(&DBG(breakpoint_list), bp_no_cmp);
403
404
405 pitem = find_bp_item_by_no(bp_no TSRMLS_CC1(DBG));
406 return listout_bp_item(pack, pitem, bp_no);
407 }