"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  */