2013-11-09 22:35:03 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2015-03-13 09:09:42 +00:00
| PHP Version 7 |
2013-11-09 22:35:03 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2015-01-15 15:27:30 +00:00
| Copyright ( c ) 1997 - 2015 The PHP Group |
2013-11-09 22:35:03 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| This source file is subject to version 3.01 of the PHP license , |
| that is bundled with this package in the file LICENSE , and is |
| available through the world - wide - web at the following url : |
| http : //www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2013-11-17 12:40:51 +00:00
| Authors : Felipe Pena < felipe @ php . net > |
2013-11-09 22:35:03 +00:00
| Authors : Joe Watkins < joe . watkins @ live . co . uk > |
2013-12-23 22:55:07 +00:00
| Authors : Bob Weinand < bwoebi @ php . net > |
2013-11-09 22:35:03 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2013-11-09 23:07:04 +00:00
2014-03-16 18:39:02 +00:00
# if !defined(ZEND_SIGNALS) || defined(_WIN32)
2013-11-20 19:16:07 +00:00
# include <signal.h>
# endif
2015-02-10 14:30:54 +00:00
2013-11-10 10:44:42 +00:00
# include "phpdbg.h"
2013-11-10 19:15:32 +00:00
# include "phpdbg_prompt.h"
2013-11-10 21:38:58 +00:00
# include "phpdbg_bp.h"
2013-11-15 16:24:22 +00:00
# include "phpdbg_break.h"
2013-12-24 12:11:57 +00:00
# include "phpdbg_list.h"
2013-11-12 22:39:39 +00:00
# include "phpdbg_utils.h"
2013-11-24 14:54:14 +00:00
# include "phpdbg_set.h"
2014-10-19 19:20:43 +00:00
# include "phpdbg_io.h"
2014-01-10 18:54:07 +00:00
# include "zend_alloc.h"
2014-10-21 09:29:18 +00:00
# include "phpdbg_eol.h"
2015-04-19 19:53:49 +00:00
# include "phpdbg_print.h"
2014-01-10 18:54:07 +00:00
2015-02-10 14:30:54 +00:00
# include "ext/standard/basic_functions.h"
2013-11-28 22:06:27 +00:00
/* {{{ remote console headers */
2013-11-28 17:21:34 +00:00
# ifndef _WIN32
2013-11-28 22:06:27 +00:00
# include <sys / socket.h>
# include <sys / select.h>
# include <sys / time.h>
# include <sys / types.h>
2014-09-28 00:57:12 +00:00
# include <sys / poll.h>
2014-05-01 09:38:08 +00:00
# include <netinet / in.h>
2013-11-28 22:06:27 +00:00
# include <unistd.h>
# include <arpa / inet.h>
# endif /* }}} */
2013-11-27 16:49:51 +00:00
2015-07-03 05:10:46 +00:00
# if defined(PHP_WIN32) && defined(HAVE_OPENSSL)
# include "openssl / applink.c"
# endif
2013-11-10 10:44:42 +00:00
ZEND_DECLARE_MODULE_GLOBALS ( phpdbg ) ;
2014-10-26 02:50:28 +00:00
int phpdbg_startup_run = 0 ;
2013-11-10 10:44:42 +00:00
2014-10-21 08:35:20 +00:00
static PHP_INI_MH ( OnUpdateEol )
{
if ( ! new_value ) {
return FAILURE ;
}
2015-06-30 10:59:27 +00:00
return phpdbg_eol_global_update ( ZSTR_VAL ( new_value ) ) ;
2014-10-21 08:35:20 +00:00
}
2014-09-09 00:15:33 +00:00
PHP_INI_BEGIN ( )
STD_PHP_INI_ENTRY ( " phpdbg.path " , " " , PHP_INI_SYSTEM | PHP_INI_PERDIR , OnUpdateString , socket_path , zend_phpdbg_globals , phpdbg_globals )
2014-10-21 09:29:18 +00:00
STD_PHP_INI_ENTRY ( " phpdbg.eol " , " 2 " , PHP_INI_ALL , OnUpdateEol , socket_path , zend_phpdbg_globals , phpdbg_globals )
2014-09-09 00:15:33 +00:00
PHP_INI_END ( )
2013-12-05 11:20:16 +00:00
static zend_bool phpdbg_booted = 0 ;
2015-02-13 09:45:43 +00:00
static zend_bool phpdbg_fully_started = 0 ;
2013-12-05 11:20:16 +00:00
2013-11-10 15:47:28 +00:00
static inline void php_phpdbg_globals_ctor ( zend_phpdbg_globals * pg ) /* { { { */
{
2013-11-24 19:34:18 +00:00
pg - > prompt [ 0 ] = NULL ;
pg - > prompt [ 1 ] = NULL ;
2013-11-24 19:41:00 +00:00
2013-11-24 19:34:18 +00:00
pg - > colors [ 0 ] = NULL ;
pg - > colors [ 1 ] = NULL ;
pg - > colors [ 2 ] = NULL ;
2013-11-24 19:41:00 +00:00
2013-11-23 17:30:10 +00:00
pg - > exec = NULL ;
pg - > exec_len = 0 ;
2014-04-21 20:43:19 +00:00
pg - > buffer = NULL ;
2014-09-24 22:55:17 +00:00
pg - > last_was_newline = 1 ;
2013-11-23 17:30:10 +00:00
pg - > ops = NULL ;
pg - > vmret = 0 ;
2014-10-24 17:29:50 +00:00
pg - > in_execution = 0 ;
2013-11-23 17:30:10 +00:00
pg - > bp_count = 0 ;
pg - > flags = PHPDBG_DEFAULT_FLAGS ;
pg - > oplog = NULL ;
2014-09-28 00:57:12 +00:00
memset ( pg - > io , 0 , sizeof ( pg - > io ) ) ;
2013-11-23 17:30:10 +00:00
pg - > frame . num = 0 ;
2014-09-10 13:53:40 +00:00
pg - > sapi_name_ptr = NULL ;
2014-10-04 21:21:34 +00:00
pg - > socket_fd = - 1 ;
pg - > socket_server_fd = - 1 ;
2015-07-24 15:17:09 +00:00
pg - > unclean_eval = 0 ;
2014-10-04 21:21:34 +00:00
2014-10-06 09:26:08 +00:00
pg - > req_id = 0 ;
2014-09-21 02:17:19 +00:00
pg - > err_buf . active = 0 ;
pg - > err_buf . type = 0 ;
2014-10-07 11:08:30 +00:00
2014-09-28 00:57:12 +00:00
pg - > input_buflen = 0 ;
pg - > sigsafe_mem . mem = NULL ;
2014-10-02 23:29:41 +00:00
pg - > sigsegv_bailout = NULL ;
2014-10-20 20:12:58 +00:00
2015-07-15 20:30:12 +00:00
pg - > oplog_list = NULL ;
2014-10-20 20:12:58 +00:00
# ifdef PHP_WIN32
pg - > sigio_watcher_thread = INVALID_HANDLE_VALUE ;
memset ( & pg - > swd , 0 , sizeof ( struct win32_sigio_watcher_data ) ) ;
# endif
2014-10-21 07:55:22 +00:00
2014-10-21 09:29:18 +00:00
pg - > eol = PHPDBG_EOL_LF ;
2013-11-10 15:47:28 +00:00
} /* }}} */
2013-11-10 10:44:42 +00:00
2013-11-10 15:47:28 +00:00
static PHP_MINIT_FUNCTION ( phpdbg ) /* { { { */
{
2013-11-23 17:30:10 +00:00
ZEND_INIT_MODULE_GLOBALS ( phpdbg , php_phpdbg_globals_ctor , NULL ) ;
2014-09-09 00:15:33 +00:00
REGISTER_INI_ENTRIES ( ) ;
2013-11-23 17:30:10 +00:00
zend_execute_ex = phpdbg_execute_ex ;
2013-11-10 14:36:30 +00:00
2013-12-18 16:33:21 +00:00
REGISTER_STRINGL_CONSTANT ( " PHPDBG_VERSION " , PHPDBG_VERSION , sizeof ( PHPDBG_VERSION ) - 1 , CONST_CS | CONST_PERSISTENT ) ;
2014-09-09 00:15:33 +00:00
2014-08-25 17:24:55 +00:00
REGISTER_LONG_CONSTANT ( " PHPDBG_FILE " , FILE_PARAM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PHPDBG_METHOD " , METHOD_PARAM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PHPDBG_LINENO " , NUMERIC_PARAM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PHPDBG_FUNC " , STR_PARAM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PHPDBG_COLOR_PROMPT " , PHPDBG_COLOR_PROMPT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PHPDBG_COLOR_NOTICE " , PHPDBG_COLOR_NOTICE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PHPDBG_COLOR_ERROR " , PHPDBG_COLOR_ERROR , CONST_CS | CONST_PERSISTENT ) ;
2013-11-25 21:39:17 +00:00
2013-11-23 17:30:10 +00:00
return SUCCESS ;
2013-11-10 15:47:28 +00:00
} /* }}} */
2013-11-10 14:36:30 +00:00
2014-10-24 17:29:50 +00:00
static void php_phpdbg_destroy_bp_file ( zval * brake ) /* { { { */
2013-11-10 15:47:28 +00:00
{
2014-10-24 17:29:50 +00:00
zend_hash_destroy ( Z_ARRVAL_P ( brake ) ) ;
2015-07-24 15:17:09 +00:00
efree ( Z_ARRVAL_P ( brake ) ) ;
2013-11-10 15:47:28 +00:00
} /* }}} */
2013-11-10 10:44:42 +00:00
2014-10-24 17:29:50 +00:00
static void php_phpdbg_destroy_bp_symbol ( zval * brake ) /* { { { */
2013-11-10 21:38:58 +00:00
{
2014-10-24 17:29:50 +00:00
efree ( ( char * ) ( ( phpdbg_breaksymbol_t * ) Z_PTR_P ( brake ) ) - > symbol ) ;
2015-07-24 15:17:09 +00:00
efree ( Z_PTR_P ( brake ) ) ;
2013-11-10 21:38:58 +00:00
} /* }}} */
2014-10-24 17:29:50 +00:00
static void php_phpdbg_destroy_bp_opcode ( zval * brake ) /* { { { */
2013-11-24 11:43:05 +00:00
{
2014-10-24 17:29:50 +00:00
efree ( ( char * ) ( ( phpdbg_breakop_t * ) Z_PTR_P ( brake ) ) - > name ) ;
2015-07-24 15:17:09 +00:00
efree ( Z_PTR_P ( brake ) ) ;
2013-11-24 11:43:05 +00:00
} /* }}} */
2014-10-24 17:29:50 +00:00
static void php_phpdbg_destroy_bp_methods ( zval * brake ) /* { { { */
2013-11-12 00:27:48 +00:00
{
2014-10-24 17:29:50 +00:00
zend_hash_destroy ( Z_ARRVAL_P ( brake ) ) ;
2015-07-24 15:17:09 +00:00
efree ( Z_ARRVAL_P ( brake ) ) ;
2013-11-12 00:27:48 +00:00
} /* }}} */
2014-10-24 17:29:50 +00:00
static void php_phpdbg_destroy_bp_condition ( zval * data ) /* { { { */
2013-11-13 14:22:01 +00:00
{
2014-10-24 17:29:50 +00:00
phpdbg_breakcond_t * brake = ( phpdbg_breakcond_t * ) Z_PTR_P ( data ) ;
2013-11-23 17:30:10 +00:00
2015-07-24 15:17:09 +00:00
if ( brake - > ops ) {
destroy_op_array ( brake - > ops ) ;
efree ( brake - > ops ) ;
2013-11-23 17:30:10 +00:00
}
2015-07-24 15:17:09 +00:00
efree ( ( char * ) brake - > code ) ;
efree ( brake ) ;
2013-11-13 14:22:01 +00:00
} /* }}} */
2014-10-24 17:29:50 +00:00
static void php_phpdbg_destroy_registered ( zval * data ) /* { { { */
2013-11-19 01:18:43 +00:00
{
2014-10-24 17:29:50 +00:00
zend_function * function = ( zend_function * ) Z_PTR_P ( data ) ;
2014-12-13 22:06:14 +00:00
destroy_zend_function ( function ) ;
2013-11-26 22:20:52 +00:00
} /* }}} */
2013-11-19 01:18:43 +00:00
2014-02-27 19:10:59 +00:00
2013-11-18 17:51:14 +00:00
static PHP_RINIT_FUNCTION ( phpdbg ) /* { { { */
2013-11-20 13:28:41 +00:00
{
2014-10-26 19:43:49 +00:00
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 ) ;
2013-11-12 01:51:50 +00:00
zend_hash_init ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_SYM ] , 8 , NULL , php_phpdbg_destroy_bp_symbol , 0 ) ;
2013-11-28 20:36:45 +00:00
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 ) ;
2013-12-01 14:58:59 +00:00
zend_hash_init ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE_OPLINE ] , 8 , NULL , php_phpdbg_destroy_bp_methods , 0 ) ;
2013-11-23 17:30:10 +00:00
zend_hash_init ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_OPLINE ] , 8 , NULL , NULL , 0 ) ;
2013-11-24 11:43:05 +00:00
zend_hash_init ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_OPCODE ] , 8 , NULL , php_phpdbg_destroy_bp_opcode , 0 ) ;
2013-11-23 17:30:10 +00:00
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 ) ;
2013-11-26 22:20:52 +00:00
zend_hash_init ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_MAP ] , 8 , NULL , NULL , 0 ) ;
2013-12-13 22:57:36 +00:00
2013-11-18 03:18:37 +00:00
zend_hash_init ( & PHPDBG_G ( seek ) , 8 , NULL , NULL , 0 ) ;
2013-11-19 01:18:43 +00:00
zend_hash_init ( & PHPDBG_G ( registered ) , 8 , NULL , php_phpdbg_destroy_registered , 0 ) ;
2013-11-20 13:28:41 +00:00
2013-11-10 14:36:30 +00:00
return SUCCESS ;
2013-11-10 15:47:28 +00:00
} /* }}} */
2013-11-10 10:44:42 +00:00
2013-11-10 15:47:28 +00:00
static PHP_RSHUTDOWN_FUNCTION ( phpdbg ) /* { { { */
{
2013-11-23 17:30:10 +00:00
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE ] ) ;
2015-07-24 15:17:09 +00:00
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE_PENDING ] ) ;
2013-11-23 17:30:10 +00:00
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_SYM ] ) ;
2013-12-01 14:58:59 +00:00
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 ] ) ;
2013-11-23 17:30:10 +00:00
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_OPLINE ] ) ;
2013-11-23 23:14:16 +00:00
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_OPCODE ] ) ;
2013-11-23 17:30:10 +00:00
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_METHOD ] ) ;
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_COND ] ) ;
2013-11-26 22:20:52 +00:00
zend_hash_destroy ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_MAP ] ) ;
2013-11-18 03:18:37 +00:00
zend_hash_destroy ( & PHPDBG_G ( seek ) ) ;
2014-10-02 23:29:41 +00:00
zend_hash_destroy ( & PHPDBG_G ( file_sources ) ) ;
2014-10-26 19:43:49 +00:00
zend_hash_destroy ( & PHPDBG_G ( registered ) ) ;
2013-12-16 15:29:31 +00:00
zend_hash_destroy ( & PHPDBG_G ( watchpoints ) ) ;
2013-12-18 07:56:20 +00:00
zend_llist_destroy ( & PHPDBG_G ( watchlist_mem ) ) ;
2013-11-20 13:28:41 +00:00
2014-04-21 20:43:19 +00:00
if ( PHPDBG_G ( buffer ) ) {
efree ( PHPDBG_G ( buffer ) ) ;
PHPDBG_G ( buffer ) = NULL ;
}
2014-09-10 13:53:40 +00:00
2013-11-23 17:30:10 +00:00
if ( PHPDBG_G ( exec ) ) {
efree ( PHPDBG_G ( exec ) ) ;
PHPDBG_G ( exec ) = NULL ;
}
2013-11-14 21:39:59 +00:00
2013-11-23 17:30:10 +00:00
if ( PHPDBG_G ( oplog ) ) {
2015-06-22 10:56:29 +00:00
fclose ( PHPDBG_G ( oplog ) ) ;
2013-11-23 17:30:10 +00:00
PHPDBG_G ( oplog ) = NULL ;
}
2013-11-10 14:36:30 +00:00
2013-11-23 17:30:10 +00:00
if ( PHPDBG_G ( ops ) ) {
2014-12-13 22:06:14 +00:00
destroy_op_array ( PHPDBG_G ( ops ) ) ;
2013-11-23 17:30:10 +00:00
efree ( PHPDBG_G ( ops ) ) ;
PHPDBG_G ( ops ) = NULL ;
}
2013-11-14 21:39:59 +00:00
2015-06-22 10:56:29 +00:00
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 ;
}
2013-11-23 17:30:10 +00:00
return SUCCESS ;
2013-11-10 15:47:28 +00:00
} /* }}} */
2013-11-09 22:35:03 +00:00
2013-12-15 13:55:03 +00:00
/* {{{ proto mixed phpdbg_exec(string context)
2013-12-06 20:56:16 +00:00
Attempt to set the execution context for phpdbg
If the execution context was set previously it is returned
2013-12-15 13:55:03 +00:00
If the execution context was not set previously boolean true is returned
2013-12-06 20:56:16 +00:00
If the request to set the context fails , boolean false is returned , and an E_WARNING raised */
2013-12-15 13:55:03 +00:00
static PHP_FUNCTION ( phpdbg_exec )
2013-12-06 20:56:16 +00:00
{
2014-10-24 17:29:50 +00:00
zend_string * exec ;
2014-09-21 02:17:19 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " S " , & exec ) = = FAILURE ) {
2013-12-06 20:56:16 +00:00
return ;
}
2013-12-15 13:55:03 +00:00
2013-12-06 20:56:16 +00:00
{
2015-03-19 12:21:48 +00:00
zend_stat_t sb ;
2013-12-06 20:56:16 +00:00
zend_bool result = 1 ;
2013-12-15 13:55:03 +00:00
2015-06-30 10:59:27 +00:00
if ( VCWD_STAT ( ZSTR_VAL ( exec ) , & sb ) ! = FAILURE ) {
2013-12-06 20:56:16 +00:00
if ( sb . st_mode & ( S_IFREG | S_IFLNK ) ) {
if ( PHPDBG_G ( exec ) ) {
2014-10-24 17:29:50 +00:00
ZVAL_STRINGL ( return_value , PHPDBG_G ( exec ) , PHPDBG_G ( exec_len ) ) ;
2013-12-06 20:56:16 +00:00
efree ( PHPDBG_G ( exec ) ) ;
result = 0 ;
}
2013-12-15 13:55:03 +00:00
2015-06-30 10:59:27 +00:00
PHPDBG_G ( exec ) = estrndup ( ZSTR_VAL ( exec ) , ZSTR_LEN ( exec ) ) ;
PHPDBG_G ( exec_len ) = ZSTR_LEN ( exec ) ;
2013-12-15 13:55:03 +00:00
2014-10-24 17:29:50 +00:00
if ( result ) {
2014-12-22 05:10:46 +00:00
ZVAL_TRUE ( return_value ) ;
2014-10-24 17:29:50 +00:00
}
2013-12-06 20:56:16 +00:00
} else {
2014-10-24 17:29:50 +00:00
zend_error ( E_WARNING , " Failed to set execution context (%s), not a regular file or symlink " , exec ) ;
2014-12-22 05:10:46 +00:00
ZVAL_FALSE ( return_value ) ;
2013-12-06 20:56:16 +00:00
}
} else {
2014-10-24 17:29:50 +00:00
zend_error ( E_WARNING , " Failed to set execution context (%s) the file does not exist " , exec ) ;
2013-12-06 20:56:16 +00:00
2014-12-22 05:10:46 +00:00
ZVAL_FALSE ( return_value ) ;
2013-12-06 20:56:16 +00:00
}
}
} /* }}} */
2014-10-26 07:02:15 +00:00
/* {{{ proto void phpdbg_break()
2013-11-12 13:07:35 +00:00
instructs phpdbg to insert a breakpoint at the next opcode */
2014-10-26 07:02:15 +00:00
static PHP_FUNCTION ( phpdbg_break_next )
2013-11-11 14:33:53 +00:00
{
2014-10-26 23:34:56 +00:00
if ( zend_parse_parameters_none ( ) = = FAILURE & & EG ( current_execute_data ) ) {
2014-10-26 07:24:35 +00:00
return ;
2013-11-23 17:30:10 +00:00
}
2015-01-03 09:22:58 +00:00
2014-12-13 22:06:14 +00:00
phpdbg_set_breakpoint_opline_ex ( ( phpdbg_opline_ptr_t ) EG ( current_execute_data ) - > opline + 1 ) ;
2014-10-26 07:02:15 +00:00
} /* }}} */
2013-11-23 17:30:10 +00:00
2014-10-26 07:02:15 +00:00
/* {{{ proto void phpdbg_break_file(string file, integer line) */
static PHP_FUNCTION ( phpdbg_break_file )
{
char * file = NULL ;
2014-10-26 23:34:56 +00:00
size_t flen = 0 ;
long line ;
2015-01-03 09:22:58 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " sl " , & file , & flen , & line ) = = FAILURE ) {
2014-10-26 07:02:15 +00:00
return ;
}
2013-11-17 12:40:51 +00:00
2014-12-13 22:06:14 +00:00
phpdbg_set_breakpoint_file ( file , line ) ;
2014-10-26 07:02:15 +00:00
} /* }}} */
/* {{{ proto void phpdbg_break_method(string class, string method) */
static PHP_FUNCTION ( phpdbg_break_method )
{
2014-10-26 23:34:56 +00:00
char * class = NULL , * method = NULL ;
size_t clen = 0 , mlen = 0 ;
2015-01-03 09:22:58 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " ss " , & class , & clen , & method , & mlen ) = = FAILURE ) {
2014-10-26 07:02:15 +00:00
return ;
2013-11-23 17:30:10 +00:00
}
2014-10-26 07:02:15 +00:00
2014-12-13 22:06:14 +00:00
phpdbg_set_breakpoint_method ( class , method ) ;
2014-10-26 07:02:15 +00:00
} /* }}} */
/* {{{ proto void phpdbg_break_function(string function) */
static PHP_FUNCTION ( phpdbg_break_function )
{
char * function = NULL ;
size_t function_len ;
2015-01-03 09:22:58 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & function , & function_len ) = = FAILURE ) {
2014-10-26 07:02:15 +00:00
return ;
}
2014-12-13 22:06:14 +00:00
phpdbg_set_breakpoint_symbol ( function , function_len ) ;
2013-11-11 14:33:53 +00:00
} /* }}} */
2013-11-11 15:14:37 +00:00
/* {{{ proto void phpdbg_clear(void)
2013-11-23 17:30:10 +00:00
instructs phpdbg to clear breakpoints */
2013-11-11 15:14:37 +00:00
static PHP_FUNCTION ( phpdbg_clear )
{
2013-11-23 17:30:10 +00:00
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE ] ) ;
2014-10-26 19:43:49 +00:00
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE_PENDING ] ) ;
2013-11-23 17:30:10 +00:00
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_SYM ] ) ;
2013-12-01 14:58:59 +00:00
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FUNCTION_OPLINE ] ) ;
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_METHOD_OPLINE ] ) ;
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE_OPLINE ] ) ;
2013-11-23 17:30:10 +00:00
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_OPLINE ] ) ;
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_METHOD ] ) ;
zend_hash_clean ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_COND ] ) ;
2013-11-11 15:14:37 +00:00
} /* }}} */
2013-11-24 20:00:56 +00:00
/* {{{ proto void phpdbg_color(integer element, string color) */
static PHP_FUNCTION ( phpdbg_color )
{
2014-02-18 08:47:15 +00:00
long element = 0L ;
char * color = NULL ;
2014-08-27 13:31:48 +00:00
size_t color_len = 0 ;
2013-11-25 21:39:17 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " ls " , & element , & color , & color_len ) = = FAILURE ) {
2013-11-24 20:00:56 +00:00
return ;
}
2013-11-25 21:39:17 +00:00
2013-11-24 20:00:56 +00:00
switch ( element ) {
case PHPDBG_COLOR_NOTICE :
case PHPDBG_COLOR_ERROR :
case PHPDBG_COLOR_PROMPT :
2014-12-13 22:06:14 +00:00
phpdbg_set_color_ex ( element , color , color_len ) ;
2013-11-24 20:00:56 +00:00
break ;
2013-11-25 21:39:17 +00:00
2013-11-24 20:00:56 +00:00
default : zend_error ( E_ERROR , " phpdbg detected an incorrect color constant " ) ;
}
} /* }}} */
/* {{{ proto void phpdbg_prompt(string prompt) */
2013-11-25 21:39:17 +00:00
static PHP_FUNCTION ( phpdbg_prompt )
2013-11-24 20:00:56 +00:00
{
2014-02-18 08:47:15 +00:00
char * prompt = NULL ;
2014-08-27 13:31:48 +00:00
size_t prompt_len = 0 ;
2013-11-25 21:39:17 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & prompt , & prompt_len ) = = FAILURE ) {
2013-11-24 20:00:56 +00:00
return ;
}
2013-11-25 21:39:17 +00:00
2014-12-13 22:06:14 +00:00
phpdbg_set_prompt ( prompt ) ;
2013-11-24 20:00:56 +00:00
} /* }}} */
2015-06-22 10:56:29 +00:00
/* {{{ proto void phpdbg_start_oplog() */
static PHP_FUNCTION ( phpdbg_start_oplog )
{
phpdbg_oplog_list * prev ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
prev = PHPDBG_G ( oplog_list ) ;
if ( ! prev ) {
PHPDBG_G ( oplog_arena ) = zend_arena_create ( 64 * 1024 ) ;
PHPDBG_G ( oplog_cur ) = ( ( phpdbg_oplog_entry * ) zend_arena_alloc ( & PHPDBG_G ( oplog_arena ) , sizeof ( phpdbg_oplog_entry ) ) ) + 1 ;
PHPDBG_G ( oplog_cur ) - > next = NULL ;
}
PHPDBG_G ( oplog_list ) = emalloc ( sizeof ( phpdbg_oplog_list ) ) ;
PHPDBG_G ( oplog_list ) - > prev = prev ;
PHPDBG_G ( oplog_list ) - > start = PHPDBG_G ( oplog_cur ) ;
}
2015-07-20 18:41:07 +00:00
static void phpdbg_oplog_fill_executable ( zend_op_array * op_array , HashTable * insert_ht , zend_bool by_opcode ) {
/* ignore RECV_* opcodes */
zend_op * cur = op_array - > opcodes + op_array - > num_args + ! ! ( op_array - > fn_flags & ZEND_ACC_VARIADIC ) ;
zend_op * end = op_array - > opcodes + op_array - > last ;
zend_long insert_idx ;
zval zero ;
ZVAL_LONG ( & zero , 0 ) ;
/* ignore autogenerated return (well, not too precise with finally branches, but that's okay) */
if ( op_array - > last > 1 & & ( end - 1 ) - > opcode = = ZEND_RETURN & & ( ( end - 2 ) - > opcode = = ZEND_RETURN | | ( end - 2 ) - > opcode = = ZEND_GENERATOR_RETURN | | ( end - 2 ) - > opcode = = ZEND_THROW ) ) {
end - - ;
}
for ( ; cur < end ; cur + + ) {
if ( cur - > opcode = = ZEND_NOP | | cur - > opcode = = ZEND_OP_DATA | | cur - > opcode = = ZEND_FE_FREE | | cur - > opcode = = ZEND_FREE | | cur - > opcode = = ZEND_ASSERT_CHECK
| | cur - > opcode = = ZEND_DECLARE_CONST | | cur - > opcode = = ZEND_DECLARE_CLASS | | cur - > opcode = = ZEND_DECLARE_INHERITED_CLASS | | cur - > opcode = = ZEND_DECLARE_FUNCTION
| | cur - > opcode = = ZEND_DECLARE_INHERITED_CLASS_DELAYED | | cur - > opcode = = ZEND_VERIFY_ABSTRACT_CLASS | | cur - > opcode = = ZEND_ADD_TRAIT | | cur - > opcode = = ZEND_BIND_TRAITS
| | cur - > opcode = = ZEND_DECLARE_ANON_CLASS | | cur - > opcode = = ZEND_DECLARE_ANON_INHERITED_CLASS | | cur - > opcode = = ZEND_FAST_RET | | cur - > opcode = = ZEND_TICKS
| | cur - > opcode = = ZEND_EXT_STMT | | cur - > opcode = = ZEND_EXT_FCALL_BEGIN | | cur - > opcode = = ZEND_EXT_FCALL_END | | cur - > opcode = = ZEND_EXT_NOP | | cur - > opcode = = ZEND_BIND_GLOBAL ) {
continue ;
}
if ( by_opcode ) {
insert_idx = cur - op_array - > opcodes ;
} else {
insert_idx = cur - > lineno ;
}
if ( cur - > opcode = = ZEND_NEW & & ( cur + 1 ) - > opcode = = ZEND_DO_FCALL ) {
cur + + ;
}
zend_hash_index_update ( insert_ht , insert_idx , & zero ) ;
}
}
2015-07-22 16:11:35 +00:00
static inline HashTable * phpdbg_add_empty_array ( HashTable * ht , zend_string * name ) {
zval * ht_zv = zend_hash_find ( ht , name ) ;
if ( ! ht_zv ) {
zval zv ;
array_init ( & zv ) ;
ht_zv = zend_hash_add_new ( ht , name , & zv ) ;
}
return Z_ARR_P ( ht_zv ) ;
}
/* {{{ proto void phpdbg_end_oplog() */
static PHP_FUNCTION ( phpdbg_get_executable )
{
HashTable * options = NULL ;
zval * option_buffer ;
zend_bool by_function = 0 ;
zend_bool by_opcode = 0 ;
HashTable * insert_ht ;
zend_function * func ;
zend_class_entry * ce ;
zend_string * name ;
HashTable * files = & PHPDBG_G ( file_sources ) ;
HashTable files_tmp ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |H " , & options ) = = FAILURE ) {
return ;
}
if ( options & & ( option_buffer = zend_hash_str_find ( options , ZEND_STRL ( " functions " ) ) ) ) {
by_function = zend_is_true ( option_buffer ) ;
}
if ( options & & ( option_buffer = zend_hash_str_find ( options , ZEND_STRL ( " opcodes " ) ) ) ) {
if ( by_function ) {
by_opcode = zend_is_true ( option_buffer ) ;
}
}
if ( options & & ( option_buffer = zend_hash_str_find ( options , ZEND_STRL ( " files " ) ) ) ) {
ZVAL_DEREF ( option_buffer ) ;
if ( Z_TYPE_P ( option_buffer ) = = IS_ARRAY & & zend_hash_num_elements ( Z_ARR_P ( option_buffer ) ) > 0 ) {
zval * filename ;
files = & files_tmp ;
zend_hash_init ( files , 0 , NULL , NULL , 0 ) ;
ZEND_HASH_FOREACH_VAL ( Z_ARR_P ( option_buffer ) , filename ) {
zend_hash_add_empty_element ( files , zval_get_string ( filename ) ) ;
} ZEND_HASH_FOREACH_END ( ) ;
} else {
GC_REFCOUNT ( files ) + + ;
}
} else {
GC_REFCOUNT ( files ) + + ;
}
array_init ( return_value ) ;
ZEND_HASH_FOREACH_STR_KEY_PTR ( EG ( function_table ) , name , func ) {
if ( func - > type = = ZEND_USER_FUNCTION ) {
if ( zend_hash_exists ( files , func - > op_array . filename ) ) {
insert_ht = phpdbg_add_empty_array ( Z_ARR_P ( return_value ) , func - > op_array . filename ) ;
if ( by_function ) {
insert_ht = phpdbg_add_empty_array ( insert_ht , name ) ;
}
phpdbg_oplog_fill_executable ( & func - > op_array , insert_ht , by_opcode ) ;
}
}
} ZEND_HASH_FOREACH_END ( ) ;
ZEND_HASH_FOREACH_STR_KEY_PTR ( EG ( class_table ) , name , ce ) {
if ( ce - > type = = ZEND_USER_CLASS ) {
if ( zend_hash_exists ( files , ce - > info . user . filename ) ) {
ZEND_HASH_FOREACH_PTR ( & ce - > function_table , func ) {
if ( func - > type = = ZEND_USER_FUNCTION ) {
insert_ht = phpdbg_add_empty_array ( Z_ARR_P ( return_value ) , func - > op_array . filename ) ;
if ( by_function ) {
zend_string * fn_name = strpprintf ( ZSTR_LEN ( name ) + ZSTR_LEN ( func - > op_array . function_name ) + 2 , " %.*s::%.*s " , ZSTR_LEN ( name ) , ZSTR_VAL ( name ) , ZSTR_LEN ( func - > op_array . function_name ) , ZSTR_VAL ( func - > op_array . function_name ) ) ;
insert_ht = phpdbg_add_empty_array ( insert_ht , fn_name ) ;
zend_string_release ( fn_name ) ;
}
phpdbg_oplog_fill_executable ( & func - > op_array , insert_ht , by_opcode ) ;
}
} ZEND_HASH_FOREACH_END ( ) ;
}
}
} ZEND_HASH_FOREACH_END ( ) ;
ZEND_HASH_FOREACH_STR_KEY ( files , name ) {
phpdbg_file_source * source = zend_hash_find_ptr ( & PHPDBG_G ( file_sources ) , name ) ;
if ( source ) {
phpdbg_oplog_fill_executable (
source - > op_array ,
phpdbg_add_empty_array ( Z_ARR_P ( return_value ) , source - > op_array - > filename ) ,
by_opcode ) ;
}
} ZEND_HASH_FOREACH_END ( ) ;
if ( ! - - GC_REFCOUNT ( files ) ) {
zend_hash_destroy ( files ) ;
}
}
2015-06-22 10:56:29 +00:00
/* {{{ proto void phpdbg_end_oplog() */
static PHP_FUNCTION ( phpdbg_end_oplog )
{
2015-07-20 18:41:07 +00:00
phpdbg_oplog_entry * cur ;
phpdbg_oplog_list * prev ;
2015-06-22 10:56:29 +00:00
2015-07-13 23:55:32 +00:00
HashTable * options = NULL ;
2015-06-22 10:56:29 +00:00
zval * option_buffer ;
zend_bool by_function = 0 ;
zend_bool by_opcode = 0 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |H " , & options ) = = FAILURE ) {
return ;
}
if ( ! PHPDBG_G ( oplog_list ) ) {
zend_error ( E_WARNING , " Can not end an oplog without starting it " ) ;
return ;
}
2015-07-20 18:41:07 +00:00
cur = PHPDBG_G ( oplog_list ) - > start ;
prev = PHPDBG_G ( oplog_list ) - > prev ;
2015-06-22 10:56:29 +00:00
efree ( PHPDBG_G ( oplog_list ) ) ;
PHPDBG_G ( oplog_list ) = prev ;
if ( options & & ( option_buffer = zend_hash_str_find ( options , ZEND_STRL ( " functions " ) ) ) ) {
by_function = zend_is_true ( option_buffer ) ;
}
if ( options & & ( option_buffer = zend_hash_str_find ( options , ZEND_STRL ( " opcodes " ) ) ) ) {
if ( by_function ) {
by_opcode = zend_is_true ( option_buffer ) ;
}
}
array_init ( return_value ) ;
{
zend_string * last_file = NULL ;
2015-07-22 16:11:35 +00:00
HashTable * file_ht ;
2015-06-22 10:56:29 +00:00
zend_string * last_function = ( void * ) ~ ( uintptr_t ) 0 ;
zend_class_entry * last_scope = NULL ;
HashTable * insert_ht ;
zend_long insert_idx ;
do {
zend_op_array * op_array = cur - > op_array ;
2015-07-20 18:41:07 +00:00
zval zero ;
ZVAL_LONG ( & zero , 0 ) ;
2015-06-22 10:56:29 +00:00
if ( op_array - > filename ! = last_file ) {
last_file = op_array - > filename ;
2015-07-22 16:11:35 +00:00
file_ht = insert_ht = phpdbg_add_empty_array ( Z_ARR_P ( return_value ) , last_file ) ;
2015-06-22 10:56:29 +00:00
}
if ( by_function ) {
2015-07-20 18:41:07 +00:00
if ( op_array - > function_name = = NULL ) {
if ( last_function ! = NULL ) {
2015-07-22 16:11:35 +00:00
insert_ht = file_ht ;
2015-07-20 18:41:07 +00:00
}
last_function = NULL ;
} else if ( op_array - > function_name ! = last_function | | op_array - > scope ! = last_scope ) {
2015-06-22 10:56:29 +00:00
zend_string * fn_name ;
last_function = op_array - > function_name ;
last_scope = op_array - > scope ;
if ( last_scope = = NULL ) {
2015-07-20 19:57:00 +00:00
fn_name = zend_string_copy ( last_function ) ;
2015-06-22 10:56:29 +00:00
} else {
2015-07-20 18:41:07 +00:00
fn_name = strpprintf ( ZSTR_LEN ( last_function ) + ZSTR_LEN ( last_scope - > name ) + 2 , " %.*s::%.*s " , ZSTR_LEN ( last_scope - > name ) , ZSTR_VAL ( last_scope - > name ) , ZSTR_LEN ( last_function ) , ZSTR_VAL ( last_function ) ) ;
2015-06-22 10:56:29 +00:00
}
2015-07-22 16:11:35 +00:00
insert_ht = phpdbg_add_empty_array ( Z_ARR_P ( return_value ) , fn_name ) ;
zend_string_release ( fn_name ) ;
2015-06-22 10:56:29 +00:00
}
}
if ( by_opcode ) {
insert_idx = cur - > op - op_array - > opcodes ;
} else {
insert_idx = cur - > op - > lineno ;
}
{
zval * num = zend_hash_index_find ( insert_ht , insert_idx ) ;
if ( ! num ) {
2015-07-20 18:41:07 +00:00
num = zend_hash_index_add_new ( insert_ht , insert_idx , & zero ) ;
2015-06-22 10:56:29 +00:00
}
Z_LVAL_P ( num ) + + ;
}
cur = cur - > next ;
} while ( cur ! = NULL ) ;
}
if ( ! prev ) {
zend_arena_destroy ( PHPDBG_G ( oplog_arena ) ) ;
}
}
2014-10-26 07:02:15 +00:00
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_break_next_arginfo , 0 , 0 , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_break_file_arginfo , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , file )
ZEND_ARG_INFO ( 0 , line )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_break_method_arginfo , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , class )
ZEND_ARG_INFO ( 0 , method )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_break_function_arginfo , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , function )
2013-11-15 16:22:20 +00:00
ZEND_END_ARG_INFO ( )
2013-11-24 20:00:56 +00:00
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_color_arginfo , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , element )
ZEND_ARG_INFO ( 0 , color )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_prompt_arginfo , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , string )
ZEND_END_ARG_INFO ( )
2013-12-06 20:56:16 +00:00
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_exec_arginfo , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , context )
ZEND_END_ARG_INFO ( )
2013-11-24 20:00:56 +00:00
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_clear_arginfo , 0 , 0 , 0 )
2013-11-15 16:22:20 +00:00
ZEND_END_ARG_INFO ( )
2015-06-22 10:56:29 +00:00
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_start_oplog_arginfo , 0 , 0 , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_end_oplog_arginfo , 0 , 0 , 0 )
2015-07-22 16:11:35 +00:00
ZEND_ARG_INFO ( 0 , options )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( phpdbg_get_executable_arginfo , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , options )
2015-06-22 10:56:29 +00:00
ZEND_END_ARG_INFO ( )
2013-11-24 20:00:56 +00:00
zend_function_entry phpdbg_user_functions [ ] = {
PHP_FE ( phpdbg_clear , phpdbg_clear_arginfo )
2014-10-26 07:02:15 +00:00
PHP_FE ( phpdbg_break_next , phpdbg_break_next_arginfo )
PHP_FE ( phpdbg_break_file , phpdbg_break_file_arginfo )
PHP_FE ( phpdbg_break_method , phpdbg_break_method_arginfo )
PHP_FE ( phpdbg_break_function , phpdbg_break_function_arginfo )
2013-12-06 20:56:16 +00:00
PHP_FE ( phpdbg_exec , phpdbg_exec_arginfo )
2013-11-24 20:00:56 +00:00
PHP_FE ( phpdbg_color , phpdbg_color_arginfo )
PHP_FE ( phpdbg_prompt , phpdbg_prompt_arginfo )
2015-06-22 10:56:29 +00:00
PHP_FE ( phpdbg_start_oplog , phpdbg_start_oplog_arginfo )
PHP_FE ( phpdbg_end_oplog , phpdbg_end_oplog_arginfo )
2015-07-22 16:11:35 +00:00
PHP_FE ( phpdbg_get_executable , phpdbg_get_executable_arginfo )
2013-11-11 14:33:53 +00:00
# ifdef PHP_FE_END
PHP_FE_END
# else
{ NULL , NULL , NULL }
# endif
} ;
2013-11-09 22:47:39 +00:00
static zend_module_entry sapi_phpdbg_module_entry = {
2013-11-09 22:35:03 +00:00
STANDARD_MODULE_HEADER ,
2013-11-28 20:36:45 +00:00
PHPDBG_NAME ,
2013-11-11 14:33:53 +00:00
phpdbg_user_functions ,
2013-11-10 10:44:42 +00:00
PHP_MINIT ( phpdbg ) ,
2013-11-09 22:35:03 +00:00
NULL ,
2013-11-10 10:44:42 +00:00
PHP_RINIT ( phpdbg ) ,
PHP_RSHUTDOWN ( phpdbg ) ,
2013-11-09 22:35:03 +00:00
NULL ,
2013-11-28 20:36:45 +00:00
PHPDBG_VERSION ,
2013-11-09 22:35:03 +00:00
STANDARD_MODULE_PROPERTIES
} ;
2013-11-09 23:07:04 +00:00
static inline int php_sapi_phpdbg_module_startup ( sapi_module_struct * module ) /* { { { */
{
2013-11-23 17:30:10 +00:00
if ( php_module_startup ( module , & sapi_phpdbg_module_entry , 1 ) = = FAILURE ) {
2013-11-09 22:35:03 +00:00
return FAILURE ;
}
2013-12-15 13:55:03 +00:00
2013-12-05 11:20:16 +00:00
phpdbg_booted = 1 ;
2013-12-15 13:55:03 +00:00
2013-11-09 22:35:03 +00:00
return SUCCESS ;
} /* }}} */
2014-12-13 22:06:14 +00:00
static char * php_sapi_phpdbg_read_cookies ( void ) /* { { { */
2013-11-12 21:40:15 +00:00
{
2013-11-23 17:30:10 +00:00
return NULL ;
2013-11-10 22:44:28 +00:00
} /* }}} */
2014-12-13 22:06:14 +00:00
static int php_sapi_phpdbg_header_handler ( sapi_header_struct * h , sapi_header_op_enum op , sapi_headers_struct * s ) /* { { { */
2013-11-10 22:44:28 +00:00
{
return 0 ;
}
/* }}} */
2014-12-13 22:06:14 +00:00
static int php_sapi_phpdbg_send_headers ( sapi_headers_struct * sapi_headers ) /* { { { */
2013-11-10 22:44:28 +00:00
{
/* We do nothing here, this function is needed to prevent that the fallback
* header handling is called . */
return SAPI_HEADER_SENT_SUCCESSFULLY ;
}
/* }}} */
2014-12-13 22:06:14 +00:00
static void php_sapi_phpdbg_send_header ( sapi_header_struct * sapi_header , void * server_context ) /* { { { */
2013-11-10 22:44:28 +00:00
{
}
/* }}} */
2014-12-13 22:06:14 +00:00
static void php_sapi_phpdbg_log_message ( char * message ) /* { { { */
2013-11-10 22:44:28 +00:00
{
2013-12-05 11:20:16 +00:00
/*
* We must not request TSRM before being boot
*/
if ( phpdbg_booted ) {
2014-10-24 12:16:49 +00:00
if ( PHPDBG_G ( flags ) & PHPDBG_IN_EVAL ) {
phpdbg_error ( " eval " , " msg= \" %s \" " , " %s " , message ) ;
return ;
}
2014-09-21 02:17:19 +00:00
phpdbg_error ( " php " , " msg= \" %s \" " , " %s " , message ) ;
2013-12-21 21:42:11 +00:00
switch ( PG ( last_error_type ) ) {
case E_ERROR :
case E_CORE_ERROR :
case E_COMPILE_ERROR :
case E_USER_ERROR :
case E_PARSE :
2014-10-25 17:09:19 +00:00
case E_RECOVERABLE_ERROR : {
2014-12-13 22:06:14 +00:00
const char * file_char = zend_get_executed_filename ( ) ;
2015-01-03 09:22:58 +00:00
zend_string * file = zend_string_init ( file_char , strlen ( file_char ) , 0 ) ;
2014-12-13 22:06:14 +00:00
phpdbg_list_file ( file , 3 , zend_get_executed_lineno ( ) - 1 , zend_get_executed_lineno ( ) ) ;
2014-10-25 17:09:19 +00:00
efree ( file ) ;
2013-12-21 21:42:11 +00:00
2015-02-13 09:45:43 +00:00
if ( ! phpdbg_fully_started ) {
return ;
}
2013-12-21 21:42:11 +00:00
do {
2014-12-13 22:06:14 +00:00
switch ( phpdbg_interactive ( 1 ) ) {
2013-12-21 21:42:11 +00:00
case PHPDBG_LEAVE :
case PHPDBG_FINISH :
case PHPDBG_UNTIL :
case PHPDBG_NEXT :
return ;
}
2014-10-26 02:50:28 +00:00
} while ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_STOPPING ) ) ;
2014-10-25 17:09:19 +00:00
}
2013-12-21 21:42:11 +00:00
}
2014-10-26 23:34:56 +00:00
} else {
fprintf ( stdout , " %s \n " , message ) ;
}
2013-11-10 22:44:28 +00:00
}
/* }}} */
2014-12-13 22:06:14 +00:00
static int php_sapi_phpdbg_deactivate ( void ) /* { { { */
2013-11-10 22:44:28 +00:00
{
fflush ( stdout ) ;
2015-07-24 15:17:09 +00:00
if ( SG ( request_info ) . argv0 ) {
2013-11-10 22:44:28 +00:00
free ( SG ( request_info ) . argv0 ) ;
SG ( request_info ) . argv0 = NULL ;
}
2014-10-26 19:43:49 +00:00
2013-11-10 22:44:28 +00:00
return SUCCESS ;
}
/* }}} */
2014-12-13 22:06:14 +00:00
static void php_sapi_phpdbg_register_vars ( zval * track_vars_array ) /* { { { */
2013-11-10 23:30:52 +00:00
{
2014-10-24 17:29:50 +00:00
size_t len ;
char * docroot = " " ;
2013-11-10 23:30:52 +00:00
/* In phpdbg mode, we consider the environment to be a part of the server variables
2013-11-23 17:30:10 +00:00
*/
2014-12-13 22:06:14 +00:00
php_import_environment_variables ( track_vars_array ) ;
2013-11-23 17:30:10 +00:00
if ( PHPDBG_G ( exec ) ) {
len = PHPDBG_G ( exec_len ) ;
2014-12-13 22:06:14 +00:00
if ( sapi_module . input_filter ( PARSE_SERVER , " PHP_SELF " , & PHPDBG_G ( exec ) , PHPDBG_G ( exec_len ) , & len ) ) {
php_register_variable ( " PHP_SELF " , PHPDBG_G ( exec ) , track_vars_array ) ;
2013-11-23 17:30:10 +00:00
}
2014-12-13 22:06:14 +00:00
if ( sapi_module . input_filter ( PARSE_SERVER , " SCRIPT_NAME " , & PHPDBG_G ( exec ) , PHPDBG_G ( exec_len ) , & len ) ) {
php_register_variable ( " SCRIPT_NAME " , PHPDBG_G ( exec ) , track_vars_array ) ;
2013-11-23 17:30:10 +00:00
}
2014-12-13 22:06:14 +00:00
if ( sapi_module . input_filter ( PARSE_SERVER , " SCRIPT_FILENAME " , & PHPDBG_G ( exec ) , PHPDBG_G ( exec_len ) , & len ) ) {
php_register_variable ( " SCRIPT_FILENAME " , PHPDBG_G ( exec ) , track_vars_array ) ;
2013-11-23 17:30:10 +00:00
}
2014-12-13 22:06:14 +00:00
if ( sapi_module . input_filter ( PARSE_SERVER , " PATH_TRANSLATED " , & PHPDBG_G ( exec ) , PHPDBG_G ( exec_len ) , & len ) ) {
php_register_variable ( " PATH_TRANSLATED " , PHPDBG_G ( exec ) , track_vars_array ) ;
2013-11-23 17:30:10 +00:00
}
}
2014-10-24 17:29:50 +00:00
/* any old docroot will do */
len = 0 ;
2014-12-13 22:06:14 +00:00
if ( sapi_module . input_filter ( PARSE_SERVER , " DOCUMENT_ROOT " , & docroot , len , & len ) ) {
php_register_variable ( " DOCUMENT_ROOT " , docroot , track_vars_array ) ;
2013-11-23 17:30:10 +00:00
}
2013-11-10 23:30:52 +00:00
}
/* }}} */
2014-12-13 22:06:14 +00:00
static inline size_t php_sapi_phpdbg_ub_write ( const char * message , size_t length ) /* { { { */
2013-11-20 14:19:15 +00:00
{
2014-10-04 21:21:34 +00:00
if ( PHPDBG_G ( socket_fd ) ! = - 1 & & ! ( PHPDBG_G ( flags ) & PHPDBG_IS_INTERACTIVE ) ) {
send ( PHPDBG_G ( socket_fd ) , message , length , 0 ) ;
}
2014-09-21 02:17:19 +00:00
return phpdbg_script ( P_STDOUT , " %.*s " , length , message ) ;
2013-11-20 14:19:15 +00:00
} /* }}} */
2014-09-21 02:17:19 +00:00
/* beginning of struct, see main/streams/plain_wrapper.c line 111 */
typedef struct {
FILE * file ;
int fd ;
} php_stdio_stream_data ;
2014-12-13 22:06:14 +00:00
static size_t phpdbg_stdiop_write ( php_stream * stream , const char * buf , size_t count ) {
2014-09-21 02:17:19 +00:00
php_stdio_stream_data * data = ( php_stdio_stream_data * ) stream - > abstract ;
while ( data - > fd > = 0 ) {
struct stat stat [ 3 ] ;
memset ( stat , 0 , sizeof ( stat ) ) ;
2014-09-23 16:29:36 +00:00
if ( ( ( fstat ( fileno ( stderr ) , & stat [ 2 ] ) < 0 ) & ( fstat ( fileno ( stdout ) , & stat [ 0 ] ) < 0 ) ) | ( fstat ( data - > fd , & stat [ 1 ] ) < 0 ) ) {
2014-09-21 02:17:19 +00:00
break ;
}
if ( stat [ 0 ] . st_dev = = stat [ 1 ] . st_dev & & stat [ 0 ] . st_ino = = stat [ 1 ] . st_ino ) {
2014-09-21 22:52:22 +00:00
phpdbg_script ( P_STDOUT , " %.*s " , ( int ) count , buf ) ;
2014-09-21 02:17:19 +00:00
return count ;
}
if ( stat [ 2 ] . st_dev = = stat [ 1 ] . st_dev & & stat [ 2 ] . st_ino = = stat [ 1 ] . st_ino ) {
2014-09-21 22:52:22 +00:00
phpdbg_script ( P_STDERR , " %.*s " , ( int ) count , buf ) ;
2014-09-21 02:17:19 +00:00
return count ;
}
break ;
}
2014-12-13 22:06:14 +00:00
return PHPDBG_G ( php_stdiop_write ) ( stream , buf , count ) ;
2014-09-21 02:17:19 +00:00
}
2014-12-13 22:06:14 +00:00
static inline void php_sapi_phpdbg_flush ( void * context ) /* { { { */
2013-12-18 10:31:14 +00:00
{
2014-12-13 22:06:14 +00:00
if ( ! phpdbg_active_sigsafe_mem ( ) ) {
2014-09-28 00:57:12 +00:00
fflush ( PHPDBG_G ( io ) [ PHPDBG_STDOUT ] . ptr ) ;
}
2013-11-20 14:19:15 +00:00
} /* }}} */
2014-05-01 09:38:08 +00:00
/* copied from sapi/cli/php_cli.c cli_register_file_handles */
2014-12-13 22:06:14 +00:00
static void phpdbg_register_file_handles ( void ) /* { { { */
2014-05-01 09:38:08 +00:00
{
2014-10-24 17:29:50 +00:00
zval zin , zout , zerr ;
2014-05-01 09:38:08 +00:00
php_stream * s_in , * s_out , * s_err ;
php_stream_context * sc_in = NULL , * sc_out = NULL , * sc_err = NULL ;
zend_constant ic , oc , ec ;
s_in = php_stream_open_wrapper_ex ( " php://stdin " , " rb " , 0 , NULL , sc_in ) ;
s_out = php_stream_open_wrapper_ex ( " php://stdout " , " wb " , 0 , NULL , sc_out ) ;
s_err = php_stream_open_wrapper_ex ( " php://stderr " , " wb " , 0 , NULL , sc_err ) ;
if ( s_in = = NULL | | s_out = = NULL | | s_err = = NULL ) {
if ( s_in ) php_stream_close ( s_in ) ;
if ( s_out ) php_stream_close ( s_out ) ;
if ( s_err ) php_stream_close ( s_err ) ;
return ;
}
# if PHP_DEBUG
/* do not close stdout and stderr */
s_out - > flags | = PHP_STREAM_FLAG_NO_CLOSE ;
s_err - > flags | = PHP_STREAM_FLAG_NO_CLOSE ;
# endif
2014-10-24 17:29:50 +00:00
php_stream_to_zval ( s_in , & zin ) ;
php_stream_to_zval ( s_out , & zout ) ;
php_stream_to_zval ( s_err , & zerr ) ;
2014-05-01 09:38:08 +00:00
2014-10-24 17:29:50 +00:00
ic . value = zin ;
2014-05-01 09:38:08 +00:00
ic . flags = CONST_CS ;
2014-10-24 17:29:50 +00:00
ic . name = zend_string_init ( ZEND_STRL ( " STDIN " ) , 0 ) ;
2014-05-01 09:38:08 +00:00
ic . module_number = 0 ;
2014-12-13 22:06:14 +00:00
zend_register_constant ( & ic ) ;
2014-05-01 09:38:08 +00:00
2014-10-24 17:29:50 +00:00
oc . value = zout ;
2014-05-01 09:38:08 +00:00
oc . flags = CONST_CS ;
2014-10-24 17:29:50 +00:00
oc . name = zend_string_init ( ZEND_STRL ( " STDOUT " ) , 0 ) ;
2014-05-01 09:38:08 +00:00
oc . module_number = 0 ;
2014-12-13 22:06:14 +00:00
zend_register_constant ( & oc ) ;
2014-05-01 09:38:08 +00:00
2014-10-24 17:29:50 +00:00
ec . value = zerr ;
2014-05-01 09:38:08 +00:00
ec . flags = CONST_CS ;
2014-10-24 17:29:50 +00:00
ec . name = zend_string_init ( ZEND_STRL ( " STDERR " ) , 0 ) ;
2014-05-01 09:38:08 +00:00
ec . module_number = 0 ;
2014-12-13 22:06:14 +00:00
zend_register_constant ( & ec ) ;
2014-05-01 09:38:08 +00:00
}
/* }}} */
2013-11-09 22:47:39 +00:00
/* {{{ sapi_module_struct phpdbg_sapi_module
2013-11-23 17:30:10 +00:00
*/
2013-11-09 22:47:39 +00:00
static sapi_module_struct phpdbg_sapi_module = {
2013-11-26 10:02:58 +00:00
" phpdbg " , /* name */
" phpdbg " , /* pretty name */
2013-11-09 22:35:03 +00:00
2013-11-26 10:02:58 +00:00
php_sapi_phpdbg_module_startup , /* startup */
2013-11-09 22:35:03 +00:00
php_module_shutdown_wrapper , /* shutdown */
2013-11-26 10:02:58 +00:00
NULL , /* activate */
php_sapi_phpdbg_deactivate , /* deactivate */
2013-11-09 22:35:03 +00:00
2013-11-26 10:02:58 +00:00
php_sapi_phpdbg_ub_write , /* unbuffered write */
php_sapi_phpdbg_flush , /* flush */
NULL , /* get uid */
NULL , /* getenv */
2013-11-09 22:35:03 +00:00
2013-11-26 10:02:58 +00:00
php_error , /* error handler */
2013-11-09 22:35:03 +00:00
2013-11-26 10:02:58 +00:00
php_sapi_phpdbg_header_handler , /* header handler */
php_sapi_phpdbg_send_headers , /* send headers handler */
php_sapi_phpdbg_send_header , /* send header handler */
2013-11-09 22:35:03 +00:00
2013-11-26 10:02:58 +00:00
NULL , /* read POST data */
2013-11-10 22:44:28 +00:00
php_sapi_phpdbg_read_cookies , /* read Cookies */
2013-11-09 22:35:03 +00:00
2013-11-26 10:02:58 +00:00
php_sapi_phpdbg_register_vars , /* register server variables */
php_sapi_phpdbg_log_message , /* Log message */
NULL , /* Get request time */
NULL , /* Child terminate */
2013-11-09 22:35:03 +00:00
STANDARD_SAPI_MODULE_PROPERTIES
} ;
/* }}} */
2013-11-10 22:01:40 +00:00
const opt_struct OPTIONS [ ] = { /* {{{ */
2013-11-12 21:40:15 +00:00
{ ' c ' , 1 , " ini path override " } ,
{ ' d ' , 1 , " define ini entry on command line " } ,
{ ' n ' , 0 , " no php.ini " } ,
{ ' z ' , 1 , " load zend_extension " } ,
/* phpdbg options */
2013-11-20 14:35:25 +00:00
{ ' q ' , 0 , " no banner " } ,
2013-11-14 21:10:44 +00:00
{ ' v ' , 0 , " disable quietness " } ,
2013-11-12 21:40:15 +00:00
{ ' b ' , 0 , " boring colours " } ,
2013-11-14 21:10:44 +00:00
{ ' i ' , 1 , " specify init " } ,
{ ' I ' , 0 , " ignore init " } ,
{ ' O ' , 1 , " opline log " } ,
2013-11-20 16:19:37 +00:00
{ ' r ' , 0 , " run " } ,
2015-07-22 11:46:06 +00:00
{ ' e ' , 0 , " generate ext_stmt opcodes " } ,
2013-11-20 17:01:37 +00:00
{ ' E ' , 0 , " step-through-eval " } ,
2013-12-02 14:45:41 +00:00
{ ' S ' , 1 , " sapi-name " } ,
2013-11-28 22:06:27 +00:00
# ifndef _WIN32
2013-11-27 16:49:51 +00:00
{ ' l ' , 1 , " listen " } ,
2013-11-29 19:42:41 +00:00
{ ' a ' , 1 , " address-or-any " } ,
2013-11-28 22:06:27 +00:00
# endif
2014-09-21 02:17:19 +00:00
{ ' x ' , 0 , " xml output " } ,
2015-04-19 19:53:49 +00:00
{ ' p ' , 2 , " show opcodes " } ,
2015-03-21 21:40:44 +00:00
{ ' h ' , 0 , " help " } ,
2013-12-18 14:12:28 +00:00
{ ' V ' , 0 , " version " } ,
2013-11-12 21:40:15 +00:00
{ ' - ' , 0 , NULL }
2013-11-10 17:45:06 +00:00
} ; /* }}} */
2013-11-10 22:44:28 +00:00
const char phpdbg_ini_hardcoded [ ] =
2013-11-23 17:30:10 +00:00
" html_errors=Off \n "
" register_argc_argv=On \n "
" implicit_flush=On \n "
" display_errors=Off \n "
" log_errors=On \n "
" max_execution_time=0 \n "
2013-12-24 12:11:57 +00:00
" max_input_time=-1 \n "
2014-10-26 07:02:15 +00:00
" error_log= \n "
" output_buffering=off \n \0 " ;
2013-11-10 22:44:28 +00:00
2013-11-10 17:45:06 +00:00
/* overwriteable ini defaults must be set in phpdbg_ini_defaults() */
2013-11-26 10:02:58 +00:00
# define INI_DEFAULT(name, value) \
2014-10-24 17:29:50 +00:00
ZVAL_STRINGL ( & tmp , value , sizeof ( value ) - 1 ) ; \
zend_hash_str_update ( configuration_hash , name , sizeof ( name ) - 1 , & tmp ) ;
2013-11-10 17:45:06 +00:00
2013-11-12 21:40:15 +00:00
void phpdbg_ini_defaults ( HashTable * configuration_hash ) /* { { { */
{
2013-11-23 17:30:10 +00:00
zval tmp ;
2013-11-10 17:45:06 +00:00
INI_DEFAULT ( " report_zend_debug " , " 0 " ) ;
} /* }}} */
2014-12-13 22:06:14 +00:00
static void phpdbg_welcome ( zend_bool cleaning ) /* { { { */
2013-11-18 01:07:57 +00:00
{
2013-11-23 17:30:10 +00:00
/* print blurb */
2013-11-18 01:07:57 +00:00
if ( ! cleaning ) {
2014-10-08 22:25:25 +00:00
phpdbg_xml ( " <intros> " ) ;
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " intro " , " version= \" %s \" " , " Welcome to phpdbg, the interactive PHP debugger, v%s " , PHPDBG_VERSION ) ;
phpdbg_writeln ( " intro " , " help= \" help \" " , " To get help using phpdbg type \" help \" and press enter " ) ;
phpdbg_notice ( " intro " , " report= \" %s \" " , " Please report bugs to <%s> " , PHPDBG_ISSUES ) ;
2014-10-08 22:25:25 +00:00
phpdbg_xml ( " </intros> " ) ;
2014-10-26 02:50:28 +00:00
} else if ( phpdbg_startup_run = = 0 ) {
2014-09-21 02:17:19 +00:00
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_WRITE_XML ) ) {
phpdbg_notice ( NULL , NULL , " Clean Execution Environment " ) ;
}
2013-11-18 01:07:57 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_write ( " cleaninfo " , " classes= \" %d \" functions= \" %d \" constants= \" %d \" includes= \" %d \" " ,
2014-10-19 18:09:39 +00:00
" Classes %d \n "
" Functions %d \n "
" Constants %d \n "
" Includes %d \n " ,
2014-09-21 02:17:19 +00:00
zend_hash_num_elements ( EG ( class_table ) ) ,
zend_hash_num_elements ( EG ( function_table ) ) ,
zend_hash_num_elements ( EG ( zend_constants ) ) ,
zend_hash_num_elements ( & EG ( included_files ) ) ) ;
2013-11-18 01:07:57 +00:00
}
} /* }}} */
2013-11-21 19:47:31 +00:00
static inline void phpdbg_sigint_handler ( int signo ) /* { { { */
{
2013-11-23 16:45:03 +00:00
2014-09-28 00:57:12 +00:00
if ( PHPDBG_G ( flags ) & PHPDBG_IS_INTERACTIVE ) {
2014-01-13 20:16:50 +00:00
/* we quit remote consoles on recv SIGINT */
if ( PHPDBG_G ( flags ) & PHPDBG_IS_REMOTE ) {
2014-10-26 02:50:28 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IS_STOPPING ;
2014-01-13 20:16:50 +00:00
zend_bailout ( ) ;
}
2014-09-28 00:57:12 +00:00
} else {
/* set signalled only when not interactive */
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_INTERACTIVE ) ) {
if ( PHPDBG_G ( flags ) & PHPDBG_IS_SIGNALED ) {
char mem [ PHPDBG_SIGSAFE_MEM_SIZE + 1 ] ;
2014-12-13 22:06:14 +00:00
phpdbg_set_sigsafe_mem ( mem ) ;
2014-09-28 00:57:12 +00:00
zend_try {
2014-12-13 22:06:14 +00:00
phpdbg_force_interruption ( ) ;
2014-09-28 00:57:12 +00:00
} zend_end_try ( )
2014-12-13 22:06:14 +00:00
phpdbg_clear_sigsafe_mem ( ) ;
2014-09-28 00:57:12 +00:00
return ;
2013-11-27 16:49:51 +00:00
}
2014-09-28 00:57:12 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IS_SIGNALED ;
2013-11-27 16:49:51 +00:00
}
}
} /* }}} */
2014-09-15 07:58:14 +00:00
static void phpdbg_remote_close ( int socket , FILE * stream ) {
if ( socket > = 0 ) {
2014-10-19 11:40:45 +00:00
phpdbg_close_socket ( socket ) ;
2013-11-28 14:54:06 +00:00
}
2013-12-15 13:55:03 +00:00
2014-09-15 07:58:14 +00:00
if ( stream ) {
fclose ( stream ) ;
2013-11-28 14:54:06 +00:00
}
2014-09-15 07:58:14 +00:00
}
2013-12-15 13:55:03 +00:00
2013-11-28 09:31:06 +00:00
/* don't inline this, want to debug it easily, will inline when done */
2014-12-13 22:06:14 +00:00
static int phpdbg_remote_init ( const char * address , unsigned short port , int server , int * socket , FILE * * stream ) {
2014-09-15 07:58:14 +00:00
phpdbg_remote_close ( * socket , * stream ) ;
2013-11-28 09:31:06 +00:00
2014-10-11 21:36:12 +00:00
if ( server < 0 ) {
2014-10-09 10:01:25 +00:00
phpdbg_rlog ( fileno ( stderr ) , " Initializing connection on %s:%u failed " , address , port ) ;
2013-12-15 13:55:03 +00:00
2013-11-27 16:49:51 +00:00
return FAILURE ;
2013-11-28 15:51:11 +00:00
}
2013-11-28 14:54:06 +00:00
2014-10-09 10:01:25 +00:00
phpdbg_rlog ( fileno ( stderr ) , " accepting connections on %s:%u " , address , port ) ;
2013-11-27 16:49:51 +00:00
{
2014-10-19 11:40:45 +00:00
struct sockaddr_storage address ;
2013-11-28 16:41:21 +00:00
socklen_t size = sizeof ( address ) ;
char buffer [ 20 ] = { 0 } ;
2014-10-18 23:31:00 +00:00
/* XXX error checks */
2014-09-15 07:58:14 +00:00
memset ( & address , 0 , size ) ;
2014-10-11 21:36:12 +00:00
* socket = accept ( server , ( struct sockaddr * ) & address , & size ) ;
2014-10-19 11:40:45 +00:00
inet_ntop ( AF_INET , & ( ( ( struct sockaddr_in * ) & address ) - > sin_addr ) , buffer , sizeof ( buffer ) ) ;
2013-11-28 09:31:06 +00:00
2014-09-28 00:57:12 +00:00
phpdbg_rlog ( fileno ( stderr ) , " connection established from %s " , buffer ) ;
2013-11-28 09:31:06 +00:00
}
2013-11-28 16:41:21 +00:00
2014-10-18 23:31:00 +00:00
# ifndef _WIN32
2014-09-15 07:58:14 +00:00
dup2 ( * socket , fileno ( stdout ) ) ;
dup2 ( * socket , fileno ( stdin ) ) ;
2013-11-28 16:41:21 +00:00
2013-11-28 15:51:11 +00:00
setbuf ( stdout , NULL ) ;
2013-11-28 16:41:21 +00:00
2014-09-15 07:58:14 +00:00
* stream = fdopen ( * socket , " r+ " ) ;
2013-11-28 16:41:21 +00:00
2014-09-28 00:57:12 +00:00
phpdbg_set_async_io ( * socket ) ;
2014-10-18 23:31:00 +00:00
# endif
2013-11-27 16:49:51 +00:00
return SUCCESS ;
2014-09-15 07:58:14 +00:00
}
2013-11-28 16:41:21 +00:00
2014-10-12 17:53:05 +00:00
# ifndef _WIN32
2014-09-28 00:57:12 +00:00
/* This function *strictly* assumes that SIGIO is *only* used on the remote connection stream */
void phpdbg_sigio_handler ( int sig , siginfo_t * info , void * context ) /* { { { */
{
int flags ;
size_t newlen ;
2014-10-02 23:29:41 +00:00
size_t i /*, last_nl*/ ;
2013-11-28 16:41:21 +00:00
2014-09-28 00:57:12 +00:00
// if (!(info->si_band & POLLIN)) {
// return; /* Not interested in writeablility etc., just interested in incoming data */
// }
2013-11-28 16:41:21 +00:00
2014-09-28 00:57:12 +00:00
/* only non-blocking reading, avoid non-blocking writing */
flags = fcntl ( PHPDBG_G ( io ) [ PHPDBG_STDIN ] . fd , F_GETFL , 0 ) ;
fcntl ( PHPDBG_G ( io ) [ PHPDBG_STDIN ] . fd , F_SETFL , flags | O_NONBLOCK ) ;
2013-11-28 16:41:21 +00:00
2014-09-28 00:57:12 +00:00
do {
char mem [ PHPDBG_SIGSAFE_MEM_SIZE + 1 ] ;
size_t off = 0 ;
2013-11-28 16:41:21 +00:00
2014-09-28 00:57:12 +00:00
if ( ( newlen = recv ( PHPDBG_G ( io ) [ PHPDBG_STDIN ] . fd , mem , PHPDBG_SIGSAFE_MEM_SIZE , MSG_PEEK ) ) = = ( size_t ) - 1 ) {
break ;
2013-11-28 16:41:21 +00:00
}
2014-09-28 00:57:12 +00:00
for ( i = 0 ; i < newlen ; i + + ) {
switch ( mem [ off + i ] ) {
case ' \x03 ' : /* ^C char */
if ( PHPDBG_G ( flags ) & PHPDBG_IS_INTERACTIVE ) {
break ; /* or quit ??? */
}
if ( PHPDBG_G ( flags ) & PHPDBG_IS_SIGNALED ) {
2014-12-13 22:06:14 +00:00
phpdbg_set_sigsafe_mem ( mem ) ;
2014-09-28 00:57:12 +00:00
zend_try {
2014-12-13 22:06:14 +00:00
phpdbg_force_interruption ( ) ;
2014-09-28 00:57:12 +00:00
} zend_end_try ( ) ;
2014-12-13 22:06:14 +00:00
phpdbg_clear_sigsafe_mem ( ) ;
2014-09-28 00:57:12 +00:00
break ;
}
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_INTERACTIVE ) ) {
PHPDBG_G ( flags ) | = PHPDBG_IS_SIGNALED ;
}
break ;
2014-10-02 23:29:41 +00:00
/* case '\n':
zend_llist_add_element ( PHPDBG_G ( stdin ) , strndup ( )
last_nl = PHPDBG_G ( stdin_buf ) . len + i ;
break ;
*/ }
2013-11-28 16:41:21 +00:00
}
2014-09-28 00:57:12 +00:00
off + = i ;
} while ( 0 ) ;
2013-11-28 16:41:21 +00:00
2014-09-28 00:57:12 +00:00
fcntl ( PHPDBG_G ( io ) [ PHPDBG_STDIN ] . fd , F_SETFL , flags ) ;
2013-11-27 16:49:51 +00:00
} /* }}} */
2014-06-29 12:57:57 +00:00
void phpdbg_signal_handler ( int sig , siginfo_t * info , void * context ) /* { { { */
{
2013-12-11 20:27:03 +00:00
int is_handled = FAILURE ;
switch ( sig ) {
case SIGBUS :
case SIGSEGV :
2014-10-02 23:29:41 +00:00
if ( PHPDBG_G ( sigsegv_bailout ) ) {
LONGJMP ( * PHPDBG_G ( sigsegv_bailout ) , FAILURE ) ;
}
2014-12-13 22:06:14 +00:00
is_handled = phpdbg_watchpoint_segfault_handler ( info , context ) ;
2013-12-11 20:27:03 +00:00
if ( is_handled = = FAILURE ) {
# ifdef ZEND_SIGNALS
2014-12-13 22:06:14 +00:00
zend_sigaction ( sig , & PHPDBG_G ( old_sigsegv_signal ) , NULL ) ;
2013-12-11 20:27:03 +00:00
# else
sigaction ( sig , & PHPDBG_G ( old_sigsegv_signal ) , NULL ) ;
# endif
}
break ;
}
2014-06-29 12:57:57 +00:00
} /* }}} */
2014-03-16 18:39:02 +00:00
# endif
2013-12-11 20:27:03 +00:00
2014-06-03 21:00:45 +00:00
2015-07-24 15:17:09 +00:00
/* A bit dark magic in order to have meaningful allocator adresses */
2015-07-24 15:51:46 +00:00
# if ZEND_DEBUG && (__has_builtin(__builtin_frame_address) || ZEND_GCC_VERSION >= 3004)
2015-07-24 15:17:09 +00:00
# define FETCH_PARENT_FILELINE(argsize) \
char * __zend_filename , * __zend_orig_filename ; \
uint __zend_lineno , __zend_orig_lineno ; \
void * parent = __builtin_frame_address ( 1U ) ; \
parent - = ZEND_MM_ALIGNED_SIZE ( sizeof ( void * ) ) ; /* remove frame pointer adress */ \
parent - = ( argsize ) ; /* size of first arguments */ \
parent - = sizeof ( char * ) ; /* filename */ \
__zend_filename = * ( char * * ) parent ; \
parent = ( void * ) ( ( intptr_t ) parent & ZEND_MM_ALIGNMENT_MASK ) ; /* realign */ \
parent - = sizeof ( uint ) ; /* lineno */ \
__zend_lineno = * ( uint * ) parent ; \
parent = ( void * ) ( ( intptr_t ) parent & ZEND_MM_ALIGNMENT_MASK ) ; /* realign */ \
parent - = sizeof ( char * ) ; /* orig_filename */ \
__zend_orig_filename = * ( char * * ) parent ; \
parent = ( void * ) ( ( intptr_t ) parent & ZEND_MM_ALIGNMENT_MASK ) ; /* realign */ \
parent - = sizeof ( uint ) ; /* orig_lineno */ \
__zend_orig_lineno = * ( uint * ) parent ;
# elif ZEND_DEBUG
2015-07-24 15:51:46 +00:00
# define FETCH_PARENT_FILELINE(argsize) \
2015-07-24 15:17:09 +00:00
char * __zend_filename = __FILE__ , * __zend_orig_filename = NULL ; \
uint __zend_lineno = __LINE__ , __zend_orig_lineno = 0 ;
2015-07-24 15:51:46 +00:00
# else
# define FETCH_PARENT_FILELINE(argsize)
2015-07-24 15:17:09 +00:00
# endif
2014-06-03 21:00:45 +00:00
2014-06-29 12:57:57 +00:00
void * phpdbg_malloc_wrapper ( size_t size ) /* { { { */
2014-06-03 21:00:45 +00:00
{
2015-07-24 15:17:09 +00:00
FETCH_PARENT_FILELINE ( ZEND_MM_ALIGNED_SIZE ( sizeof ( size ) ) ) ;
return _zend_mm_alloc ( zend_mm_get_heap ( ) , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC ) ;
2014-06-29 12:57:57 +00:00
} /* }}} */
2014-06-03 21:00:45 +00:00
2014-06-29 12:57:57 +00:00
void phpdbg_free_wrapper ( void * p ) /* { { { */
2014-06-03 21:00:45 +00:00
{
2015-07-24 15:17:09 +00:00
zend_mm_heap * heap = zend_mm_get_heap ( ) ;
2015-03-09 03:19:05 +00:00
if ( UNEXPECTED ( heap = = p ) ) {
/* TODO: heap maybe allocated by mmap(zend_mm_init) or malloc(USE_ZEND_ALLOC=0)
* let ' s prevent it from segfault for now
*/
} else {
2015-07-24 15:17:09 +00:00
FETCH_PARENT_FILELINE ( ZEND_MM_ALIGNED_SIZE ( sizeof ( p ) ) ) ;
return _zend_mm_free ( heap , p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC ) ;
2015-03-09 03:19:05 +00:00
}
2014-06-29 12:57:57 +00:00
} /* }}} */
2014-06-03 21:00:45 +00:00
2014-06-29 12:57:57 +00:00
void * phpdbg_realloc_wrapper ( void * ptr , size_t size ) /* { { { */
2014-06-03 21:00:45 +00:00
{
2015-07-24 15:17:09 +00:00
FETCH_PARENT_FILELINE ( ZEND_MM_ALIGNED_SIZE ( sizeof ( ptr ) ) + ZEND_MM_ALIGNED_SIZE ( sizeof ( size ) ) ) ;
return _zend_mm_realloc ( zend_mm_get_heap ( ) , ptr , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC ) ;
2014-06-29 12:57:57 +00:00
} /* }}} */
2014-06-03 21:00:45 +00:00
2013-11-12 21:40:15 +00:00
int main ( int argc , char * * argv ) /* { { { */
2013-11-09 23:07:04 +00:00
{
2013-11-10 00:34:38 +00:00
sapi_module_struct * phpdbg = & phpdbg_sapi_module ;
2013-12-03 12:26:19 +00:00
char * sapi_name ;
2013-11-14 11:13:21 +00:00
char * ini_entries ;
int ini_entries_len ;
2013-12-03 12:26:19 +00:00
char * * zend_extensions = NULL ;
zend_ulong zend_extensions_len = 0L ;
2013-11-23 15:11:09 +00:00
zend_bool ini_ignore ;
char * ini_override ;
2014-10-26 19:43:49 +00:00
char * exec = NULL ;
2013-11-14 14:14:13 +00:00
char * init_file ;
size_t init_file_len ;
2013-11-14 16:58:50 +00:00
zend_bool init_file_default ;
2013-11-14 21:10:44 +00:00
char * oplog_file ;
size_t oplog_file_len ;
2013-11-14 11:13:21 +00:00
zend_ulong flags ;
char * php_optarg ;
2013-11-20 14:35:25 +00:00
int php_optind , opt , show_banner = 1 ;
2014-10-26 21:21:18 +00:00
long cleaning = - 1 ;
2015-07-13 12:11:39 +00:00
volatile zend_bool quit_immediately = 0 ; /* somehow some gcc release builds will play a bit around with order in combination with setjmp..., hence volatile */
2013-11-28 16:41:21 +00:00
zend_bool remote = 0 ;
2014-10-26 19:43:49 +00:00
zend_phpdbg_globals * settings = NULL ;
2014-10-28 16:20:21 +00:00
char * bp_tmp = NULL ;
2013-11-29 19:42:41 +00:00
char * address ;
2014-09-15 07:58:14 +00:00
int listen = - 1 ;
int server = - 1 ;
int socket = - 1 ;
FILE * stream = NULL ;
2015-04-19 19:53:49 +00:00
char * print_opline_func ;
2015-07-22 11:46:06 +00:00
zend_bool ext_stmt = 0 ;
2015-07-24 15:17:09 +00:00
zend_bool use_mm_wrappers = 0 ;
2013-11-20 18:52:34 +00:00
2013-11-09 22:35:03 +00:00
# ifdef ZTS
2013-11-09 23:07:04 +00:00
void * * * tsrm_ls ;
2013-11-09 22:35:03 +00:00
# endif
2013-11-09 23:07:04 +00:00
2014-03-16 18:39:02 +00:00
# ifndef _WIN32
2014-09-28 00:57:12 +00:00
struct sigaction sigio_struct ;
2013-12-11 20:27:03 +00:00
struct sigaction signal_struct ;
signal_struct . sa_sigaction = phpdbg_signal_handler ;
signal_struct . sa_flags = SA_SIGINFO | SA_NODEFER ;
2015-07-23 12:55:13 +00:00
sigemptyset ( & signal_struct . sa_mask ) ;
2014-09-28 00:57:12 +00:00
sigio_struct . sa_sigaction = phpdbg_sigio_handler ;
sigio_struct . sa_flags = SA_SIGINFO ;
2015-07-23 12:55:13 +00:00
sigemptyset ( & sigio_struct . sa_mask ) ;
2013-12-11 20:27:03 +00:00
2013-11-29 19:42:41 +00:00
address = strdup ( " 127.0.0.1 " ) ;
2013-11-28 22:06:27 +00:00
# endif
2013-11-09 23:07:04 +00:00
2013-11-09 22:47:39 +00:00
# ifdef PHP_WIN32
2013-11-09 23:07:04 +00:00
_fmode = _O_BINARY ; /* sets default for file streams to binary */
setmode ( _fileno ( stdin ) , O_BINARY ) ; /* make the stdio mode be binary */
setmode ( _fileno ( stdout ) , O_BINARY ) ; /* make the stdio mode be binary */
setmode ( _fileno ( stderr ) , O_BINARY ) ; /* make the stdio mode be binary */
2013-11-09 22:47:39 +00:00
# endif
2013-11-10 22:44:28 +00:00
# ifdef ZTS
2013-11-18 01:18:12 +00:00
tsrm_startup ( 1 , 1 , 0 , NULL ) ;
2013-11-10 22:44:28 +00:00
tsrm_ls = ts_resource ( 0 ) ;
2013-12-15 13:55:03 +00:00
# endif
2013-12-11 20:27:03 +00:00
2013-11-25 23:02:54 +00:00
phpdbg_main :
2013-11-18 01:18:12 +00:00
ini_entries = NULL ;
ini_entries_len = 0 ;
2013-11-23 15:11:09 +00:00
ini_ignore = 0 ;
ini_override = NULL ;
2013-12-03 12:26:19 +00:00
zend_extensions = NULL ;
zend_extensions_len = 0L ;
2013-11-18 01:18:12 +00:00
init_file = NULL ;
init_file_len = 0 ;
init_file_default = 1 ;
oplog_file = NULL ;
oplog_file_len = 0 ;
flags = PHPDBG_DEFAULT_FLAGS ;
php_optarg = NULL ;
php_optind = 1 ;
opt = 0 ;
2013-12-02 14:45:41 +00:00
sapi_name = NULL ;
2014-10-26 19:43:49 +00:00
if ( settings ) {
exec = settings - > exec ;
}
2013-12-15 13:55:03 +00:00
2013-11-18 01:18:12 +00:00
while ( ( opt = php_getopt ( argc , argv , OPTIONS , & php_optarg , & php_optind , 0 , 2 ) ) ! = - 1 ) {
switch ( opt ) {
2013-11-20 16:19:37 +00:00
case ' r ' :
2015-06-16 21:36:20 +00:00
if ( settings = = NULL ) {
phpdbg_startup_run + + ;
}
2013-11-23 17:30:10 +00:00
break ;
2013-11-18 01:18:12 +00:00
case ' n ' :
2013-11-23 15:11:09 +00:00
ini_ignore = 1 ;
2013-11-23 17:30:10 +00:00
break ;
2013-11-18 01:18:12 +00:00
case ' c ' :
2013-11-23 15:11:09 +00:00
if ( ini_override ) {
free ( ini_override ) ;
2013-11-18 01:18:12 +00:00
}
2013-11-23 15:11:09 +00:00
ini_override = strdup ( php_optarg ) ;
2013-11-23 17:30:10 +00:00
break ;
2013-11-18 01:18:12 +00:00
case ' d ' : {
2013-11-26 07:11:34 +00:00
int len = strlen ( php_optarg ) ;
char * val ;
if ( ( val = strchr ( php_optarg , ' = ' ) ) ) {
val + + ;
if ( ! isalnum ( * val ) & & * val ! = ' " ' & & * val ! = ' \' ' & & * val ! = ' \0 ' ) {
ini_entries = realloc ( ini_entries , ini_entries_len + len + sizeof ( " \" \" \n \0 " ) ) ;
memcpy ( ini_entries + ini_entries_len , php_optarg , ( val - php_optarg ) ) ;
ini_entries_len + = ( val - php_optarg ) ;
memcpy ( ini_entries + ini_entries_len , " \" " , 1 ) ;
ini_entries_len + + ;
memcpy ( ini_entries + ini_entries_len , val , len - ( val - php_optarg ) ) ;
ini_entries_len + = len - ( val - php_optarg ) ;
memcpy ( ini_entries + ini_entries_len , " \" \n \0 " , sizeof ( " \" \n \0 " ) ) ;
ini_entries_len + = sizeof ( " \n \0 \" " ) - 2 ;
} else {
ini_entries = realloc ( ini_entries , ini_entries_len + len + sizeof ( " \n \0 " ) ) ;
memcpy ( ini_entries + ini_entries_len , php_optarg , len ) ;
memcpy ( ini_entries + ini_entries_len + len , " \n \0 " , sizeof ( " \n \0 " ) ) ;
ini_entries_len + = len + sizeof ( " \n \0 " ) - 2 ;
}
} else {
ini_entries = realloc ( ini_entries , ini_entries_len + len + sizeof ( " =1 \n \0 " ) ) ;
memcpy ( ini_entries + ini_entries_len , php_optarg , len ) ;
memcpy ( ini_entries + ini_entries_len + len , " =1 \n \0 " , sizeof ( " =1 \n \0 " ) ) ;
ini_entries_len + = len + sizeof ( " =1 \n \0 " ) - 2 ;
}
} break ;
2013-12-15 13:55:03 +00:00
2013-11-18 01:18:12 +00:00
case ' z ' :
2013-12-03 12:26:19 +00:00
zend_extensions_len + + ;
if ( zend_extensions ) {
zend_extensions = realloc ( zend_extensions , sizeof ( char * ) * zend_extensions_len ) ;
} else zend_extensions = malloc ( sizeof ( char * ) * zend_extensions_len ) ;
zend_extensions [ zend_extensions_len - 1 ] = strdup ( php_optarg ) ;
2013-11-26 07:11:34 +00:00
break ;
2013-11-18 01:18:12 +00:00
2013-11-26 07:11:34 +00:00
/* begin phpdbg options */
2013-11-18 01:18:12 +00:00
2013-12-02 14:45:41 +00:00
case ' S ' : { /* set SAPI name */
if ( sapi_name ) {
free ( sapi_name ) ;
}
sapi_name = strdup ( php_optarg ) ;
} break ;
2013-11-18 01:18:12 +00:00
case ' I ' : { /* ignore .phpdbginit */
2013-11-26 07:11:34 +00:00
init_file_default = 0 ;
} break ;
2013-11-18 01:18:12 +00:00
case ' i ' : { /* set init file */
2013-12-04 23:26:14 +00:00
if ( init_file ) {
free ( init_file ) ;
}
2013-12-15 13:55:03 +00:00
2013-11-26 07:11:34 +00:00
init_file_len = strlen ( php_optarg ) ;
if ( init_file_len ) {
2013-12-04 23:26:14 +00:00
init_file = strdup ( php_optarg ) ;
2013-11-26 07:11:34 +00:00
}
} break ;
2013-11-18 01:18:12 +00:00
case ' O ' : { /* set oplog output */
2013-11-26 07:11:34 +00:00
oplog_file_len = strlen ( php_optarg ) ;
if ( oplog_file_len ) {
oplog_file = strdup ( php_optarg ) ;
}
} break ;
2013-11-18 01:18:12 +00:00
case ' v ' : /* set quietness off */
2013-11-26 07:11:34 +00:00
flags & = ~ PHPDBG_IS_QUIET ;
break ;
2013-11-18 01:18:12 +00:00
2015-07-22 11:46:06 +00:00
case ' e ' :
ext_stmt = 1 ;
break ;
2013-11-20 17:01:37 +00:00
case ' E ' : /* stepping through eval on */
2013-11-26 07:11:34 +00:00
flags | = PHPDBG_IS_STEPONEVAL ;
break ;
2013-11-18 01:18:12 +00:00
case ' b ' : /* set colours off */
2013-11-26 07:11:34 +00:00
flags & = ~ PHPDBG_IS_COLOURED ;
break ;
2013-11-20 14:35:25 +00:00
case ' q ' : /* hide banner */
2013-11-26 07:11:34 +00:00
show_banner = 0 ;
break ;
2013-11-28 22:06:27 +00:00
# ifndef _WIN32
2014-09-15 07:58:14 +00:00
/* if you pass a listen port, we will read and write on listen port */
case ' l ' : /* set listen ports */
if ( sscanf ( php_optarg , " %d " , & listen ) ! = 1 ) {
listen = 8000 ;
2013-11-29 18:55:15 +00:00
}
2015-04-20 10:22:55 +00:00
break ;
2013-12-15 13:55:03 +00:00
2013-11-29 19:42:41 +00:00
case ' a ' : { /* set bind address */
free ( address ) ;
if ( ! php_optarg ) {
address = strdup ( " * " ) ;
} else address = strdup ( php_optarg ) ;
} break ;
2013-11-28 22:06:27 +00:00
# endif
2013-12-18 14:12:28 +00:00
2014-09-21 02:17:19 +00:00
case ' x ' :
flags | = PHPDBG_WRITE_XML ;
break ;
2015-03-21 21:40:44 +00:00
2015-04-19 19:53:49 +00:00
case ' p ' : {
print_opline_func = php_optarg ;
show_banner = 0 ;
settings = ( void * ) 0x1 ;
} break ;
2015-03-21 21:40:44 +00:00
case ' h ' : {
sapi_startup ( phpdbg ) ;
phpdbg - > startup ( phpdbg ) ;
PHPDBG_G ( flags ) = 0 ;
phpdbg_set_prompt ( PHPDBG_DEFAULT_PROMPT ) ;
phpdbg_do_help ( NULL ) ;
sapi_deactivate ( ) ;
sapi_shutdown ( ) ;
return 0 ;
} break ;
2013-12-18 14:12:28 +00:00
case ' V ' : {
2013-12-18 15:13:14 +00:00
sapi_startup ( phpdbg ) ;
phpdbg - > startup ( phpdbg ) ;
2013-12-18 14:12:28 +00:00
printf (
2015-01-15 15:27:30 +00:00
" phpdbg %s (built: %s %s) \n PHP %s, Copyright (c) 1997-2015 The PHP Group \n %s " ,
2013-12-18 14:12:28 +00:00
PHPDBG_VERSION ,
__DATE__ ,
__TIME__ ,
2013-12-18 15:13:14 +00:00
PHP_VERSION ,
get_zend_version ( )
2013-12-18 14:12:28 +00:00
) ;
2014-12-13 22:06:14 +00:00
sapi_deactivate ( ) ;
2013-12-18 15:13:14 +00:00
sapi_shutdown ( ) ;
2013-12-18 14:12:28 +00:00
return 0 ;
} break ;
2013-11-18 01:18:12 +00:00
}
2015-04-19 19:53:49 +00:00
php_optarg = NULL ;
2013-11-18 01:18:12 +00:00
}
2015-01-03 09:22:58 +00:00
2014-04-21 20:24:41 +00:00
/* set exec if present on command line */
2015-07-20 14:18:30 +00:00
if ( argc > php_optind & & ( strcmp ( argv [ php_optind - 1 ] , " -- " ) ! = SUCCESS ) ) {
if ( ! exec & & strlen ( argv [ php_optind ] ) ) {
2014-04-21 20:24:41 +00:00
exec = strdup ( argv [ php_optind ] ) ;
}
php_optind + + ;
}
2013-11-10 17:51:20 +00:00
2013-12-02 14:45:41 +00:00
if ( sapi_name ) {
phpdbg - > name = sapi_name ;
}
2013-12-15 13:55:03 +00:00
2013-11-18 01:18:12 +00:00
phpdbg - > ini_defaults = phpdbg_ini_defaults ;
2013-11-10 17:45:06 +00:00
phpdbg - > phpinfo_as_text = 1 ;
phpdbg - > php_ini_ignore_cwd = 1 ;
2013-11-09 23:07:04 +00:00
sapi_startup ( phpdbg ) ;
2013-11-18 01:18:12 +00:00
phpdbg - > executable_location = argv [ 0 ] ;
phpdbg - > phpinfo_as_text = 1 ;
2013-11-23 15:11:09 +00:00
phpdbg - > php_ini_ignore = ini_ignore ;
phpdbg - > php_ini_path_override = ini_override ;
2013-11-12 13:07:35 +00:00
2013-11-18 01:18:12 +00:00
if ( ini_entries ) {
2013-11-10 22:44:28 +00:00
ini_entries = realloc ( ini_entries , ini_entries_len + sizeof ( phpdbg_ini_hardcoded ) ) ;
memmove ( ini_entries + sizeof ( phpdbg_ini_hardcoded ) - 2 , ini_entries , ini_entries_len + 1 ) ;
memcpy ( ini_entries , phpdbg_ini_hardcoded , sizeof ( phpdbg_ini_hardcoded ) - 2 ) ;
} else {
ini_entries = malloc ( sizeof ( phpdbg_ini_hardcoded ) ) ;
memcpy ( ini_entries , phpdbg_ini_hardcoded , sizeof ( phpdbg_ini_hardcoded ) ) ;
}
ini_entries_len + = sizeof ( phpdbg_ini_hardcoded ) - 2 ;
2013-12-15 13:55:03 +00:00
2013-12-03 12:26:19 +00:00
if ( zend_extensions_len ) {
zend_ulong zend_extension = 0L ;
2013-12-15 13:55:03 +00:00
2013-12-03 12:26:19 +00:00
while ( zend_extension < zend_extensions_len ) {
const char * ze = zend_extensions [ zend_extension ] ;
size_t ze_len = strlen ( ze ) ;
2013-12-15 13:55:03 +00:00
2013-12-03 12:26:19 +00:00
ini_entries = realloc (
ini_entries , ini_entries_len + ( ze_len + ( sizeof ( " zend_extension= \n " ) ) ) ) ;
memcpy ( & ini_entries [ ini_entries_len ] , " zend_extension= " , ( sizeof ( " zend_extension= \n " ) - 1 ) ) ;
ini_entries_len + = ( sizeof ( " zend_extension= " ) - 1 ) ;
memcpy ( & ini_entries [ ini_entries_len ] , ze , ze_len ) ;
ini_entries_len + = ze_len ;
memcpy ( & ini_entries [ ini_entries_len ] , " \n " , ( sizeof ( " \n " ) - 1 ) ) ;
2013-12-04 23:26:14 +00:00
2013-12-03 12:26:19 +00:00
free ( zend_extensions [ zend_extension ] ) ;
zend_extension + + ;
}
2013-12-15 13:55:03 +00:00
2013-12-03 12:26:19 +00:00
free ( zend_extensions ) ;
}
2013-11-12 13:07:35 +00:00
2013-11-18 01:18:12 +00:00
phpdbg - > ini_entries = ini_entries ;
2013-12-15 13:55:03 +00:00
2013-11-09 23:07:04 +00:00
if ( phpdbg - > startup ( phpdbg ) = = SUCCESS ) {
2015-07-24 19:28:40 +00:00
zend_mm_heap * mm_heap ;
2014-03-16 18:39:02 +00:00
# ifdef _WIN32
EXCEPTION_POINTERS * xp ;
__try {
# endif
2014-10-24 17:29:50 +00:00
void * ( * _malloc ) ( size_t ) ;
void ( * _free ) ( void * ) ;
void * ( * _realloc ) ( void * , size_t ) ;
2014-06-03 21:00:45 +00:00
2014-10-26 19:43:49 +00:00
/* set flags from command line */
PHPDBG_G ( flags ) = flags ;
2015-04-19 19:53:49 +00:00
if ( settings > ( zend_phpdbg_globals * ) 0x2 ) {
2014-10-26 19:43:49 +00:00
# ifdef ZTS
* ( ( zend_phpdbg_globals * ) ( * ( ( void * * * ) tsrm_ls ) ) [ TSRM_UNSHUFFLE_RSRC_ID ( phpdbg_globals_id ) ] ) = * settings ;
# else
phpdbg_globals = * settings ;
# endif
2015-07-24 15:17:09 +00:00
free ( settings ) ;
2014-09-28 00:57:12 +00:00
}
2014-10-26 19:43:49 +00:00
/* setup remote server if necessary */
2014-10-27 09:44:01 +00:00
if ( cleaning < = 0 & & listen > 0 ) {
2014-12-13 22:06:14 +00:00
server = phpdbg_open_socket ( address , listen ) ;
2015-07-18 18:37:44 +00:00
if ( - 1 > server | | phpdbg_remote_init ( address , listen , server , & socket , & stream ) = = FAILURE ) {
2014-10-26 19:43:49 +00:00
exit ( 0 ) ;
}
2014-09-28 00:57:12 +00:00
2014-10-12 17:53:05 +00:00
# ifndef _WIN32
2014-10-26 19:43:49 +00:00
sigaction ( SIGIO , & sigio_struct , NULL ) ;
2014-10-24 17:29:50 +00:00
# endif
2014-09-28 00:57:12 +00:00
2014-10-26 19:43:49 +00:00
/* set remote flag to stop service shutting down upon quit */
remote = 1 ;
}
2014-09-28 00:57:12 +00:00
2015-07-24 15:17:09 +00:00
mm_heap = zend_mm_get_heap ( ) ;
2014-10-24 17:29:50 +00:00
zend_mm_get_custom_handlers ( mm_heap , & _malloc , & _free , & _realloc ) ;
2014-06-03 21:00:45 +00:00
2015-07-24 15:17:09 +00:00
use_mm_wrappers = ! _malloc & & ! _realloc & & ! _free ;
if ( use_mm_wrappers ) {
2014-10-24 17:29:50 +00:00
_malloc = phpdbg_malloc_wrapper ;
_realloc = phpdbg_realloc_wrapper ;
_free = phpdbg_free_wrapper ;
2014-01-10 18:54:07 +00:00
}
2014-06-03 21:00:45 +00:00
2014-12-13 22:06:14 +00:00
phpdbg_init_list ( ) ;
2014-10-02 23:29:41 +00:00
2014-10-24 17:29:50 +00:00
PHPDBG_G ( original_free_function ) = _free ;
_free = phpdbg_watch_efree ;
zend_mm_set_custom_handlers ( mm_heap , _malloc , _free , _realloc ) ;
2014-01-10 18:54:07 +00:00
2014-12-13 22:06:14 +00:00
phpdbg_setup_watchpoints ( ) ;
2013-12-11 20:27:03 +00:00
2014-03-16 18:39:02 +00:00
# if defined(ZEND_SIGNALS) && !defined(_WIN32)
2013-12-11 20:27:03 +00:00
zend_try {
2014-12-13 22:06:14 +00:00
zend_signal_activate ( ) ;
2013-12-11 20:27:03 +00:00
} zend_end_try ( ) ;
# endif
2014-03-16 18:39:02 +00:00
# if defined(ZEND_SIGNALS) && !defined(_WIN32)
2014-12-13 22:06:14 +00:00
zend_try { zend_sigaction ( SIGSEGV , & signal_struct , & PHPDBG_G ( old_sigsegv_signal ) ) ; } zend_end_try ( ) ;
zend_try { zend_sigaction ( SIGBUS , & signal_struct , & PHPDBG_G ( old_sigsegv_signal ) ) ; } zend_end_try ( ) ;
2014-03-16 18:39:02 +00:00
# elif !defined(_WIN32)
2013-12-11 20:27:03 +00:00
sigaction ( SIGSEGV , & signal_struct , & PHPDBG_G ( old_sigsegv_signal ) ) ;
sigaction ( SIGBUS , & signal_struct , & PHPDBG_G ( old_sigsegv_signal ) ) ;
# endif
2014-09-10 13:53:40 +00:00
PHPDBG_G ( sapi_name_ptr ) = sapi_name ;
2015-07-20 14:18:30 +00:00
if ( exec ) { /* set execution context */
PHPDBG_G ( exec ) = phpdbg_resolve_path ( exec ) ;
PHPDBG_G ( exec_len ) = PHPDBG_G ( exec ) ? strlen ( PHPDBG_G ( exec ) ) : 0 ;
free ( exec ) ;
exec = NULL ;
}
2014-12-13 22:06:14 +00:00
php_output_activate ( ) ;
php_output_deactivate ( ) ;
2014-09-21 22:52:22 +00:00
2015-07-24 15:17:09 +00:00
if ( SG ( sapi_headers ) . mimetype ) {
efree ( SG ( sapi_headers ) . mimetype ) ;
SG ( sapi_headers ) . mimetype = NULL ;
}
2014-12-13 22:06:14 +00:00
php_output_activate ( ) ;
2014-09-21 22:52:22 +00:00
2015-07-24 15:17:09 +00:00
{
2014-04-13 10:07:38 +00:00
int i ;
2014-09-21 22:52:22 +00:00
SG ( request_info ) . argc = argc - php_optind + 1 ;
2014-04-13 10:07:38 +00:00
SG ( request_info ) . argv = emalloc ( SG ( request_info ) . argc * sizeof ( char * ) ) ;
for ( i = SG ( request_info ) . argc ; - - i ; ) {
SG ( request_info ) . argv [ i ] = estrdup ( argv [ php_optind - 1 + i ] ) ;
}
2015-07-20 14:18:30 +00:00
SG ( request_info ) . argv [ 0 ] = PHPDBG_G ( exec ) ? estrdup ( PHPDBG_G ( exec ) ) : estrdup ( " " ) ;
2015-07-24 15:17:09 +00:00
}
2014-04-14 13:45:15 +00:00
2015-07-24 15:17:09 +00:00
if ( php_request_startup ( ) = = FAILURE ) {
PUTS ( " Could not startup " ) ;
return 1 ;
2014-04-12 22:27:46 +00:00
}
2014-04-16 09:40:29 +00:00
2013-11-28 15:51:11 +00:00
/* do not install sigint handlers for remote consoles */
/* sending SIGINT then provides a decent way of shutting down the server */
2014-09-14 10:24:56 +00:00
# ifndef _WIN32
2014-09-15 07:58:14 +00:00
if ( listen < 0 ) {
2014-03-16 18:39:02 +00:00
# endif
2014-09-14 10:24:56 +00:00
# if defined(ZEND_SIGNALS) && !defined(_WIN32)
2014-12-13 22:06:14 +00:00
zend_try { zend_signal ( SIGINT , phpdbg_sigint_handler ) ; } zend_end_try ( ) ;
2014-09-14 10:24:56 +00:00
# else
2013-11-28 15:51:11 +00:00
signal ( SIGINT , phpdbg_sigint_handler ) ;
2014-09-14 10:24:56 +00:00
# endif
2013-12-01 08:55:37 +00:00
# ifndef _WIN32
2013-11-28 15:51:11 +00:00
}
2013-12-15 13:55:03 +00:00
2013-11-27 16:49:51 +00:00
/* setup io here */
2014-10-18 23:31:00 +00:00
if ( remote ) {
2013-11-27 16:49:51 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IS_REMOTE ;
2013-11-28 22:06:27 +00:00
2013-11-27 16:49:51 +00:00
signal ( SIGPIPE , SIG_IGN ) ;
}
2014-09-28 00:57:12 +00:00
PHPDBG_G ( io ) [ PHPDBG_STDIN ] . ptr = stdin ;
PHPDBG_G ( io ) [ PHPDBG_STDIN ] . fd = fileno ( stdin ) ;
PHPDBG_G ( io ) [ PHPDBG_STDOUT ] . ptr = stdout ;
PHPDBG_G ( io ) [ PHPDBG_STDOUT ] . fd = fileno ( stdout ) ;
2014-10-18 23:31:00 +00:00
# else
/* XXX this is a complete mess here with FILE/fd/SOCKET,
2015-01-03 09:22:58 +00:00
we should let only one to survive probably . Need
2014-10-18 23:31:00 +00:00
a clean separation whether it ' s a remote or local
prompt . And what is supposed to go as user interaction ,
error log , etc . */
if ( remote ) {
PHPDBG_G ( io ) [ PHPDBG_STDIN ] . ptr = stdin ;
PHPDBG_G ( io ) [ PHPDBG_STDIN ] . fd = socket ;
PHPDBG_G ( io ) [ PHPDBG_STDOUT ] . ptr = stdout ;
PHPDBG_G ( io ) [ PHPDBG_STDOUT ] . fd = socket ;
} else {
PHPDBG_G ( io ) [ PHPDBG_STDIN ] . ptr = stdin ;
PHPDBG_G ( io ) [ PHPDBG_STDIN ] . fd = fileno ( stdin ) ;
PHPDBG_G ( io ) [ PHPDBG_STDOUT ] . ptr = stdout ;
PHPDBG_G ( io ) [ PHPDBG_STDOUT ] . fd = fileno ( stdout ) ;
}
# endif
2014-09-28 00:57:12 +00:00
PHPDBG_G ( io ) [ PHPDBG_STDERR ] . ptr = stderr ;
PHPDBG_G ( io ) [ PHPDBG_STDERR ] . fd = fileno ( stderr ) ;
2013-12-15 13:55:03 +00:00
2014-09-21 02:17:19 +00:00
# ifndef _WIN32
PHPDBG_G ( php_stdiop_write ) = php_stream_stdio_ops . write ;
php_stream_stdio_ops . write = phpdbg_stdiop_write ;
# endif
2013-12-15 13:55:03 +00:00
2013-11-18 01:18:12 +00:00
if ( oplog_file ) { /* open oplog */
PHPDBG_G ( oplog ) = fopen ( oplog_file , " w+ " ) ;
if ( ! PHPDBG_G ( oplog ) ) {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " oplog " , " path= \" %s \" " , " Failed to open oplog %s " , oplog_file ) ;
2013-11-18 01:18:12 +00:00
}
free ( oplog_file ) ;
}
2013-11-12 13:07:35 +00:00
2013-11-24 19:34:18 +00:00
/* set default colors */
2014-12-13 22:06:14 +00:00
phpdbg_set_color_ex ( PHPDBG_COLOR_PROMPT , PHPDBG_STRL ( " white-bold " ) ) ;
phpdbg_set_color_ex ( PHPDBG_COLOR_ERROR , PHPDBG_STRL ( " red-bold " ) ) ;
phpdbg_set_color_ex ( PHPDBG_COLOR_NOTICE , PHPDBG_STRL ( " green " ) ) ;
2013-11-24 14:54:14 +00:00
2013-11-24 19:34:18 +00:00
/* set default prompt */
2014-12-13 22:06:14 +00:00
phpdbg_set_prompt ( PHPDBG_DEFAULT_PROMPT ) ;
2013-11-24 19:41:00 +00:00
2014-05-01 09:38:08 +00:00
/* Make stdin, stdout and stderr accessible from PHP scripts */
2014-12-13 22:06:14 +00:00
phpdbg_register_file_handles ( ) ;
2014-05-01 09:38:08 +00:00
2014-10-26 21:21:18 +00:00
if ( show_banner & & cleaning < 2 ) {
2013-11-20 14:35:25 +00:00
/* print blurb */
2014-12-13 22:06:14 +00:00
phpdbg_welcome ( cleaning = = 1 ) ;
2013-11-20 14:35:25 +00:00
}
2013-11-20 13:28:41 +00:00
2014-10-26 21:21:18 +00:00
cleaning = - 1 ;
2014-04-19 20:08:54 +00:00
2015-07-22 11:46:06 +00:00
if ( ext_stmt ) {
CG ( compiler_options ) | = ZEND_COMPILE_EXTENDED_INFO ;
}
2013-11-23 17:30:10 +00:00
/* initialize from file */
2014-01-17 21:08:35 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IS_INITIALIZING ;
2013-11-23 17:30:10 +00:00
zend_try {
2014-12-13 22:06:14 +00:00
phpdbg_init ( init_file , init_file_len , init_file_default ) ;
2014-10-28 16:20:21 +00:00
if ( bp_tmp ) {
PHPDBG_G ( flags ) | = PHPDBG_DISCARD_OUTPUT ;
2014-12-13 22:06:14 +00:00
phpdbg_string_init ( bp_tmp ) ;
2014-10-28 16:20:21 +00:00
free ( bp_tmp ) ;
bp_tmp = NULL ;
PHPDBG_G ( flags ) & = ~ PHPDBG_DISCARD_OUTPUT ;
}
2013-11-23 17:30:10 +00:00
} zend_end_try ( ) ;
2014-01-17 21:08:35 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_INITIALIZING ;
2015-01-03 09:22:58 +00:00
2014-01-17 21:08:35 +00:00
/* quit if init says so */
if ( PHPDBG_G ( flags ) & PHPDBG_IS_QUITTING ) {
goto phpdbg_out ;
}
2013-11-23 17:30:10 +00:00
2014-10-26 21:21:18 +00:00
/* auto compile */
if ( PHPDBG_G ( exec ) ) {
2015-07-18 18:37:44 +00:00
if ( settings | | phpdbg_startup_run > 0 ) {
2014-10-26 21:21:18 +00:00
PHPDBG_G ( flags ) | = PHPDBG_DISCARD_OUTPUT ;
}
2015-02-13 09:45:43 +00:00
zend_try {
phpdbg_compile ( ) ;
} zend_end_try ( ) ;
2014-10-26 21:21:18 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_DISCARD_OUTPUT ;
}
2015-04-19 19:53:49 +00:00
if ( settings = = ( void * ) 0x1 ) {
if ( PHPDBG_G ( ops ) ) {
phpdbg_print_opcodes ( print_opline_func ) ;
} else {
write ( PHPDBG_G ( io ) [ PHPDBG_STDERR ] . fd , ZEND_STRL ( " No opcodes could be compiled | No file specified or compilation failed? \n " ) ) ;
}
goto phpdbg_out ;
}
2015-07-20 18:41:07 +00:00
PG ( during_request_startup ) = 0 ;
2015-02-13 09:45:43 +00:00
phpdbg_fully_started = 1 ;
2014-03-16 18:39:02 +00:00
/* #ifndef for making compiler shutting up */
# ifndef _WIN32
2013-11-28 09:31:06 +00:00
phpdbg_interact :
2014-03-16 18:39:02 +00:00
# endif
2013-11-23 17:30:10 +00:00
/* phpdbg main() */
do {
zend_try {
2014-10-28 12:55:14 +00:00
if ( phpdbg_startup_run ) {
2015-06-16 21:36:20 +00:00
quit_immediately = phpdbg_startup_run > 1 ;
2014-10-28 16:20:21 +00:00
phpdbg_startup_run = 0 ;
2014-12-13 22:06:14 +00:00
PHPDBG_COMMAND_HANDLER ( run ) ( NULL ) ;
2014-10-28 16:20:21 +00:00
if ( quit_immediately ) {
2014-10-28 12:55:14 +00:00
/* if -r is on the command line more than once just quit */
EG ( bailout ) = __orig_bailout ; /* reset zend_try */
break ;
}
}
2015-07-24 15:17:09 +00:00
CG ( unclean_shutdown ) = 0 ;
2014-12-13 22:06:14 +00:00
phpdbg_interactive ( 1 ) ;
2013-11-23 17:30:10 +00:00
} zend_catch {
if ( ( PHPDBG_G ( flags ) & PHPDBG_IS_CLEANING ) ) {
2014-10-28 16:20:21 +00:00
char * bp_tmp_str ;
2014-10-26 21:21:18 +00:00
PHPDBG_G ( flags ) | = PHPDBG_DISCARD_OUTPUT ;
2014-12-13 22:06:14 +00:00
phpdbg_export_breakpoints_to_string ( & bp_tmp_str ) ;
2014-10-26 21:21:18 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_DISCARD_OUTPUT ;
2014-10-28 16:20:21 +00:00
if ( bp_tmp_str ) {
bp_tmp = strdup ( bp_tmp_str ) ;
efree ( bp_tmp_str ) ;
}
2013-11-23 17:30:10 +00:00
cleaning = 1 ;
2013-11-25 22:38:43 +00:00
} else {
cleaning = 0 ;
}
2013-12-15 13:55:03 +00:00
2013-11-28 22:06:27 +00:00
# ifndef _WIN32
2014-01-17 21:15:03 +00:00
if ( ! cleaning ) {
/* remote client disconnected */
if ( ( PHPDBG_G ( flags ) & PHPDBG_IS_DISCONNECTED ) ) {
2015-01-03 09:22:58 +00:00
2014-01-17 21:15:03 +00:00
if ( PHPDBG_G ( flags ) & PHPDBG_IS_REMOTE ) {
/* renegociate connections */
2014-12-13 22:06:14 +00:00
phpdbg_remote_init ( address , listen , server , & socket , & stream ) ;
2015-01-03 09:22:58 +00:00
2014-01-17 21:15:03 +00:00
/* set streams */
2014-09-15 07:58:14 +00:00
if ( stream ) {
2014-01-17 21:15:03 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_QUITTING ;
}
2015-01-03 09:22:58 +00:00
2014-01-17 21:15:03 +00:00
/* this must be forced */
CG ( unclean_shutdown ) = 0 ;
} else {
/* local consoles cannot disconnect, ignore EOF */
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_DISCONNECTED ;
}
2013-11-28 09:31:06 +00:00
}
}
2013-11-28 22:06:27 +00:00
# endif
2013-11-23 17:30:10 +00:00
} zend_end_try ( ) ;
2014-10-26 02:50:28 +00:00
} while ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_STOPPING ) ) ;
2014-10-26 19:43:49 +00:00
2013-11-28 22:06:27 +00:00
# ifndef _WIN32
2014-03-16 21:37:33 +00:00
phpdbg_out :
2014-01-13 08:14:04 +00:00
if ( ( PHPDBG_G ( flags ) & PHPDBG_IS_DISCONNECTED ) ) {
2013-11-28 09:31:06 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_DISCONNECTED ;
goto phpdbg_interact ;
}
2013-11-28 22:06:27 +00:00
# endif
2013-12-15 13:55:03 +00:00
2014-03-16 19:04:08 +00:00
# ifdef _WIN32
} __except ( phpdbg_exception_handler_win32 ( xp = GetExceptionInformation ( ) ) ) {
2014-11-20 20:00:07 +00:00
phpdbg_error ( " segfault " , " " , " Access violation (Segmentation fault) encountered \n trying to abort cleanly... " ) ;
2014-03-16 19:04:08 +00:00
}
2014-03-16 21:37:33 +00:00
phpdbg_out :
2014-03-16 19:04:08 +00:00
# endif
2014-09-21 22:52:22 +00:00
2014-10-26 21:21:18 +00:00
if ( cleaning < = 0 ) {
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_CLEANING ;
cleaning = - 1 ;
}
2014-04-13 10:07:38 +00:00
{
int i ;
/* free argv */
2015-07-20 14:18:30 +00:00
for ( i = SG ( request_info ) . argc ; i - - ; ) {
2014-04-13 10:07:38 +00:00
efree ( SG ( request_info ) . argv [ i ] ) ;
}
efree ( SG ( request_info ) . argv ) ;
2014-04-12 22:27:46 +00:00
}
2013-11-10 17:45:06 +00:00
if ( ini_entries ) {
2013-11-23 17:30:10 +00:00
free ( ini_entries ) ;
2013-11-10 17:45:06 +00:00
}
2013-11-23 16:45:03 +00:00
2013-11-23 15:11:09 +00:00
if ( ini_override ) {
free ( ini_override ) ;
}
2014-09-21 22:52:22 +00:00
2015-07-24 15:17:09 +00:00
/* In case we aborted during script execution, we may not reset CG(unclean_shutdown) */
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_RUNNING ) ) {
CG ( unclean_shutdown ) = PHPDBG_G ( unclean_eval ) ;
}
2013-11-09 23:07:04 +00:00
2014-10-26 19:43:49 +00:00
if ( ( PHPDBG_G ( flags ) & ( PHPDBG_IS_CLEANING | PHPDBG_IS_RUNNING ) ) = = PHPDBG_IS_CLEANING ) {
2014-12-13 22:06:14 +00:00
php_free_shutdown_functions ( ) ;
zend_objects_store_mark_destructed ( & EG ( objects_store ) ) ;
2014-10-26 19:43:49 +00:00
}
2015-07-24 15:17:09 +00:00
/* backup globals when cleaning */
if ( ( cleaning > 0 | | remote ) & & ! quit_immediately ) {
settings = calloc ( 1 , sizeof ( zend_phpdbg_globals ) ) ;
php_phpdbg_globals_ctor ( settings ) ;
2014-10-26 19:43:49 +00:00
2015-07-24 15:17:09 +00:00
if ( PHPDBG_G ( exec ) ) {
settings - > exec = zend_strndup ( PHPDBG_G ( exec ) , PHPDBG_G ( exec_len ) ) ;
settings - > exec_len = PHPDBG_G ( exec_len ) ;
}
settings - > oplog = PHPDBG_G ( oplog ) ;
settings - > prompt [ 0 ] = PHPDBG_G ( prompt ) [ 0 ] ;
settings - > prompt [ 1 ] = PHPDBG_G ( prompt ) [ 1 ] ;
memcpy ( settings - > colors , PHPDBG_G ( colors ) , sizeof ( settings - > colors ) ) ;
settings - > eol = PHPDBG_G ( eol ) ;
settings - > input_buflen = PHPDBG_G ( input_buflen ) ;
memcpy ( settings - > input_buffer , PHPDBG_G ( input_buffer ) , settings - > input_buflen ) ;
settings - > flags = PHPDBG_G ( flags ) & PHPDBG_PRESERVE_FLAGS_MASK ;
} else {
if ( PHPDBG_G ( prompt ) [ 0 ] ) {
free ( PHPDBG_G ( prompt ) [ 0 ] ) ;
}
if ( PHPDBG_G ( prompt ) [ 1 ] ) {
free ( PHPDBG_G ( prompt ) [ 1 ] ) ;
}
}
/* 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 ... */
2015-07-24 19:30:53 +00:00
* ( size_t * ) mm_heap = 0 ;
2015-07-24 15:17:09 +00:00
}
2014-10-26 19:43:49 +00:00
zend_try {
php_request_shutdown ( NULL ) ;
} zend_end_try ( ) ;
2015-07-24 15:17:09 +00:00
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_QUITTING ) & & PHPDBG_G ( in_execution ) ) {
2015-07-18 18:51:25 +00:00
if ( ! quit_immediately & & ! phpdbg_startup_run ) {
phpdbg_notice ( " stop " , " type= \" normal \" " , " Script ended normally " ) ;
2015-07-24 15:17:09 +00:00
cleaning + + ;
2015-07-18 18:51:25 +00:00
}
2014-10-26 19:43:49 +00:00
}
2014-12-13 22:06:14 +00:00
php_output_deactivate ( ) ;
2014-09-21 22:52:22 +00:00
2013-11-14 11:30:31 +00:00
zend_try {
2014-12-13 22:06:14 +00:00
php_module_shutdown ( ) ;
2013-11-14 11:30:31 +00:00
} zend_end_try ( ) ;
2013-11-09 23:07:04 +00:00
2015-07-24 15:17:09 +00:00
# ifndef _WIN32
/* 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
2014-03-16 19:04:08 +00:00
2015-07-24 15:17:09 +00:00
sapi_shutdown ( ) ;
2013-11-09 23:07:04 +00:00
}
2013-11-14 21:39:59 +00:00
2015-06-16 21:36:20 +00:00
if ( ( cleaning > 0 | | remote ) & & ! quit_immediately ) {
2015-07-20 14:18:30 +00:00
/* reset internal php_getopt state */
php_getopt ( - 1 , argv , OPTIONS , NULL , & php_optind , 0 , 0 ) ;
2013-11-25 22:19:21 +00:00
goto phpdbg_main ;
}
2014-09-21 22:52:22 +00:00
2013-11-25 23:02:54 +00:00
# ifdef ZTS
/* bugggy */
/* tsrm_shutdown(); */
# endif
2013-11-29 19:42:41 +00:00
# ifndef _WIN32
if ( address ) {
2013-12-15 13:55:03 +00:00
free ( address ) ;
2013-11-29 19:42:41 +00:00
}
# endif
2013-12-02 14:45:41 +00:00
2014-09-10 13:53:40 +00:00
if ( PHPDBG_G ( sapi_name_ptr ) ) {
free ( PHPDBG_G ( sapi_name_ptr ) ) ;
2013-12-02 14:45:41 +00:00
}
2014-09-10 13:53:40 +00:00
2013-11-09 23:07:04 +00:00
return 0 ;
2013-11-09 22:35:03 +00:00
} /* }}} */