]> granicus.if.org Git - php/commitdiff
Fix phpdbg ZTS watchpoint+shutdown sequences & opcache+watchpoints
authorBob Weinand <bobwei9@hotmail.com>
Tue, 12 Jul 2016 18:35:54 +0000 (20:35 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Tue, 12 Jul 2016 18:50:51 +0000 (20:50 +0200)
run-tests.php
sapi/phpdbg/phpdbg.c
sapi/phpdbg/phpdbg_watch.c

index fd4e12081f3055cc4045dcb40eb775af07afa4df..0dcf21bcbf5bdfae6b1883fae91f423e69fdcbc5 100755 (executable)
@@ -1366,6 +1366,7 @@ TEST $file
                                return 'SKIPPED';
                        }
                }
+               $uses_cgi = true;
        }
 
        /* For phpdbg tests, check if phpdbg sapi is available and if it is, use it. */
@@ -1916,7 +1917,7 @@ COMMAND $cmd
        /* when using CGI, strip the headers from the output */
        $headers = "";
 
-       if (isset($old_php) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) {
+       if (!empty($uses_cgi) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) {
                $output = trim($match[2]);
                $rh = preg_split("/[\n\r]+/", $match[1]);
                $headers = array();
index 0d0b4b41cadf992e3e5062e7d3f1cf68824a75dc..bf11359bb084888475f32cc65950d085c8d96774 100644 (file)
@@ -77,6 +77,63 @@ static zend_bool phpdbg_booted = 0;
 static zend_bool phpdbg_fully_started = 0;
 zend_bool use_mm_wrappers = 0;
 
+static void php_phpdbg_destroy_bp_file(zval *brake) /* {{{ */
+{
+       zend_hash_destroy(Z_ARRVAL_P(brake));
+       efree(Z_ARRVAL_P(brake));
+} /* }}} */
+
+static void php_phpdbg_destroy_bp_symbol(zval *brake) /* {{{ */
+{
+       efree((char *) ((phpdbg_breaksymbol_t *) Z_PTR_P(brake))->symbol);
+       efree(Z_PTR_P(brake));
+} /* }}} */
+
+static void php_phpdbg_destroy_bp_opcode(zval *brake) /* {{{ */
+{
+       efree((char *) ((phpdbg_breakop_t *) Z_PTR_P(brake))->name);
+       efree(Z_PTR_P(brake));
+} /* }}} */
+
+static void php_phpdbg_destroy_bp_opline(zval *brake) /* {{{ */
+{
+       efree(Z_PTR_P(brake));
+} /* }}} */
+
+static void php_phpdbg_destroy_bp_methods(zval *brake) /* {{{ */
+{
+       zend_hash_destroy(Z_ARRVAL_P(brake));
+       efree(Z_ARRVAL_P(brake));
+} /* }}} */
+
+static void php_phpdbg_destroy_bp_condition(zval *data) /* {{{ */
+{
+       phpdbg_breakcond_t *brake = (phpdbg_breakcond_t *) Z_PTR_P(data);
+
+       if (brake->ops) {
+               destroy_op_array(brake->ops);
+               efree(brake->ops);
+       }
+       efree((char*) brake->code);
+       efree(brake);
+} /* }}} */
+
+static void php_phpdbg_destroy_registered(zval *data) /* {{{ */
+{
+       zend_function *function = (zend_function *) Z_PTR_P(data);
+       destroy_zend_function(function);
+} /* }}} */
+
+static void php_phpdbg_destroy_file_source(zval *data) /* {{{ */
+{
+       phpdbg_file_source *source = (phpdbg_file_source *) Z_PTR_P(data);
+       destroy_op_array(&source->op_array);
+       if (source->buf) {
+               efree(source->buf);
+       }
+       efree(source);
+} /* }}} */
+
 static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
 {
        pg->prompt[0] = NULL;
@@ -124,7 +181,24 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
 
 static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
 {
-       ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], 8, NULL, php_phpdbg_destroy_bp_file, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], 8, NULL, php_phpdbg_destroy_bp_symbol, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], 8, NULL, php_phpdbg_destroy_bp_opline, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], 8, NULL, php_phpdbg_destroy_bp_opcode, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0);
+       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0);
+
+       zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
+       zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0);
+
+       zend_hash_init(&PHPDBG_G(file_sources), 0, NULL, php_phpdbg_destroy_file_source, 0);
+       phpdbg_setup_watchpoints();
+
        REGISTER_INI_ENTRIES();
 
        zend_execute_ex = phpdbg_execute_ex;
@@ -143,63 +217,76 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
        return SUCCESS;
 } /* }}} */
 
-static void php_phpdbg_destroy_bp_file(zval *brake) /* {{{ */
+static PHP_MSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
 {
-       zend_hash_destroy(Z_ARRVAL_P(brake));
-       efree(Z_ARRVAL_P(brake));
-} /* }}} */
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
+       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]);
+       zend_hash_destroy(&PHPDBG_G(file_sources));
+       zend_hash_destroy(&PHPDBG_G(seek));
+       zend_hash_destroy(&PHPDBG_G(registered));
+       phpdbg_destroy_watchpoints();
 
-static void php_phpdbg_destroy_bp_symbol(zval *brake) /* {{{ */
-{
-       efree((char *) ((phpdbg_breaksymbol_t *) Z_PTR_P(brake))->symbol);
-       efree(Z_PTR_P(brake));
-} /* }}} */
+       if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
+               phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+       }
 
-static void php_phpdbg_destroy_bp_opcode(zval *brake) /* {{{ */
-{
-       efree((char *) ((phpdbg_breakop_t *) Z_PTR_P(brake))->name);
-       efree(Z_PTR_P(brake));
-} /* }}} */
+       /* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
+       if (use_mm_wrappers) {
+               /* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
+               *(int *) zend_mm_get_heap() = 0;
+       }
 
-static void php_phpdbg_destroy_bp_opline(zval *brake) /* {{{ */
-{
-       efree(Z_PTR_P(brake));
-} /* }}} */
+       if (PHPDBG_G(buffer)) {
+               free(PHPDBG_G(buffer));
+               PHPDBG_G(buffer) = NULL;
+       }
 
-static void php_phpdbg_destroy_bp_methods(zval *brake) /* {{{ */
-{
-       zend_hash_destroy(Z_ARRVAL_P(brake));
-       efree(Z_ARRVAL_P(brake));
-} /* }}} */
+       if (PHPDBG_G(exec)) {
+               efree(PHPDBG_G(exec));
+               PHPDBG_G(exec) = NULL;
+       }
 
-static void php_phpdbg_destroy_bp_condition(zval *data) /* {{{ */
-{
-       phpdbg_breakcond_t *brake = (phpdbg_breakcond_t *) Z_PTR_P(data);
+       if (PHPDBG_G(oplog)) {
+               fclose(PHPDBG_G(oplog));
+               PHPDBG_G(oplog) = NULL;
+       }
 
-       if (brake->ops) {
-               destroy_op_array(brake->ops);
-               efree(brake->ops);
+       if (PHPDBG_G(ops)) {
+               destroy_op_array(PHPDBG_G(ops));
+               efree(PHPDBG_G(ops));
+               PHPDBG_G(ops) = NULL;
        }
-       efree((char*) brake->code);
-       efree(brake);
-} /* }}} */
 
-static void php_phpdbg_destroy_registered(zval *data) /* {{{ */
-{
-       zend_function *function = (zend_function *) Z_PTR_P(data);
-       destroy_zend_function(function);
-} /* }}} */
+       if (PHPDBG_G(oplog_list)) {
+               phpdbg_oplog_list *cur = PHPDBG_G(oplog_list);
+               do {
+                       phpdbg_oplog_list *prev = cur->prev;
+                       efree(cur);
+                       cur = prev;
+               } while (cur != NULL);
 
-static void php_phpdbg_destroy_file_source(zval *data) /* {{{ */
-{
-       phpdbg_file_source *source = (phpdbg_file_source *) Z_PTR_P(data);
-       destroy_op_array(&source->op_array);
-       if (source->buf) {
-               efree(source->buf);
+               zend_arena_destroy(PHPDBG_G(oplog_arena));
+               PHPDBG_G(oplog_list) = NULL;
        }
-       efree(source);
-} /* }}} */
 
+       fflush(stdout);
+       if (SG(request_info).argv0) {
+               free(SG(request_info).argv0);
+               SG(request_info).argv0 = NULL;
+       }
+
+       return SUCCESS;
+}
+/* }}} */
 
 static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
 {
@@ -701,7 +788,7 @@ static zend_module_entry sapi_phpdbg_module_entry = {
        PHPDBG_NAME,
        phpdbg_user_functions,
        PHP_MINIT(phpdbg),
-       NULL,
+       PHP_MSHUTDOWN(phpdbg),
        PHP_RINIT(phpdbg),
        PHP_RSHUTDOWN(phpdbg),
        NULL,
@@ -796,93 +883,13 @@ static void php_sapi_phpdbg_log_message(char *message, int syslog_type_int) /* {
 
 static int php_sapi_phpdbg_activate(void) /* {{{ */
 {
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], 8, NULL, php_phpdbg_destroy_bp_file, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], 8, NULL, php_phpdbg_destroy_bp_symbol, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], 8, NULL, php_phpdbg_destroy_bp_opline, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], 8, NULL, php_phpdbg_destroy_bp_opcode, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0);
-       zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0);
-
-       zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
-       zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0);
-
-       zend_hash_init(&PHPDBG_G(file_sources), 0, NULL, php_phpdbg_destroy_file_source, 0);
-       phpdbg_setup_watchpoints();
-
        return SUCCESS;
 }
 
 static int php_sapi_phpdbg_deactivate(void) /* {{{ */
 {
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
-       zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]);
-       zend_hash_destroy(&PHPDBG_G(file_sources));
-       zend_hash_destroy(&PHPDBG_G(seek));
-       zend_hash_destroy(&PHPDBG_G(registered));
-       phpdbg_destroy_watchpoints();
-
-       /* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
-       if (use_mm_wrappers) {
-               /* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
-               *(int *) zend_mm_get_heap() = 0;
-       }
-
-       if (PHPDBG_G(buffer)) {
-               free(PHPDBG_G(buffer));
-               PHPDBG_G(buffer) = NULL;
-       }
-
-       if (PHPDBG_G(exec)) {
-               efree(PHPDBG_G(exec));
-               PHPDBG_G(exec) = NULL;
-       }
-
-       if (PHPDBG_G(oplog)) {
-               fclose(PHPDBG_G(oplog));
-               PHPDBG_G(oplog) = NULL;
-       }
-
-       if (PHPDBG_G(ops)) {
-               destroy_op_array(PHPDBG_G(ops));
-               efree(PHPDBG_G(ops));
-               PHPDBG_G(ops) = NULL;
-       }
-
-       if (PHPDBG_G(oplog_list)) {
-               phpdbg_oplog_list *cur = PHPDBG_G(oplog_list);
-               do {
-                       phpdbg_oplog_list *prev = cur->prev;
-                       efree(cur);
-                       cur = prev;
-               } while (cur != NULL);
-
-               zend_arena_destroy(PHPDBG_G(oplog_arena));
-               PHPDBG_G(oplog_list) = NULL;
-       }
-
-       fflush(stdout);
-       if (SG(request_info).argv0) {
-               free(SG(request_info).argv0);
-               SG(request_info).argv0 = NULL;
-       }
-
        return SUCCESS;
 }
-/* }}} */
 
 static void php_sapi_phpdbg_register_vars(zval *track_vars_array) /* {{{ */
 {
@@ -1358,6 +1365,7 @@ int main(int argc, char **argv) /* {{{ */
        setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
 #endif
 
+phpdbg_main:
 #ifdef ZTS
        tsrm_startup(1, 1, 0, NULL);
        (void)ts_resource(0);
@@ -1366,7 +1374,6 @@ int main(int argc, char **argv) /* {{{ */
 
        zend_signal_startup();
 
-phpdbg_main:
        ini_entries = NULL;
        ini_entries_len = 0;
        ini_ignore = 0;
@@ -1446,9 +1453,6 @@ phpdbg_main:
                        /* begin phpdbg options */
 
                        case 'S': { /* set SAPI name */
-                               if (sapi_name) {
-                                       free(sapi_name);
-                               }
                                sapi_name = strdup(php_optarg);
                        } break;
 
@@ -1523,6 +1527,7 @@ phpdbg_main:
                        } break;
 
                        case 'h': {
+                               ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
                                sapi_startup(phpdbg);
                                phpdbg->startup(phpdbg);
                                PHPDBG_G(flags) = 0;
@@ -1538,6 +1543,7 @@ phpdbg_main:
                        } break;
 
                        case 'V': {
+                               ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
                                sapi_startup(phpdbg);
                                phpdbg->startup(phpdbg);
                                printf(
@@ -1614,6 +1620,20 @@ phpdbg_main:
 
        phpdbg->ini_entries = ini_entries;
 
+       ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
+
+       if (settings > (zend_phpdbg_globals *) 0x2) {
+#ifdef ZTS
+               *((zend_phpdbg_globals *) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(phpdbg_globals_id)]) = *settings;
+#else
+               phpdbg_globals = *settings;
+#endif
+               free(settings);
+       }
+
+       /* set flags from command line */
+       PHPDBG_G(flags) = flags;
+
        if (phpdbg->startup(phpdbg) == SUCCESS) {
                zend_mm_heap *mm_heap;
 #ifdef _WIN32
@@ -1624,18 +1644,6 @@ phpdbg_main:
                void (*_free)(void*);
                void* (*_realloc)(void*, size_t);
 
-               /* set flags from command line */
-               PHPDBG_G(flags) = flags;
-
-               if (settings > (zend_phpdbg_globals *) 0x2) {
-#ifdef ZTS
-                       *((zend_phpdbg_globals *) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(phpdbg_globals_id)]) = *settings;
-#else
-                       phpdbg_globals = *settings;
-#endif
-                       free(settings);
-               }
-
                /* setup remote server if necessary */
                if (cleaning <= 0 && listen > 0) {
                        server = phpdbg_open_socket(address, listen);
@@ -2008,28 +2016,47 @@ phpdbg_out:
                        exit_status = EG(exit_status);
                }
 
+               php_output_deactivate();
+
                if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
+                       PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
                        if (PHPDBG_G(in_execution) || is_exit) {
                                if (!quit_immediately && !phpdbg_startup_run) {
-                                       phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+                                       PHPDBG_G(flags) -= PHPDBG_IS_QUITTING;
                                        cleaning++;
                                }
                        }
                }
-               php_output_deactivate();
 
                zend_try {
                        php_module_shutdown();
                } zend_end_try();
 
 #ifndef _WIN32
+               signal(SIGSEGV, SIG_DFL);
+               signal(SIGBUS, SIG_DFL);
+
                /* reset it... else we risk a stack overflow upon next run (when clean'ing) */
                php_stream_stdio_ops.write = PHPDBG_G(php_stdiop_write);
 #endif
+       }
+
+       sapi_shutdown();
 
-               sapi_shutdown();
+#ifdef ZTS
+       ts_free_id(phpdbg_globals_id);
+#endif
+
+       if (sapi_name) {
+               free(sapi_name);
        }
 
+       zend_signal_shutdown();
+
+#ifdef ZTS
+       tsrm_shutdown();
+#endif
+
        if ((cleaning > 0 || remote) && !quit_immediately) {
                /* reset internal php_getopt state */
                php_getopt(-1, argv, OPTIONS, NULL, &php_optind, 0, 0);
@@ -2037,21 +2064,12 @@ phpdbg_out:
                goto phpdbg_main;
        }
 
-#ifdef ZTS
-       /* bugggy */
-       /* tsrm_shutdown(); */
-#endif
-
 #ifndef _WIN32
        if (address) {
                free(address);
        }
 #endif
 
-       if (PHPDBG_G(sapi_name_ptr)) {
-               free(PHPDBG_G(sapi_name_ptr));
-       }
-
        /* usually 0; just for -rr */
        return exit_status;
 } /* }}} */
index e01e9a787dbc55aea0a33c873e5df24befd054ed..63af56793be545f80a5c42693f52101dfcb6db94 100644 (file)
@@ -939,7 +939,7 @@ zend_string *phpdbg_watchpoint_change_collision_name(phpdbg_watchpoint_t *watch)
        }
        ZEND_HASH_FOREACH_PTR(&watch->elements, element) {
                if (element->flags & PHPDBG_WATCH_IMPLICIT) {
-                       if ((watch->type == WATCH_ON_ZVAL || watch->type == WATCH_ON_BUCKET) && Z_REFCOUNTED(watch->backup.zv)) {
+                       if ((watch->type == WATCH_ON_ZVAL || watch->type == WATCH_ON_BUCKET) && Z_TYPE(watch->backup.zv) > IS_STRING) {
                                phpdbg_update_watch_element_watch(element->child);
                        }
                        continue;