"Fossies" - the Fresh Open Source Software Archive 
Member "dbg-2.15.5/dbg.c" (28 Apr 2007, 33374 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.c" see the
Fossies "Dox" file reference documentation.
1 /***************************************************************************
2 dbg.c - description
3 -------------------
4 begin : Sun Sep 24 2000
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
17 #include "php.h"
18 #include "php_ini.h"
19 #include "ext/standard/info.h"
20 #include "php_compat.h"
21 #include "php_network.h"
22 #include "php_logos.h"
23 #include "SAPI.h"
24
25 #if PHP_WIN32 || defined WIN32
26 #include "config.w32.h"
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33
34 #include "php_dbg.h"
35 #include "dbg_cmd.h"
36 #include "dbg_prof.h"
37 #include "dbg_ser.h"
38 #include "dbg_bp.h"
39
40 #include "zend_extensions.h"
41
42 #ifdef ZTS
43 #include "TSRM.h"
44 #endif
45
46 #define php_module_dbg_name "dbg"
47 #define zend_ext_dbg_name "DBG"
48
49 /*ZEND_DECLARE_MODULE_GLOBALS(dbg); */
50 #ifdef ZTS
51 int DBG_globals_id;
52 #else
53 zend_DBG_globals DBG_globals;
54 #endif
55
56 zend_DBG_globals *pDBG_globals;
57
58 static int dbg_module_id;
59 static int is_dbg_ext_started;
60
61 static void (*orig_zend_error_cb)(int type, const char *err_mod_name, const uint err_line_no, const char *format, va_list args);
62
63 #if ZEND_EXTENSION_API_NO >= 20010710
64 static int (*orig_sapi_module_ub_write)(const char *str, unsigned int str_length TSRMLS_DC);
65 #else
66 static int (*orig_sapi_module_ub_write)(const char *str, unsigned int str_length);
67 #endif
68
69 /************************
70
71 INI Settings
72
73 *************************/
74
75 #define JIT_LEVEL_STR "debugger.JIT_level"
76 #define DEFAULT_JIT_LEVEL "3"
77
78 static PHP_INI_MH(on_update_JIT_level) {
79 TSRMLS_FETCH1_NOP(DBG);
80 if (!new_value) {
81 DBG(cfgprm_JIT_level) = 3;
82 } else {
83 DBG(cfgprm_JIT_level) = atoi(new_value);
84 if (DBG(cfgprm_JIT_level) < 0 || DBG(cfgprm_JIT_level) > 4) DBG(cfgprm_JIT_level) = 3;
85 }
86 switch (DBG(cfgprm_JIT_level)) {
87 case 0:
88 DBG(JIT_filter) = ERR_LEVEL0_MASK;
89 break;
90 case 1:
91 DBG(JIT_filter) = ERR_LEVEL1_MASK;
92 break;
93 case 2:
94 DBG(JIT_filter) = ERR_LEVEL2_MASK;
95 break;
96 case 3:
97 DBG(JIT_filter) = ERR_LEVEL3_MASK;
98 break;
99 case 4:
100 DBG(JIT_filter) = ERR_LEVEL4_MASK;
101 break;
102 }
103 return SUCCESS;
104 }
105
106 #if defined(ZEND_ENGINE_2)
107 #define OnUpdateInt OnUpdateLong
108 #endif
109
110 #define DBG_INI_BOOLEAN(name, dflt, fld) \
111 STD_PHP_INI_BOOLEAN(name, dflt, PHP_INI_ALL &~PHP_INI_USER, OnUpdateInt, fld, zend_DBG_globals, DBG_globals)
112 #define DBG_INI_STRING(name, dflt, fld) \
113 STD_PHP_INI_ENTRY(name, dflt, PHP_INI_ALL &~PHP_INI_USER, OnUpdateString, fld, zend_DBG_globals, DBG_globals)
114 #define DBG_INI_INT(name, dflt, fld) \
115 STD_PHP_INI_ENTRY(name, dflt, PHP_INI_ALL &~PHP_INI_USER, OnUpdateInt, fld, zend_DBG_globals, DBG_globals)
116
117 PHP_INI_BEGIN()
118 DBG_INI_BOOLEAN( "debugger.enabled", "0", cfgprm_enabled)
119 DBG_INI_BOOLEAN( "debugger.JIT_enabled", "0", cfgprm_JIT_enabled)
120 DBG_INI_STRING( "debugger.JIT_host", CLIENT_HOST, cfgprm_JIT_host)
121 DBG_INI_INT( "debugger.JIT_port", DEFAULT_PORT_STR, cfgprm_JIT_port)
122 DBG_INI_BOOLEAN( "debugger.fail_silently", "1", cfgprm_fail_silently)
123 DBG_INI_INT( "debugger.timeout_seconds", "300", cfgprm_timeout_seconds)
124 DBG_INI_BOOLEAN( "debugger.ignore_nops", "0", cfgprm_ignore_nops)
125 DBG_INI_BOOLEAN( "debugger.enable_session_cookie", "1", cfgprm_session_cookie)
126 DBG_INI_BOOLEAN( "debugger.session_nocache", "1", cfgprm_session_nocache)
127 DBG_INI_BOOLEAN( "debugger.profiler_enabled", "0", cfgprm_profiler_enabled)
128 PHP_INI_ENTRY( JIT_LEVEL_STR, DEFAULT_JIT_LEVEL, PHP_INI_ALL, on_update_JIT_level)
129 PHP_INI_END()
130
131
132 /************************
133
134 Destructors
135
136 *************************/
137
138 void bp_dtor(void *data) {
139 bp_item *item = data;
140 if (item->mod_name) {
141 efree(item->mod_name);
142 item->mod_name = NULL;
143 }
144 if (item->condition) {
145 efree(item->condition);
146 item->condition = NULL;
147 }
148 }
149
150 void back_trace_dtor(void *data) {
151 back_trace_item *item = data;
152 if (item->descr) {
153 efree(item->descr);
154 item->descr = NULL;
155 }
156 }
157
158 static void mod_list_dtor(void *data) {
159 mod_item *item = data;
160 if (item->profdata_arr) efree(item->profdata_arr);
161 item->profdata_arr = NULL;
162 if (item->mod_name) {
163 efree(item->mod_name);
164 item->mod_name = NULL;
165 }
166 }
167
168 static void ctxlines_dtor(void *data) {
169 ctxlines_item *item = data;
170 item->mod_name = NULL;
171 }
172
173 static void ctx_dtor(void *data) {
174 ctx_item *item = data;
175 if (item->mod_name) {
176 efree(item->mod_name);
177 item->mod_name = NULL;
178 }
179 if (item->function_name) {
180 efree(item->function_name);
181 item->function_name = NULL;
182 }
183 }
184
185
186 /************************
187
188 TSRM Memory (e.g. TLS)
189
190 *************************/
191
192 static void php_dbg_clearruntimeglobals(TSRMLS_D1(DBG)) {
193 DBG_TRACE(("php_dbg_clearruntimeglobals\n"));
194 DBG(clientversion) = 0;
195 DBG(curr_line_no) = 0;
196 DBG(curr_mod_name) = NULL;
197 DBG(curr_mod_no) = 0;
198 DBG(curr_mod) = NULL;
199 DBG(last_opline) = NULL;
200 DBG(debugger_flags) = 0;
201 DBG(debugger_step_depth) = 0;
202 DBG(in_eval) = 0;
203 DBG(eval_nest) = 0;
204 DBG(pause_cntr) = 0;
205 DBG(breakpoint_list_inv) = 0;
206 DBG(back_trace_count) = 0;
207 DBG(ctx_counter) = 0;
208 DBG(e_time) = 0;
209 DBG(l_time) = 0;
210 DBG(deactivate_inprocess) = 0;
211 DBG(session_cookie_added) = 0;
212 }
213
214 TS_ALLOC_CTOR_FUNCTION(DBG) {
215 /*void php_dbg_init_globals(TSRMLS_D1(DBG)) { */
216
217 DBG_TRACE(("TS_ALLOC_CTOR_FUNCTION(DBG)\n"));
218 #ifdef ZTS
219 pDBG_globals = DBG_globals;
220 #else
221 pDBG_globals = &DBG_globals;
222 #endif
223
224 DBG(is_extension_activated) = 0;
225 DBG(is_failed_connection) = 0;
226
227 DBG(sesstype) = 0;
228 DBG(error_filter) = ERR_LEVEL3_MASK;
229 DBG(debug_socket) = 0;
230 DBG(req_client_port) = 0;
231 DBG(req_client_ip_address) = NULL;
232 DBG(client_port) = 0;
233 DBG(client_address) = NULL;
234 DBG(session_id) = NULL;
235 DBG(req_sess_var) = NULL;
236 DBG(eval_error) = NULL;
237 DBG(opt_flags) = SOF_DEFAULT;
238 DBG(output_str_nd) = NULL;
239 DBG(output_str_nd_len) = 0;
240 DBG(output_str_nd_limit) = 0;
241 php_dbg_clearruntimeglobals(TSRMLS_C1(DBG));
242
243 DBG(JIT_filter) = ERR_LEVEL3_MASK;
244
245 memset(&DBG(global_bp_arr), 0, sizeof(DBG(global_bp_arr)));
246 memset(&DBG(back_trace), 0, sizeof(DBG(back_trace)));
247 memset(&DBG(mod_list), 0, sizeof(DBG(mod_list)));
248 memset(&DBG(breakpoint_list), 0, sizeof(DBG(breakpoint_list)));
249 memset(&DBG(ctxlines_list), 0, sizeof(DBG(ctxlines_list)));
250 memset(&DBG(ctx_list), 0, sizeof(DBG(ctx_list)));
251
252 zend_llist_init(&DBG(back_trace), sizeof(back_trace_item), back_trace_dtor, 0);
253 zend_llist_init(&DBG(mod_list),sizeof(mod_item),mod_list_dtor, 0);
254 zend_llist_init(&DBG(breakpoint_list), sizeof(bp_item), bp_dtor, 0);
255 zend_llist_init(&DBG(ctxlines_list), sizeof(ctxlines_item), ctxlines_dtor, 0);
256 zend_llist_init(&DBG(ctx_list), sizeof(ctx_item), ctx_dtor, 0);
257 dbg_packet_new(&DBG(logpack));
258
259 DBG(is_globals_initialized) = 1;
260 }
261
262 static void module_cleanup(TSRMLS_D1(DBG)) {
263 DBG_TRACE(("module_cleanup\n"));
264 DBG(is_globals_initialized) = 0;
265 DBG(is_extension_activated) = 0;
266 DBG(is_failed_connection) = 0;
267 if (DBG(req_client_ip_address)) {
268 efree(DBG(req_client_ip_address));
269 DBG(req_client_ip_address) = NULL;
270 }
271 if (DBG(client_address)) {
272 DBG_TRACE(("client_address = %x\n", SON(DBG(client_address))));
273 efree(DBG(client_address));
274 DBG(client_address) = NULL;
275 }
276 if (DBG(session_id)) {
277 efree(DBG(session_id));
278 DBG(session_id) = NULL;
279 }
280
281 if (DBG(debug_socket) > 0) {
282 DBG_TRACE(("close dbg socket(%d)\n", DBG(debug_socket)));
283 SCLOSE(DBG(debug_socket));
284 } else {
285 DBG_TRACE(("socket = (%d)\n", DBG(debug_socket)));
286 }
287 DBG(debug_socket) = 0;
288
289 if (DBG(req_sess_var)) {
290 efree(DBG(req_sess_var));
291 DBG(req_sess_var) = NULL;
292 }
293 if (DBG(mod_list).size) {
294 zend_llist_destroy(&DBG(mod_list));
295 memset(&DBG(mod_list), 0, sizeof(DBG(mod_list)));
296 }
297 if (DBG(breakpoint_list).size) {
298 zend_llist_destroy(&DBG(breakpoint_list));
299 memset(&DBG(breakpoint_list), 0, sizeof(DBG(breakpoint_list)));
300 }
301 if (DBG(back_trace).size) {
302 zend_llist_destroy(&DBG(back_trace));
303 memset(&DBG(back_trace), 0, sizeof(DBG(back_trace)));
304 DBG(back_trace_count) = 0;
305 }
306 if (DBG(eval_error)) {
307 efree(DBG(eval_error));
308 DBG(eval_error) = NULL;
309 }
310 if (DBG(ctxlines_list).size) {
311 zend_llist_destroy(&DBG(ctxlines_list));
312 memset(&DBG(ctxlines_list), 0, sizeof(DBG(ctxlines_list)));
313 }
314 if (DBG(ctx_list).size) {
315 zend_llist_destroy(&DBG(ctx_list));
316 memset(&DBG(ctx_list), 0, sizeof(DBG(ctx_list)));
317 }
318 bp_array_free(&DBG(global_bp_arr));
319 dbg_packet_free(&DBG(logpack));
320 if (DBG(output_str_nd)) {
321 efree(DBG(output_str_nd));
322 DBG(output_str_nd) = NULL;
323 DBG(output_str_nd_len) = 0;
324 }
325 php_dbg_clearruntimeglobals(TSRMLS_C1(DBG));
326 }
327
328 TS_ALLOC_DTOR_FUNCTION(DBG) {
329 DBG_TRACE(("TS_ALLOC_DTOR_FUNCTION\n"));
330 module_cleanup(TSRMLS_C1(DBG));
331 }
332
333
334 /**********************
335
336 S T E P B Y S T E P
337
338 **********************/
339
340 static inline int dbg_step( TSRMLS_D3(DBG,E,S) ) {
341 int ret_val = 0, hitcnt;
342
343 DBG_TRACE(("step: flags: %d\n", DBG(debugger_flags)));
344
345 hitcnt = dbg_chk_bp_hits(TSRMLS_C2(DBG,E));
346 if (DBGF(DBGF_STEPINTO)) {
347 ret_val = dbg_send_std_action(DBGC_STEPINTO_DONE, hitcnt TSRMLS_CC2(DBG, E));
348 } else if (DBGF(DBGF_STEPOVER) &&
349 DBG(back_trace_count) <= DBG(debugger_step_depth)) {
350 ret_val = dbg_send_std_action(DBGC_STEPOVER_DONE, hitcnt TSRMLS_CC2(DBG, E));
351 } else if (DBGF(DBGF_STEPOUT) &&
352 DBG(back_trace_count) < DBG(debugger_step_depth)) {
353 ret_val = dbg_send_std_action(DBGC_STEPOUT_DONE, hitcnt TSRMLS_CC2(DBG, E));
354 } else if (hitcnt > 0) {
355 ret_val = dbg_send_std_action(DBGC_BREAKPOINT, hitcnt TSRMLS_CC2(DBG, E));
356 }
357 return ret_val;
358 }
359
360 /**********************
361
362 P R O F I L E R
363
364 **********************/
365
366 static inline void dbg_store_prof_data(dbgint64 t TSRMLS_DC1(DBG)) {
367 mod_item* item;
368 profdata_item* pr_item;
369 dbgint line_no;
370
371 if (!DBG(cfgprm_profiler_enabled)) return;
372 item = dbg_mod_item_by_no(DBG(curr_mod_no) TSRMLS_CC1(DBG));
373 line_no = DBG(curr_line_no);
374 if (!item || !item->profdata_arr ||
375 line_no <= 0 || line_no >= item->profdata_items) return;
376 if (t < 0)
377 t=0;
378 pr_item = &(item->profdata_arr[line_no]);
379 if (pr_item->hitcount == 0) {
380 pr_item->tm_max = t;
381 pr_item->tm_min = t;
382 pr_item->tm_sum = t;
383 } else {
384 if (t > pr_item->tm_max) pr_item->tm_max = t;
385 if (t < pr_item->tm_min) pr_item->tm_min = t;
386 pr_item->tm_sum += t;
387 }
388 pr_item->hitcount++;
389 }
390
391
392 static void on_dbg_ub_write(const char *str, unsigned int str_length TSRMLS_DC2(DBG, E)) {
393 if (DBGO(SOF_SEND_OUTPUT) && DBGF(DBGF_STARTED) && !DBG(is_failed_connection)) {
394 dbg_send_log((char *)str, str_length, LT_OUTPUT, NULL, 0, 0 TSRMLS_CC2(DBG, E));
395 }
396 }
397
398
399 int dbg_ub_write(const char *str, unsigned int str_length TSRMLS_DC0) {
400 PROF_ENTER {
401 TSRMLS_FETCH2_NOP(DBG, E);
402 on_dbg_ub_write(str, str_length TSRMLS_CC2(DBG, E));
403 PROF_LEAVE;
404 }
405 if (orig_sapi_module_ub_write) {
406 return orig_sapi_module_ub_write(str,str_length TSRMLS_CC0);
407 } else {
408 return 0;
409 }
410 }
411
412 /**********************
413
414 E R R O R H A N D L I N G
415
416 **********************/
417
418 static int on_dbg_error_cb(int type, const char *err_mod_name, const uint err_line_no, const char *format, va_list args TSRMLS_DC4(DBG, E, C, S)) {
419 char buffer[2048];
420 int ret_val;
421 int can_send;
422 int is_started = 0;
423 int can_be_ignored = 0;
424
425 DBG_TRACE(("error_cb\n"));
426 can_send = (DBG(cfgprm_enabled) && !DBG(is_failed_connection));
427 if (!DBG(cfgprm_JIT_enabled) && !DBGF(DBGF_STARTED | DBGF_REQUESTPENDING)) return 1;
428
429 {
430 va_list args_copy;
431 va_copy(args_copy, args);
432 vsnprintf(buffer, sizeof(buffer)-1, format, args_copy);
433 va_end(args_copy);
434 }
435
436
437 buffer[sizeof(buffer)-1]=0;
438 /*strncat(buffer,"\n",sizeof(buffer));*/
439 DBG_TRACE(("err:\"%s\"\n",buffer));
440
441 if (!can_send) return 1;
442
443 if (DBG(in_eval)) {
444 /* zend_op *end=EG(active_op_array)->opcodes + EG(active_op_array)->last;*/
445 /* zend_op **opline_ptr = EG(opline_ptr);*/
446
447 if (!DBG(eval_error))
448 DBG(eval_error) = estrdup(buffer);
449
450
451 switch (type) {
452 case E_CORE_ERROR:
453 case E_ERROR:
454 case E_COMPILE_ERROR:
455 case E_USER_ERROR:
456 #if ZEND_EXTENSION_API_NO >= 20010710
457 zend_bailout();
458 #else
459 dbg_send_log(buffer, strlen(buffer), LT_FATALERROR, err_mod_name, err_line_no, type TSRMLS_CC2(DBG, E));
460 #endif
461 return 1;
462 }
463 /* if (!CG(in_compilation)) {
464 while ((*opline_ptr) < end && (*opline_ptr)->opcode != ZEND_RETURN) (*opline_ptr)++;
465 if ((*opline_ptr) >= end) {
466 (*opline_ptr)--;
467 (*opline_ptr)->opcode = ZEND_RETURN;
468 }
469 } */
470 return 0;
471 }
472
473 can_be_ignored = (DBG(error_filter) & type) == 0;
474 /* log */
475 if (DBGO(SOF_SEND_ERRORS)) {
476 dbg_send_log(buffer, strlen(buffer), LT_ERROR, err_mod_name, err_line_no, type TSRMLS_CC2(DBG, E));
477 }
478
479 DBG_FINDMODULE_ADD(err_mod_name); /* put file into the mod_list */
480 if (
481 ((DBG(cfgprm_JIT_enabled) && (DBG(JIT_filter) & type)) || (DBGF(DBGF_REQUESTPENDING) && !can_be_ignored)) &&
482 !DBGF(DBGF_STARTED) &&
483 can_send
484 ) {
485 is_started = 1;
486 if (!DBGF(DBGF_REQUESTPENDING)) {
487 dbg_start_session(DBG_JIT TSRMLS_CC3(DBG, E, S));
488 } else {
489 dbg_start_session(DBG_REQ TSRMLS_CC3(DBG, E, S));
490 }
491 }
492 if (DBGF(DBGF_STARTED) == 0) return 1;
493
494 /* error */
495 if (is_started || !can_be_ignored)
496 ret_val = dbg_send_error(buffer, type, err_mod_name, err_line_no TSRMLS_CC2(DBG, E));
497 return 1;
498 }
499
500 void dbg_error_cb(int type, const char *err_mod_name, const uint err_line_no, const char *format, va_list args) {
501 int ret_val = 1;
502 PROF_ENTER {
503 TSRMLS_FETCH4(DBG, E, C, S);
504 ret_val = on_dbg_error_cb(type, err_mod_name, err_line_no, format, args TSRMLS_CC4(DBG, E, C, S));
505 PROF_LEAVE;
506 }
507 if (ret_val) {
508 if (orig_zend_error_cb) /* standard handler */
509 orig_zend_error_cb(type, err_mod_name, err_line_no, format, args);
510 switch (type) { /* terminate in certain cases */
511 case E_CORE_ERROR:
512 case E_ERROR:
513 case E_COMPILE_ERROR:
514 case E_USER_ERROR:
515 zend_bailout(); /* terminate anyway, PHP/Zend can not recover on such errors */
516 }
517 }
518 }
519
520 /*************************
521
522 DBG ZEND EXTENSION
523
524 *************************/
525
526
527 int dbg_startup(zend_extension *extension) {
528 /* int module_number; */
529 TSRMLS_FETCH1(P);
530
531 DBG_TRACE(("dbg_startup Zend extension\n"));
532 if (is_dbg_ext_started) return FAILURE;
533 is_dbg_ext_started = 1;
534 /* module_number = (dbg_module_id) ? dbg_module_id : (int)extension->handle; */
535 /* ZEND_INIT_MODULE_GLOBALS(dbg, php_dbg_init_globals, php_dbg_uninit_globals);*/
536
537 orig_zend_error_cb = zend_error_cb;
538 zend_error_cb = dbg_error_cb;
539 orig_sapi_module_ub_write = sapi_module.ub_write;
540 sapi_module.ub_write = dbg_ub_write;
541 return SUCCESS;
542 }
543
544 void dbg_shutdown(zend_extension *extension) {
545 /* int module_number; */
546 /* TSRMLS_FETCH1(P); */
547
548 DBG_TRACE(("dbg_shutdown Zend extension\n"));
549 /* module_number = (dbg_module_id) ? dbg_module_id : (int)extension->handle; */
550 zend_error_cb = orig_zend_error_cb;
551 sapi_module.ub_write = orig_sapi_module_ub_write;
552 is_dbg_ext_started = 0;
553
554 return;
555 }
556
557 NOPRM(dbg_activate) {
558 TSRMLS_FETCH2(DBG, C);
559
560 DBG_TRACE(("dbg_activate Zend extension\n"));
561 if (!DBG(is_globals_initialized)) {
562 TS_ALLOC_CTOR_CALL(DBG);
563 }
564 DBG(is_extension_activated) = 1;
565 if (DBG(cfgprm_enabled)) {
566 CG(extended_info) = 1;
567 }
568 }
569
570 NOPRM(dbg_deactivate) {
571 TSRMLS_FETCH1(C);
572
573 DBG_TRACE(("dbg_deactivate Zend extension\n"));
574 CG(extended_info) = 0;
575
576 /* TS_ALLOC_DTOR_CALL(DBG); */
577 }
578
579 void dbg_op_array_handler(zend_op_array *op_array) {
580 zend_op *op, *op_end;
581 unsigned int line_no, max_line_no;
582 dbgint mod_no;
583 ctxlines_item lines_item;
584 ctx_item item;
585 mod_item *pmod;
586
587 PROF_ENTER {
588 TSRMLS_FETCH2(DBG, C);
589 DBG_TRACE(("dbg_op_array_handler %s:%s\n", SON(op_array->filename), SON(op_array->function_name)));
590
591 if (!DBG(is_extension_activated) || DBG(is_failed_connection)) return;
592 if (!DBG(cfgprm_JIT_enabled) && !DBGF(DBGF_STARTED | DBGF_REQUESTPENDING)) return;
593
594 op = op_array->opcodes;
595 op_end = op + op_array->last;
596
597 pmod = dbg_findmodule(op_array->filename, 1 TSRMLS_CC1(DBG));
598 mod_no = (pmod) ? (pmod->mod_no) : 0;
599
600 DBG(ctx_counter)++;
601 item.ctx_id = DBG(ctx_counter);
602 item.op_array = op_array;
603 if (op_array->function_name) {
604 if (CG(active_class_entry)) {
605 char fnname[256];
606 snprintf(fnname, sizeof(fnname)-1, "%s::%s", CG(active_class_entry)->name, op_array->function_name);
607 fnname[sizeof(fnname)-1] = 0;
608 item.function_name = estrdup(fnname);
609 } else
610 item.function_name = estrdup(op_array->function_name);
611 } else
612 item.function_name = NULL;
613 item.mod_name = estrdup(op_array->filename);
614 zend_llist_add_element(&DBG(ctx_list), &item);
615
616 max_line_no = 0;
617 while (op < op_end) {
618 /* if (op_array->function_name != NULL) */
619 if (DBG(cfgprm_ignore_nops)) {
620 while (op < op_end && (op->opcode==ZEND_NOP || op->opcode==ZEND_EXT_STMT)) op++;
621 if (op >= op_end) break;
622 }
623 lines_item.start_line_no = op->lineno;
624 op++;
625 line_no = lines_item.start_line_no;
626 while (op < op_end) {
627 if (op->lineno==line_no) {
628 } else if (op->lineno==line_no+1) {
629 line_no++;
630 } else break;
631 op++;
632 }
633 lines_item.lines_cnt = line_no - lines_item.start_line_no + 1;
634 if (lines_item.lines_cnt > 0) {
635
636 if (line_no > max_line_no) max_line_no = line_no;
637
638 lines_item.ctx_id = DBG(ctx_counter);
639 lines_item.mod_name = pmod->mod_name;
640 lines_item.mod_no = mod_no;
641 zend_llist_add_element(&DBG(ctxlines_list), &lines_item);
642 }
643 }
644
645 if (DBG(cfgprm_profiler_enabled) && max_line_no) {
646 int sz, items, oldsz;
647 items = (max_line_no + 1 + 64) & ~63;
648 if (items > pmod->profdata_items) {
649 oldsz = sizeof(profdata_item) * pmod->profdata_items;
650 pmod->profdata_items = items;
651 sz = sizeof(profdata_item) * items;
652 pmod->profdata_arr = erealloc(pmod->profdata_arr, sz);
653 memset((char *)pmod->profdata_arr + oldsz, 0, sz - oldsz);
654 }
655 }
656
657 pmod->lines_changed = 1;
658
659 PROF_LEAVE;
660 }
661 }
662
663 inline int on_dbg_statement_handler(zend_op_array *op_array TSRMLS_DC3(DBG, E, S)) {
664 dbgint line_no;
665 int ret_val = 0, mod_changed=0;
666 zend_op *opline;
667
668 DBG_TRACE(("statement:%s file:%s:%d\n", SON(op_array->function_name), SON(op_array->filename), zend_get_executed_lineno(TSRMLS_C1(E))));
669
670 /* track the tree of source files */
671 /* we must add new module even if it contains only NOPs, that is why this check is performed here */
672 if (op_array->filename!=DBG(curr_mod_name)) {
673 DBG(curr_mod) = dbg_findmodule(op_array->filename, 1 TSRMLS_CC1(DBG));
674 DBG(curr_mod_no) = (DBG(curr_mod)) ? (DBG(curr_mod)->mod_no) : 0;
675 DBG(curr_mod_name) = op_array->filename;
676
677 if (DBG(curr_mod)->lines_changed) {
678 dbg_resolve_bp(TSRMLS_C1(DBG));
679 dbg_rebuild_bplist_mod(DBG(curr_mod) TSRMLS_CC1(DBG));
680 }
681 mod_changed = 1;
682 }
683
684 /*ignore NOPs*/
685 opline = *EG(opline_ptr);
686 line_no = opline->lineno;
687 if (DBG(cfgprm_ignore_nops)) {
688 opline++;
689 switch (opline->opcode) {
690 case ZEND_EXT_NOP:
691 case ZEND_NOP:
692 return 0;
693 case ZEND_INCLUDE_OR_EVAL:
694 /* if (opline->op2.u.constant.value.lval == ZEND_EVAL) {
695 opline = opline;
696 }*/
697 break;
698 }
699 }
700
701 /* ignore if the same line is hit again */
702 if (line_no != DBG(curr_line_no) ||
703 (opline == DBG(last_opline) && !DBGF(DBGF_STEPOVER)) ||
704 mod_changed)
705 {
706 DBG(last_opline) = opline;
707 DBG(curr_line_no) = line_no;
708 DBG_TRACE(("step\n"));
709 ret_val = dbg_step(TSRMLS_C3(DBG, E, S));
710 } else {
711 DBG_TRACE(("the same line\n"));
712 }
713 if (!ret_val) {
714 if (DBG(pause_cntr)-- <= 0) {
715 DBG(pause_cntr) = 100;
716 if (dbg_checkpausereq(TSRMLS_C1(DBG))) {
717 dbg_send_std_action(DBGC_BREAKPOINT, 0 TSRMLS_CC2(DBG, E));
718 }
719 }
720 }
721 return ret_val;
722 }
723
724 void dbg_onsessfailed(int rslt) {
725 char buf[512];
726 TSRMLS_FETCH3(DBG, E, S);
727
728 switch (rslt) {
729 case ESESS_LOOKUP:
730 snprintf(buf, sizeof(buf), "client host address [%s] lookup failed", DBG(client_address)?DBG(client_address):"NULL");
731 break;
732 case ESESS_SOCK:
733 snprintf(buf, sizeof(buf), "failed to create TCP/IP socket");
734 break;
735 case ESESS_CONN:
736 snprintf(buf, sizeof(buf), "failed to establish connection to client host on <i>%s:%d</i>", DBG(client_address), DBG(client_port));
737 break;
738 default:
739 snprintf(buf, sizeof(buf), "internal error");
740 }
741 buf[sizeof(buf)-1] = '\0';
742
743 DBG_TRACE(("Failed to start debug session\n", buf));
744 php_printf("<html><body><h2>DBG</h2><br>Failed to start debug session<br><br>reason:<br>%s<br></body></html>", buf);
745 zend_bailout();
746 }
747
748 void dbg_statement_handler(zend_op_array *op_array) {
749 int is_new_line;
750 zend_op *opline;
751 int ret_val;
752
753 TSRMLS_FETCH3(DBG, E, S);
754 if (!DBGF(DBGF_STARTED | DBGF_REQUESTPENDING)) return;
755
756 {
757 PROF_ENTER {
758 DBG_TRACE(("statement\n"));
759
760 if (!DBG(cfgprm_enabled) || DBG(is_failed_connection)) return;
761
762 opline = *EG(opline_ptr);
763 is_new_line = ((int)opline->lineno != DBG(curr_line_no) ||
764 op_array->filename!=DBG(curr_mod_name)
765 );
766 if (DBG(cfgprm_ignore_nops)) {
767 opline++;
768 is_new_line = (
769 opline->opcode!=ZEND_EXT_NOP &&
770 opline->opcode!=ZEND_NOP);
771 }
772
773 if (is_new_line) {
774 PROF_STORE_TIME(dbg_store_prof_data);
775 }
776
777
778
779 #ifdef DBG_204COMPAT
780 if (!DBGF(DBGF_STARTED)) {
781 DBG(debugger_flags) &= ~DBGF_REQUESTPENDING;
782 ret_val = dbg_start_session(DBG_COMPAT TSRMLS_CC3(DBG, E, S));
783 if (ret_val < 0)
784 dbg_onsessfailed(ret_val);
785 }
786 #else
787 if (DBGF(DBGF_STARTED | DBGF_REQUESTPENDING) == DBGF_REQUESTPENDING) {
788 DBG(debugger_flags) &= ~DBGF_REQUESTPENDING;
789 ret_val = dbg_start_session(DBG_REQ TSRMLS_CC3(DBG, E, S)); /* by request */
790 if (ret_val < 0)
791 dbg_onsessfailed(ret_val);
792 }
793 #endif
794
795 if (!DBGF(DBGF_STARTED)) return;
796
797 on_dbg_statement_handler(op_array TSRMLS_CC3(DBG, E, S));
798
799 PROF_LEAVE;
800 }
801 }
802 }
803
804 void dbg_fcall_begin_handler(zend_op_array *op_array) {
805 back_trace_item bt_item;
806 char descr[256];
807 mod_item *mod;
808
809 TSRMLS_FETCH2(DBG, E);
810
811 DBG_TRACE(("begin fcall function:%s file:%s:%d\n", SON(op_array->function_name), SON(op_array->filename), zend_get_executed_lineno(TSRMLS_C1(E))));
812
813 /* if (!DBG(cfgprm_JIT_enabled) && DBGF(DBGF_STARTED) == 0) return; */
814 if (!DBG(is_extension_activated) || DBG(is_failed_connection)) return;
815
816 bt_item.active_sym_table = EG(active_symbol_table);
817 bt_item.line_no = (*EG(opline_ptr))->lineno;
818 if (EG(active_op_array)->function_name) {
819 snprintf(descr, sizeof(descr)-1, "%s()", EG(active_op_array)->function_name);
820 } else if (EG(active_op_array)->filename) {
821 snprintf(descr, sizeof(descr)-1, "%s::main()", EG(active_op_array)->filename);
822 } else descr[0]=0;
823 descr[sizeof(descr)-1]=0;
824 bt_item.descr = estrdup(descr);
825
826 mod = dbg_findmodule(EG(active_op_array)->filename, 1 TSRMLS_CC1(DBG));
827 bt_item.mod_no = (mod) ? (mod->mod_no) : (0);
828 zend_llist_add_element(&DBG(back_trace), &bt_item);
829 DBG(back_trace_count)++;
830 DBG_TRACE(("exit fcall\n"));
831 }
832
833 void dbg_fcall_end_handler(zend_op_array *op_array) {
834 /* back_trace_item *bt_item;*/
835 TSRMLS_FETCH2(DBG, E);
836
837 DBG_TRACE(("end fcall function:%s file:%s:%d\n", SON(op_array->function_name), SON(op_array->filename), zend_get_executed_lineno(TSRMLS_C1(E))));
838
839 /* if (!DBG(cfgprm_JIT_enabled) && DBGF(DBGF_STARTED) == 0) return; */
840 if (!DBG(is_extension_activated) || DBG(is_failed_connection)) return;
841
842 DBG(back_trace_count)--;
843 /*LLIST_ITEM_AT(DBG(back_trace), DBG(back_trace_count), bt_item);
844 zend_llist_del_element(&DBG(back_trace), bt_item, cmpll);*/
845 zend_llist_del_element(&DBG(back_trace), DBG(back_trace).tail->data, cmpll);
846 }
847
848 void dbg_op_array_ctor(zend_op_array *op_array) {
849 DBG_TRACE(("dbg_op_array_ctor\n"));
850 }
851
852 void dbg_op_array_dtor(zend_op_array *op_array) {
853 DBG_TRACE(("dbg_op_array_dtor\n"));
854 }
855
856 int dbg_api_no_check(int api_no) {
857 return ((ZEND_EXTENSION_API_NO==api_no)?SUCCESS:FAILURE);
858 }
859
860
861 #ifdef COMPILE_DL_DBG
862 #define DBG_EXT ZEND_DLEXPORT
863 #else
864 #define DBG_EXT
865 #endif
866
867 ext_compat_info dbg_compat_info = {
868 2001050101,
869 DBG_PROD_NAME,
870 2,
871 NULL
872 };
873
874 DBG_EXT zend_extension zend_extension_entry = {
875 zend_ext_dbg_name, /* name */
876 DBG_API_FULL_VERSION_STR, /* version */
877 "Dmitri Dmitrienko", /* author */
878 "www.nusphere.com", /* URL */
879 "(C) 2000,2007", /* copyright */
880 dbg_startup, dbg_shutdown,
881 dbg_activate, dbg_deactivate,
882 NULL,
883 dbg_op_array_handler, dbg_statement_handler,
884 dbg_fcall_begin_handler, dbg_fcall_end_handler,
885 dbg_op_array_ctor, dbg_op_array_dtor,
886 dbg_api_no_check,
887 NULL, /* reserved2 */
888 NULL, /* reserved3 */
889 NULL, /* reserved4 */
890 NULL, /* reserved5 */
891 NULL, /* reserved6 */
892 NULL, /* reserved7 */
893 &dbg_compat_info, /* reserved8 */
894 NULL, /* handle */
895 -1 /* resource_number */
896 };
897
898
899 /*************************
900
901 DBG ZEND MODULE
902
903 *************************/
904
905 int cmp_ext(void *element1, void *element2) {
906 return (element1==element2) ? 1:0;
907 }
908
909 PHP_MINIT_FUNCTION(dbg) {
910 DBG_TRACE(("module init\n"));
911 #if defined(PHP_WIN32) && defined(DBG_DEBUG_MEM)
912 _crtDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF;
913 #endif
914 ZEND_INIT_MODULE_GLOBALS(DBG, TS_ALLOC_CTOR(DBG), NULL);
915 REGISTER_INI_ENTRIES();
916
917 /* dbg_module_id = module_number; */
918 if (!zend_get_extension(zend_ext_dbg_name)) {
919 if (zend_register_extension(&zend_extension_entry,(DL_HANDLE)0)!=SUCCESS) {
920 return FAILURE;
921 }
922 }
923 return SUCCESS;
924 }
925
926 PHP_MSHUTDOWN_FUNCTION(dbg) {
927 zend_extension *ext;
928
929 #if ZEND_EXTENSION_API_NO < 20010710
930 TSRMLS_FETCH1_NOP(DBG);
931 #endif
932
933 DBG_TRACE(("module shutdown\n"));
934
935 ext = zend_get_extension(zend_ext_dbg_name);
936 if (ext) {
937 if (ext->shutdown) {
938 ext->shutdown(ext);
939 }
940 zend_llist_del_element(&zend_extensions, ext, cmp_ext);
941 }
942 UNREGISTER_INI_ENTRIES();
943 return SUCCESS;
944 }
945
946 int chk_scan_post(char *name, int name_length TSRMLS_DC1(DBG)) {
947 zval **data, **tmp;
948 char *string_key;
949 ulong num_key;
950 int ret_val;
951
952 TSRMLS_FETCH1_NOP(E);
953
954 DBG_TRACE(("chk_scan_post '%s'\n", SON(name)));
955
956 if (zend_hash_find(&EG(symbol_table), name, name_length+1, (void **) &data)!=FAILURE
957 && ((*data)->type==IS_ARRAY)) {
958 zend_hash_internal_pointer_reset((*data)->value.ht);
959 while (zend_hash_get_current_data((*data)->value.ht, (void **) &tmp) == SUCCESS) {
960 if (zend_hash_get_current_key((*data)->value.ht, &string_key, &num_key, 0) == HASH_KEY_IS_STRING &&
961 strcmp(string_key, DBGSESSVAR) == 0 &&
962 (*tmp)->type == IS_STRING) {
963 ret_val = parse_session_request((*tmp)->value.str.val, (*tmp)->value.str.len, '\0' TSRMLS_CC1(DBG));
964 DBG_TRACE(("chk_scan_post -> ret='%d'\n", ret_val));
965 if (ret_val) return ret_val;
966 }
967 zend_hash_move_forward((*data)->value.ht);
968 }
969 }
970 return 0;
971 }
972
973 int chk_session_request_post(TSRMLS_D2(DBG, S)) {
974 int ret_val;
975 ret_val = chk_scan_post("_POST", sizeof("_POST")-1 TSRMLS_CC1(DBG));
976 if (!ret_val) ret_val = chk_scan_post("HTTP_POST_VARS", sizeof("HTTP_POST_VARS")-1 TSRMLS_CC1(DBG));
977 if (!ret_val) ret_val = chk_scan_post("_COOKIE", sizeof("_COOKIE")-1 TSRMLS_CC1(DBG));
978 if (!ret_val) ret_val = chk_scan_post("HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS")-1 TSRMLS_CC1(DBG));
979 return (ret_val);
980 }
981
982 PHP_RINIT_FUNCTION(dbg) {
983 int isreq;
984 TSRMLS_FETCH2_NOP(DBG, S);
985
986 DBG_TRACE(("RINIT q='%s'\n", SON(SG(request_info).query_string)));
987
988 if (!DBG(is_extension_activated) || DBG(is_failed_connection) || !DBG(cfgprm_enabled)) return SUCCESS;
989
990 isreq = chk_session_request(SG(request_info).query_string, -1, '&' TSRMLS_CC1(DBG));
991 if (isreq == 0) isreq = chk_session_request_post(TSRMLS_C2(DBG, S));
992 if (isreq == 0) isreq = chk_session_request(SG(request_info).cookie_data, -1, ';' TSRMLS_CC1(DBG));
993 DBG_TRACE(("RINIT isreq='%d'\n", isreq));
994 if (isreq) {
995 DBG(debugger_flags) |= DBGF_REQUESTFOUND;
996 if (isreq > 0) {
997 DBG_TRACE(("DBGF_REQUESTPENDING(%d)\n", isreq));
998 if (!DBGF(DBGF_STARTED))
999 DBG(debugger_flags) |= DBGF_REQUESTPENDING;
1000 } else {
1001 DBG(debugger_flags) |= DBGF_REJECTIONFOUND;
1002 }
1003 add_session_cookie(TSRMLS_C2(DBG, S));
1004 }
1005 return SUCCESS;
1006 }
1007
1008 PHP_RSHUTDOWN_FUNCTION(dbg) {
1009
1010 #if ZEND_EXTENSION_API_NO < 20010710
1011 TSRMLS_FETCH2_NOP(DBG, E);
1012 #endif
1013
1014 DBG_TRACE(("PHP_RSHUTDOWN_FUNCTION\n"));
1015 DBG(debugger_flags) &= ~DBGF_WAITACK;
1016
1017 dbg_flush_log(TSRMLS_C2(DBG, E));
1018 dbg_stop_session(TSRMLS_C2(DBG, E));
1019
1020 module_cleanup(TSRMLS_C1(DBG));
1021 return SUCCESS;
1022 }
1023
1024 PHP_MINFO_FUNCTION(dbg) {
1025 int is_ext_ok = 0, is_text = 0;
1026 DBG_TRACE(("module info\n"));
1027 #ifdef ZTS
1028 is_ext_ok = (is_dbg_ext_started && (DBG_globals_id!=0));
1029 if (is_ext_ok) {
1030 TSRMLS_FETCH1_NOP(DBG);
1031 is_ext_ok = DBG(is_extension_activated) != 0;
1032 }
1033 #else
1034 is_ext_ok = is_dbg_ext_started && (DBG(is_extension_activated) != 0);
1035 #endif
1036
1037 /*
1038 4.2.3 and before
1039 4.3.0, 4.3.1 PG()
1040 4.3.2 and higher */
1041 #if (PHP_MAJOR_VERSION > 4) || ((PHP_MAJOR_VERSION == 4) && (PHP_MINOR_VERSION > 3)) || ((PHP_MAJOR_VERSION == 4) && (PHP_MINOR_VERSION == 3) && (PHP_RELEASE_VERSION >= 2))
1042 is_text = sapi_module.phpinfo_as_text;
1043 #elif ((PHP_MAJOR_VERSION == 4) && (PHP_MINOR_VERSION == 3) && (PHP_RELEASE_VERSION >= 0))
1044 is_text = PG(html_errors);
1045 #else
1046 is_text = 0;
1047 #endif
1048
1049 if (!is_text) {
1050 php_printf("\n<table border=0 style=\"border: 1px solid #000000;\" cellpadding=3 cellspacing=0 width=600 bgcolor=#33CCFF align=\"center\">");
1051 php_printf("<tr valign=\"top\" align=\"center\"><td style=\"border: 0px none; vertical-align: top;\">");
1052 php_printf("<b><a href=\"http://www.nusphere.com\" style='color: #660880; background-color: #33CCFF'>" DBG_API_DESCRIPTION "</a></b></td></tr>");
1053 php_printf("</table><br>\n");
1054 }
1055
1056 if (!is_ext_ok) {
1057 if (!is_text) {
1058 php_printf("<table border=1 cellpadding=0 cellspacing=0 width=600 bgcolor=red align=\"center\">\n");
1059 php_printf("<tr valign='middle' align='center'><td><font color=#ffff00>");
1060 php_printf("<b>PHP DBG ZExtension is not activated, yet.<br>Check configuration parameters in the php.ini file.</b>");
1061 php_printf("</font></td></tr>");
1062 php_printf("</table><br>\n");
1063 } else {
1064 php_printf("PHP DBG ZExtension is not activated, yet.\nCheck configuration parameters in the php.ini file.");
1065 }
1066 }
1067
1068 php_info_print_table_start();
1069 php_info_print_table_row(2, "Version", DBG_API_FULL_VERSION_STR);
1070 #ifdef COMPILE_DL_DBG
1071 php_info_print_table_row(2, "Linked", "as a shared library.");
1072 #else
1073 php_info_print_table_row(2, "Linked", "statically.");
1074 #endif
1075
1076
1077 #ifdef HAVE_DBG_PROFILER
1078 {
1079 int prof_enabled = 0;
1080 if (is_ext_ok) {
1081 TSRMLS_FETCH1_NOP(DBG);
1082 prof_enabled = DBG(cfgprm_profiler_enabled);
1083 }
1084 if (prof_enabled) {
1085 php_info_print_table_row(2, "Profiler", "compiled, enabled");
1086 } else {
1087 php_info_print_table_row(2, "Profiler", "compiled, disabled");
1088 }
1089 }
1090 #else
1091 php_info_print_table_row(2, "Profiler", "not compiled");
1092 #endif
1093 php_info_print_table_end();
1094 DISPLAY_INI_ENTRIES();
1095 }
1096
1097 /* {{{ proto bool DebugBreak()
1098 Breaks execution and starts Debug Session */
1099 PHP_FUNCTION(debugbreak){
1100 PROF_ENTER {
1101 int ok = 1;
1102 TSRMLS_FETCH2_NOP(DBG, S);
1103
1104 DBG_TRACE(("debugbreak()\n"));
1105 if (ZEND_NUM_ARGS()!=0) {
1106 WRONG_PARAM_COUNT;
1107 ok = 0;
1108 } else
1109 ok = (DBG(is_extension_activated) && !DBG(is_failed_connection) && DBG(cfgprm_enabled));
1110
1111 if (ok) {
1112 if (DBGF(DBGF_STARTED) == 0) {
1113 dbg_start_session(DBG_EMB TSRMLS_CC3(DBG, E, S));
1114 }
1115 ok = (DBGF(DBGF_STARTED) != 0);
1116 }
1117
1118 if (ok) {
1119 dbg_send_std_action(DBGC_EMBEDDED_BREAK, 0 TSRMLS_CC2(DBG,E));
1120 ok = !DBG(is_failed_connection);
1121 }
1122
1123 PROF_LEAVE;
1124 if (!ok) RETURN_FALSE;
1125 RETURN_TRUE;
1126 }
1127 }
1128 /* }}} */
1129
1130 /* {{{ proto bool OutputDebugString(string logstr)
1131 Outputs a message into Debugging Log if Debug Session is started */
1132 PHP_FUNCTION(outputdebugstring){
1133 pval *str;
1134 int ret_val;
1135
1136 TSRMLS_FETCH1_NOP(DBG);
1137 if (ZEND_NUM_ARGS()!=1) {
1138 WRONG_PARAM_COUNT;
1139 RETURN_FALSE;
1140 }
1141 if (!DBG(is_extension_activated) ||
1142 DBG(is_failed_connection) ||
1143 !DBG(cfgprm_enabled) ||
1144 !DBGO(SOF_SEND_LOGS)) RETURN_FALSE;
1145 getParameters(ht, 1, &str);
1146 convert_to_string(str);
1147 ret_val = dbg_send_log(Z_STRVAL_P(str), Z_STRLEN_P(str), LT_ODS, NULL, 0, 0 TSRMLS_CC2(DBG, E));
1148 RETURN_LONG(ret_val);
1149 }
1150 /* }}} */
1151
1152 function_entry dbg_functions[] = {
1153 PHP_FE(debugbreak, NULL)
1154 PHP_FE(outputdebugstring, NULL)
1155 #ifdef HAVE_DBG_PROFILER
1156 PHP_FE(dbg_get_profiler_results, NULL)
1157 #endif
1158 PHP_FE(dbg_get_all_module_names, NULL)
1159 PHP_FE(dbg_get_module_name, NULL)
1160 PHP_FE(dbg_get_all_contexts, NULL)
1161 PHP_FE(dbg_get_context_name, NULL)
1162 PHP_FE(dbg_get_all_source_lines, NULL)
1163 PHP_FE(dbg_get_source_context, NULL)
1164 {NULL, NULL, NULL}
1165 };
1166
1167
1168 zend_module_entry dbg_module_entry = {
1169 #if ZEND_EXTENSION_API_NO >= 20010710
1170 STANDARD_MODULE_HEADER,
1171 #endif
1172 php_module_dbg_name,
1173 dbg_functions,
1174 PHP_MINIT(dbg),
1175 PHP_MSHUTDOWN(dbg),
1176 PHP_RINIT(dbg),
1177 PHP_RSHUTDOWN(dbg),
1178 PHP_MINFO(dbg),
1179 #if ZEND_EXTENSION_API_NO >= 20010710
1180 DBG_API_FULL_VERSION_STR,
1181 #endif
1182 STANDARD_MODULE_PROPERTIES
1183 };
1184
1185 #ifdef COMPILE_DL_DBG
1186 ZEND_GET_MODULE(dbg)
1187 ZEND_DLEXPORT zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG };
1188 #endif
1189
1190 /*
1191 * Local variables:
1192 * tab-width: 4
1193 * c-basic-offset: 4
1194 * End:
1195 */