2013-11-10 01:30:32 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| PHP Version 5 |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-01-17 22:09:07 +00:00
| Copyright ( c ) 1997 - 2014 The PHP Group |
2013-11-10 01:30:32 +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 . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Felipe Pena < felipe @ php . net > |
2013-11-10 10:44:42 +00:00
| Authors : Joe Watkins < joe . watkins @ live . co . uk > |
2013-11-22 19:06:31 +00:00
| Authors : Bob Weinand < bwoebi @ php . net > |
2013-11-10 01:30:32 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
# include <stdio.h>
# include <string.h>
# include "zend.h"
2013-11-10 13:01:46 +00:00
# include "zend_compile.h"
2013-11-10 10:44:42 +00:00
# include "phpdbg.h"
2014-09-09 00:15:33 +00:00
2013-11-10 10:44:42 +00:00
# include "phpdbg_help.h"
2013-11-12 08:26:11 +00:00
# include "phpdbg_print.h"
2013-11-17 15:42:34 +00:00
# include "phpdbg_info.h"
2013-11-13 14:22:01 +00:00
# include "phpdbg_break.h"
2013-11-10 18:06:41 +00:00
# include "phpdbg_bp.h"
2013-11-10 20:01:09 +00:00
# include "phpdbg_opcode.h"
2013-11-12 00:24:24 +00:00
# include "phpdbg_list.h"
2013-11-12 02:19:43 +00:00
# include "phpdbg_utils.h"
2013-11-17 21:01:41 +00:00
# include "phpdbg_prompt.h"
# include "phpdbg_cmd.h"
2013-11-24 14:54:14 +00:00
# include "phpdbg_set.h"
2013-12-08 18:29:15 +00:00
# include "phpdbg_frame.h"
2014-02-18 19:48:33 +00:00
# include "phpdbg_lexer.h"
# include "phpdbg_parser.h"
2014-09-10 13:53:40 +00:00
# include "phpdbg_wait.h"
ZEND_EXTERN_MODULE_GLOBALS ( phpdbg ) ;
2014-09-09 00:15:33 +00:00
# ifdef HAVE_LIBDL
# ifdef PHP_WIN32
# include "win32/param.h"
# include "win32/winutil.h"
# define GET_DL_ERROR() php_win_err()
# elif defined(NETWARE)
# include <sys/param.h>
# define GET_DL_ERROR() dlerror()
# else
# include <sys/param.h>
# define GET_DL_ERROR() DL_ERROR()
# endif
# endif
2014-02-18 19:48:33 +00:00
2013-11-13 21:15:45 +00:00
/* {{{ command declarations */
2013-11-21 19:47:31 +00:00
const phpdbg_command_t phpdbg_prompt_commands [ ] = {
2014-10-02 23:29:41 +00:00
PHPDBG_COMMAND_D ( exec , " set execution context " , ' e ' , NULL , " s " , 0 ) ,
PHPDBG_COMMAND_D ( step , " step through execution " , ' s ' , NULL , 0 , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( continue , " continue execution " , ' c ' , NULL , 0 , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( run , " attempt execution " , ' r ' , NULL , " |s " , 0 ) ,
2014-10-03 10:43:32 +00:00
PHPDBG_COMMAND_D ( ev , " evaluate some code " , 0 , NULL , " i " , PHPDBG_ASYNC_SAFE ) , /* restricted ASYNC_SAFE */
2014-10-02 23:29:41 +00:00
PHPDBG_COMMAND_D ( until , " continue past the current line " , ' u ' , NULL , 0 , 0 ) ,
PHPDBG_COMMAND_D ( finish , " continue past the end of the stack " , ' F ' , NULL , 0 , 0 ) ,
PHPDBG_COMMAND_D ( leave , " continue until the end of the stack " , ' L ' , NULL , 0 , 0 ) ,
PHPDBG_COMMAND_D ( print , " print something " , ' p ' , phpdbg_print_commands , 0 , 0 ) ,
PHPDBG_COMMAND_D ( break , " set breakpoint " , ' b ' , phpdbg_break_commands , " |*c " , 0 ) ,
PHPDBG_COMMAND_D ( back , " show trace " , ' t ' , NULL , " |n " , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( frame , " switch to a frame " , ' f ' , NULL , " |n " , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( list , " lists some code " , ' l ' , phpdbg_list_commands , " * " , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( info , " displays some informations " , ' i ' , phpdbg_info_commands , " s " , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( clean , " clean the execution environment " , ' X ' , NULL , 0 , 0 ) ,
PHPDBG_COMMAND_D ( clear , " clear breakpoints " , ' C ' , NULL , 0 , 0 ) ,
PHPDBG_COMMAND_D ( help , " show help menu " , ' h ' , phpdbg_help_commands , " |s " , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( set , " set phpdbg configuration " , ' S ' , phpdbg_set_commands , " s " , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( register , " register a function " , ' R ' , NULL , " s " , 0 ) ,
PHPDBG_COMMAND_D ( source , " execute a phpdbginit " , ' < ' , NULL , " s " , 0 ) ,
PHPDBG_COMMAND_D ( export , " export breaks to a .phpdbginit script " , ' > ' , NULL , " s " , PHPDBG_ASYNC_SAFE ) ,
PHPDBG_COMMAND_D ( sh , " shell a command " , 0 , NULL , " i " , 0 ) ,
PHPDBG_COMMAND_D ( quit , " exit phpdbg " , ' q ' , NULL , 0 , PHPDBG_ASYNC_SAFE ) ,
2014-10-04 21:21:34 +00:00
PHPDBG_COMMAND_D ( wait , " wait for other process " , ' W ' , NULL , 0 , 0 ) ,
2014-10-02 23:29:41 +00:00
PHPDBG_COMMAND_D ( watch , " set watchpoint " , ' w ' , phpdbg_watch_commands , " |ss " , 0 ) ,
2013-11-17 21:01:41 +00:00
PHPDBG_END_COMMAND
2013-11-13 21:15:45 +00:00
} ; /* }}} */
2013-11-10 10:44:42 +00:00
2014-02-19 08:33:54 +00:00
static inline int phpdbg_call_register ( phpdbg_param_t * stack TSRMLS_DC ) /* { { { */
2013-12-06 20:18:44 +00:00
{
2014-02-21 20:42:15 +00:00
phpdbg_param_t * name = NULL ;
2013-12-06 20:18:44 +00:00
2014-02-21 20:42:15 +00:00
if ( stack - > type = = STACK_PARAM ) {
name = stack - > next ;
2014-09-21 02:17:19 +00:00
2014-02-21 21:31:01 +00:00
if ( ! name | | name - > type ! = STR_PARAM ) {
return FAILURE ;
}
2014-09-21 02:17:19 +00:00
if ( zend_hash_exists ( & PHPDBG_G ( registered ) , name - > str , name - > len + 1 ) ) {
2014-02-19 08:33:54 +00:00
zval fname , * fretval ;
zend_fcall_info fci ;
2014-02-24 17:11:09 +00:00
ZVAL_STRINGL ( & fname , name - > str , name - > len , 1 ) ;
2014-02-19 08:33:54 +00:00
memset ( & fci , 0 , sizeof ( zend_fcall_info ) ) ;
fci . size = sizeof ( zend_fcall_info ) ;
fci . function_table = & PHPDBG_G ( registered ) ;
fci . function_name = & fname ;
fci . symbol_table = EG ( active_symbol_table ) ;
fci . object_ptr = NULL ;
fci . retval_ptr_ptr = & fretval ;
fci . no_separation = 1 ;
2014-02-21 20:42:15 +00:00
if ( name - > next ) {
2014-02-19 08:33:54 +00:00
zval params ;
2014-02-21 20:42:15 +00:00
phpdbg_param_t * next = name - > next ;
2014-09-21 02:17:19 +00:00
2014-02-19 08:33:54 +00:00
array_init ( & params ) ;
2014-02-24 22:30:46 +00:00
while ( next ) {
char * buffered = NULL ;
2014-09-21 02:17:19 +00:00
2014-02-19 08:33:54 +00:00
switch ( next - > type ) {
2014-02-24 22:30:46 +00:00
case OP_PARAM :
case COND_PARAM :
2014-02-19 08:33:54 +00:00
case STR_PARAM :
2014-09-21 02:17:19 +00:00
add_next_index_stringl ( & params , next - > str , next - > len , 1 ) ;
2014-02-19 08:33:54 +00:00
break ;
2014-09-21 02:17:19 +00:00
2014-02-19 08:33:54 +00:00
case NUMERIC_PARAM :
add_next_index_long ( & params , next - > num ) ;
break ;
2014-09-21 02:17:19 +00:00
2014-02-24 22:30:46 +00:00
case METHOD_PARAM :
2014-04-13 07:43:19 +00:00
spprintf ( & buffered , 0 , " %s::%s " ,
next - > method . class , next - > method . name ) ;
2014-02-24 22:30:46 +00:00
add_next_index_string ( & params , buffered , 0 ) ;
break ;
2014-09-21 02:17:19 +00:00
2014-02-24 22:30:46 +00:00
case NUMERIC_METHOD_PARAM :
2014-04-13 07:43:19 +00:00
spprintf ( & buffered , 0 , " %s::%s#%ld " ,
next - > method . class , next - > method . name , next - > num ) ;
2014-02-24 22:30:46 +00:00
add_next_index_string ( & params , buffered , 0 ) ;
break ;
2014-09-21 02:17:19 +00:00
2014-02-24 22:30:46 +00:00
case NUMERIC_FUNCTION_PARAM :
2014-04-13 07:43:19 +00:00
spprintf ( & buffered , 0 , " %s#%ld " ,
next - > str , next - > num ) ;
2014-02-24 22:30:46 +00:00
add_next_index_string ( & params , buffered , 0 ) ;
break ;
2014-09-21 02:17:19 +00:00
2014-02-24 22:30:46 +00:00
case FILE_PARAM :
2014-04-13 07:43:19 +00:00
spprintf ( & buffered , 0 , " %s:%ld " ,
next - > file . name , next - > file . line ) ;
2014-02-24 22:30:46 +00:00
add_next_index_string ( & params , buffered , 0 ) ;
break ;
2014-09-21 02:17:19 +00:00
2014-02-24 22:30:46 +00:00
case NUMERIC_FILE_PARAM :
2014-04-13 07:43:19 +00:00
spprintf ( & buffered , 0 , " %s:#%ld " ,
next - > file . name , next - > file . line ) ;
2014-02-24 22:30:46 +00:00
add_next_index_string ( & params , buffered , 0 ) ;
break ;
2014-09-21 02:17:19 +00:00
2014-02-19 08:33:54 +00:00
default : {
/* not yet */
}
}
2014-09-21 02:17:19 +00:00
next = next - > next ;
2014-02-19 08:33:54 +00:00
}
2013-12-06 20:18:44 +00:00
2014-02-19 08:33:54 +00:00
zend_fcall_info_args ( & fci , & params TSRMLS_CC ) ;
} else {
fci . params = NULL ;
fci . param_count = 0 ;
2013-12-06 20:18:44 +00:00
}
2014-09-21 22:52:22 +00:00
phpdbg_activate_err_buf ( 0 TSRMLS_CC ) ;
phpdbg_free_err_buf ( TSRMLS_C ) ;
2014-09-21 02:17:19 +00:00
phpdbg_debug ( " created %d params from arguments " , fci . param_count ) ;
2013-12-06 20:18:44 +00:00
2014-02-19 08:33:54 +00:00
zend_call_function ( & fci , NULL TSRMLS_CC ) ;
2013-12-06 20:18:44 +00:00
2014-02-19 08:33:54 +00:00
if ( fretval ) {
2014-09-21 02:17:19 +00:00
zend_print_zval_r ( fretval , 0 TSRMLS_CC ) ;
phpdbg_out ( " \n " ) ;
2014-02-19 08:33:54 +00:00
}
2013-12-06 20:18:44 +00:00
2014-02-19 08:33:54 +00:00
zval_dtor ( & fname ) ;
2013-12-06 20:18:44 +00:00
2014-02-19 08:33:54 +00:00
return SUCCESS ;
2014-09-21 02:17:19 +00:00
}
2013-12-06 20:18:44 +00:00
}
return FAILURE ;
} /* }}} */
2013-12-08 18:07:49 +00:00
void phpdbg_try_file_init ( char * init_file , size_t init_file_len , zend_bool free_init TSRMLS_DC ) /* { { { */
{
2013-11-25 12:19:01 +00:00
struct stat sb ;
2014-09-21 02:17:19 +00:00
2013-11-25 12:19:01 +00:00
if ( init_file & & VCWD_STAT ( init_file , & sb ) ! = - 1 ) {
2013-11-17 12:07:01 +00:00
FILE * fp = fopen ( init_file , " r " ) ;
if ( fp ) {
int line = 1 ;
char cmd [ PHPDBG_MAX_CMD ] ;
size_t cmd_len = 0L ;
char * code = NULL ;
size_t code_len = 0L ;
zend_bool in_code = 0 ;
while ( fgets ( cmd , PHPDBG_MAX_CMD , fp ) ! = NULL ) {
cmd_len = strlen ( cmd ) - 1 ;
2013-11-23 15:35:30 +00:00
while ( cmd_len > 0L & & isspace ( cmd [ cmd_len - 1 ] ) )
2013-11-17 12:07:01 +00:00
cmd_len - - ;
cmd [ cmd_len ] = ' \0 ' ;
if ( * cmd & & cmd_len > 0L & & cmd [ 0 ] ! = ' # ' ) {
if ( cmd_len = = 2 ) {
if ( memcmp ( cmd , " <: " , sizeof ( " <: " ) - 1 ) = = SUCCESS ) {
in_code = 1 ;
goto next_line ;
} else {
if ( memcmp ( cmd , " :> " , sizeof ( " :> " ) - 1 ) = = SUCCESS ) {
in_code = 0 ;
code [ code_len ] = ' \0 ' ;
{
2014-09-21 02:17:19 +00:00
zend_eval_stringl ( code , code_len , NULL , " phpdbginit code " TSRMLS_CC ) ;
2013-11-17 12:07:01 +00:00
}
free ( code ) ;
code = NULL ;
goto next_line ;
}
}
}
2013-11-16 10:59:50 +00:00
2013-11-17 12:07:01 +00:00
if ( in_code ) {
if ( code = = NULL ) {
2013-11-18 20:20:07 +00:00
code = malloc ( cmd_len + 1 ) ;
} else code = realloc ( code , code_len + cmd_len + 1 ) ;
2013-11-17 12:07:01 +00:00
if ( code ) {
memcpy (
& code [ code_len ] , cmd , cmd_len ) ;
code_len + = cmd_len ;
}
goto next_line ;
}
2013-11-20 12:10:27 +00:00
2013-11-20 10:04:05 +00:00
{
2014-02-21 20:42:15 +00:00
char * input = phpdbg_read_input ( cmd TSRMLS_CC ) ;
phpdbg_param_t stack ;
phpdbg_init_param ( & stack , STACK_PARAM ) ;
2013-11-20 12:10:27 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_activate_err_buf ( 1 TSRMLS_CC ) ;
2014-06-08 22:02:10 +00:00
if ( phpdbg_do_parse ( & stack , input TSRMLS_CC ) < = 0 ) {
2014-10-07 11:08:30 +00:00
switch ( phpdbg_stack_execute ( & stack , 1 /* allow_async_unsafe == 1 */ TSRMLS_CC ) ) {
2014-02-21 20:42:15 +00:00
case FAILURE :
2014-09-21 02:17:19 +00:00
phpdbg_activate_err_buf ( 0 TSRMLS_CC ) ;
if ( phpdbg_call_register ( & stack TSRMLS_CC ) = = FAILURE ) {
phpdbg_output_err_buf ( " initfailure " , " %b file= \" %s \" line= \" %d \" input= \" %s \" " , " Unrecognized command in %s:%d: %s, %b! " TSRMLS_CC , init_file , line , input ) ;
}
2014-02-21 20:42:15 +00:00
break ;
}
}
2014-06-08 20:34:30 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_activate_err_buf ( 0 TSRMLS_CC ) ;
phpdbg_free_err_buf ( TSRMLS_C ) ;
2014-06-08 20:34:30 +00:00
2014-02-21 20:42:15 +00:00
phpdbg_stack_free ( & stack ) ;
2013-11-20 10:04:05 +00:00
phpdbg_destroy_input ( & input TSRMLS_CC ) ;
2013-11-17 12:07:01 +00:00
}
}
2013-11-15 14:53:40 +00:00
next_line :
2013-11-17 12:07:01 +00:00
line + + ;
}
2013-11-16 10:59:50 +00:00
2013-11-17 12:07:01 +00:00
if ( code ) {
free ( code ) ;
}
2013-11-16 10:59:50 +00:00
2013-11-17 12:07:01 +00:00
fclose ( fp ) ;
} else {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " initfailure " , " type= \" openfile \" file= \" %s \" " , " Failed to open %s for initialization " , init_file ) ;
2013-11-17 12:07:01 +00:00
}
2013-11-16 10:59:50 +00:00
2013-11-25 12:19:01 +00:00
if ( free_init ) {
2013-12-04 23:26:14 +00:00
free ( init_file ) ;
2013-11-17 12:07:01 +00:00
}
}
2013-11-14 14:14:13 +00:00
} /* }}} */
2013-11-10 11:03:29 +00:00
2013-11-25 12:19:01 +00:00
void phpdbg_init ( char * init_file , size_t init_file_len , zend_bool use_default TSRMLS_DC ) /* { { { */
{
if ( ! init_file & & use_default ) {
char * scan_dir = getenv ( " PHP_INI_SCAN_DIR " ) ;
2013-11-25 16:15:51 +00:00
int i ;
2013-11-25 12:19:01 +00:00
2013-11-26 08:26:13 +00:00
phpdbg_try_file_init ( PHPDBG_STRL ( PHP_CONFIG_FILE_PATH " / " PHPDBG_INIT_FILENAME ) , 0 TSRMLS_CC ) ;
2013-11-25 12:19:01 +00:00
if ( ! scan_dir ) {
scan_dir = PHP_CONFIG_FILE_SCAN_DIR ;
}
2013-11-25 16:15:51 +00:00
while ( * scan_dir ! = 0 ) {
i = 0 ;
while ( scan_dir [ i ] ! = ' : ' ) {
if ( scan_dir [ i + + ] = = 0 ) {
i = - 1 ;
break ;
}
}
if ( i ! = - 1 ) {
scan_dir [ i ] = 0 ;
}
2013-12-08 18:07:49 +00:00
2014-09-21 02:17:19 +00:00
asprintf ( & init_file , " %s/%s " , scan_dir , PHPDBG_INIT_FILENAME ) ;
2013-11-25 16:15:51 +00:00
phpdbg_try_file_init ( init_file , strlen ( init_file ) , 1 TSRMLS_CC ) ;
if ( i = = - 1 ) {
break ;
}
scan_dir + = i + 1 ;
}
2013-11-25 12:19:01 +00:00
2013-11-26 08:26:13 +00:00
phpdbg_try_file_init ( PHPDBG_STRL ( PHPDBG_INIT_FILENAME ) , 0 TSRMLS_CC ) ;
2013-11-25 12:19:01 +00:00
} else {
phpdbg_try_file_init ( init_file , init_file_len , 1 TSRMLS_CC ) ;
}
}
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( exec ) /* {{{ */
2013-11-10 18:29:05 +00:00
{
2014-02-21 20:42:15 +00:00
struct stat sb ;
2013-11-17 12:07:01 +00:00
2014-02-21 20:42:15 +00:00
if ( VCWD_STAT ( param - > str , & sb ) ! = FAILURE ) {
if ( sb . st_mode & ( S_IFREG | S_IFLNK ) ) {
char * res = phpdbg_resolve_path ( param - > str TSRMLS_CC ) ;
size_t res_len = strlen ( res ) ;
2013-11-23 15:34:36 +00:00
2014-02-21 20:42:15 +00:00
if ( ( res_len ! = PHPDBG_G ( exec_len ) ) | | ( memcmp ( res , PHPDBG_G ( exec ) , res_len ) ! = SUCCESS ) ) {
2013-11-23 15:34:36 +00:00
2014-02-21 20:42:15 +00:00
if ( PHPDBG_G ( exec ) ) {
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " exec " , " type= \" unset \" context= \" %s \" " , " Unsetting old execution context: %s " , PHPDBG_G ( exec ) ) ;
2014-02-21 20:42:15 +00:00
efree ( PHPDBG_G ( exec ) ) ;
PHPDBG_G ( exec ) = NULL ;
PHPDBG_G ( exec_len ) = 0L ;
}
2013-11-23 13:04:27 +00:00
2014-02-21 20:42:15 +00:00
if ( PHPDBG_G ( ops ) ) {
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " exec " , " type= \" unsetops \" " , " Destroying compiled opcodes " ) ;
2014-02-21 20:42:15 +00:00
phpdbg_clean ( 0 TSRMLS_CC ) ;
}
2013-11-17 12:07:01 +00:00
2014-02-21 20:42:15 +00:00
PHPDBG_G ( exec ) = res ;
PHPDBG_G ( exec_len ) = res_len ;
2014-09-25 13:28:25 +00:00
2014-10-04 21:30:57 +00:00
VCWD_CHDIR_FILE ( res ) ;
2014-04-13 07:09:53 +00:00
* SG ( request_info ) . argv = PHPDBG_G ( exec ) ;
php_hash_environment ( TSRMLS_C ) ;
2013-11-17 12:07:01 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " exec " , " type= \" set \" context= \" %s \" " , " Set execution context: %s " , PHPDBG_G ( exec ) ) ;
2014-04-20 10:54:50 +00:00
if ( phpdbg_compile ( TSRMLS_C ) = = FAILURE ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " compile " , " type= \" compilefailure \" context= \" %s \" " , " Failed to compile %s " , PHPDBG_G ( exec ) ) ;
2014-04-20 10:54:50 +00:00
}
2013-11-17 12:07:01 +00:00
} else {
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " exec " , " type= \" unchanged \" " , " Execution context not changed " ) ;
2013-11-17 12:07:01 +00:00
}
2014-02-21 20:42:15 +00:00
} else {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " exec " , " type= \" invalid \" context= \" %s \" " , " Cannot use %s as execution context, not a valid file or symlink " , param - > str ) ;
2014-02-21 20:42:15 +00:00
}
} else {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " exec " , " type= \" notfound \" context= \" %s \" " , " Cannot stat %s, ensure the file exists " , param - > str ) ;
2013-11-17 12:07:01 +00:00
}
2013-11-10 18:29:05 +00:00
return SUCCESS ;
2013-11-10 11:35:59 +00:00
} /* }}} */
2013-11-17 09:30:44 +00:00
int phpdbg_compile ( TSRMLS_D ) /* { { { */
2013-11-10 18:29:05 +00:00
{
zend_file_handle fh ;
2013-11-10 13:01:46 +00:00
2014-04-19 20:22:09 +00:00
if ( ! PHPDBG_G ( exec ) ) {
2014-09-25 20:01:31 +00:00
phpdbg_error ( " inactive " , " type= \" nocontext \" " , " No execution context " ) ;
2014-04-19 20:22:09 +00:00
return SUCCESS ;
}
2013-11-13 21:43:54 +00:00
if ( EG ( in_execution ) ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" isrunning \" " , " Cannot compile while in execution " ) ;
2013-11-13 21:43:54 +00:00
return FAILURE ;
}
2013-11-11 22:02:34 +00:00
2014-09-21 02:17:19 +00:00
if ( php_stream_open_for_zend_ex ( PHPDBG_G ( exec ) , & fh , USE_PATH | STREAM_OPEN_FOR_INCLUDE TSRMLS_CC ) = = SUCCESS ) {
2013-11-12 22:39:39 +00:00
2013-11-13 21:43:54 +00:00
PHPDBG_G ( ops ) = zend_compile_file ( & fh , ZEND_INCLUDE TSRMLS_CC ) ;
zend_destroy_file_handle ( & fh TSRMLS_CC ) ;
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " compile " , " context= \" %s \" " , " Successful compilation of %s " , PHPDBG_G ( exec ) ) ;
2013-11-13 21:43:54 +00:00
return SUCCESS ;
2013-11-10 21:07:29 +00:00
} else {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " compile " , " type= \" openfailure \" context= \" %s \" " , " Could not open file %s " , PHPDBG_G ( exec ) ) ;
2013-11-10 21:07:29 +00:00
}
2013-11-10 21:38:58 +00:00
2013-11-10 18:29:05 +00:00
return FAILURE ;
2013-11-10 11:03:29 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( step ) /* {{{ */
2013-11-10 18:29:05 +00:00
{
2014-04-21 21:00:21 +00:00
if ( EG ( in_execution ) ) {
PHPDBG_G ( flags ) | = PHPDBG_IS_STEPPING ;
}
2013-11-12 02:19:43 +00:00
2014-04-20 14:47:24 +00:00
return PHPDBG_NEXT ;
2013-11-10 14:28:14 +00:00
} /* }}} */
2014-04-20 16:10:52 +00:00
PHPDBG_COMMAND ( continue ) /* {{{ */
2013-11-10 18:29:05 +00:00
{
return PHPDBG_NEXT ;
2013-11-10 15:32:24 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( until ) /* {{{ */
2013-11-16 10:59:50 +00:00
{
2013-11-18 01:44:46 +00:00
if ( ! EG ( in_execution ) ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" noexec \" " , " Not executing " ) ;
2013-11-18 01:44:46 +00:00
return SUCCESS ;
}
2013-11-18 14:09:25 +00:00
2013-11-18 01:44:46 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IN_UNTIL ;
{
2014-09-21 02:17:19 +00:00
uint32_t next = 0 , self = ( EG ( current_execute_data ) - > opline - EG ( active_op_array ) - > opcodes ) ;
2013-11-18 01:44:46 +00:00
zend_op * opline = & EG ( active_op_array ) - > opcodes [ self ] ;
2013-11-18 14:09:25 +00:00
2013-11-18 01:44:46 +00:00
for ( next = self ; next < EG ( active_op_array ) - > last ; next + + ) {
if ( EG ( active_op_array ) - > opcodes [ next ] . lineno ! = opline - > lineno ) {
2014-09-21 02:17:19 +00:00
zend_hash_index_update ( & PHPDBG_G ( seek ) , ( zend_ulong ) & EG ( active_op_array ) - > opcodes [ next ] , & EG ( active_op_array ) - > opcodes [ next ] , sizeof ( zend_op ) , NULL ) ;
2013-11-18 01:44:46 +00:00
break ;
}
}
}
2013-11-18 14:09:25 +00:00
2013-11-16 10:59:50 +00:00
return PHPDBG_UNTIL ;
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( finish ) /* {{{ */
2013-11-17 13:59:21 +00:00
{
2013-11-18 01:44:46 +00:00
if ( ! EG ( in_execution ) ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" noexec \" " , " Not executing " ) ;
2013-11-18 01:44:46 +00:00
return SUCCESS ;
}
2013-11-18 14:09:25 +00:00
2013-11-18 01:44:46 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IN_FINISH ;
2013-11-18 02:14:17 +00:00
{
2014-09-21 02:17:19 +00:00
uint32_t next = 0 , self = ( EG ( current_execute_data ) - > opline - EG ( active_op_array ) - > opcodes ) ;
2013-11-18 14:09:25 +00:00
2013-11-18 02:14:17 +00:00
for ( next = self ; next < EG ( active_op_array ) - > last ; next + + ) {
2013-11-18 03:18:37 +00:00
switch ( EG ( active_op_array ) - > opcodes [ next ] . opcode ) {
case ZEND_RETURN :
case ZEND_THROW :
case ZEND_EXIT :
2013-11-18 10:32:33 +00:00
# ifdef ZEND_YIELD
case ZEND_YIELD :
# endif
2014-09-21 02:17:19 +00:00
zend_hash_index_update ( & PHPDBG_G ( seek ) , ( zend_ulong ) & EG ( active_op_array ) - > opcodes [ next ] , & EG ( active_op_array ) - > opcodes [ next ] , sizeof ( zend_op ) , NULL ) ;
2013-11-18 02:14:17 +00:00
break ;
}
}
}
2013-11-18 14:09:25 +00:00
2013-11-17 13:59:21 +00:00
return PHPDBG_FINISH ;
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( leave ) /* {{{ */
2013-11-17 15:39:23 +00:00
{
2013-11-18 01:44:46 +00:00
if ( ! EG ( in_execution ) ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" noexec \" " , " Not executing " ) ;
2013-11-18 01:44:46 +00:00
return SUCCESS ;
}
2013-11-18 14:09:25 +00:00
2013-11-18 01:44:46 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IN_LEAVE ;
2013-11-18 02:14:17 +00:00
{
2014-09-21 02:17:19 +00:00
uint32_t next = 0 , self = ( EG ( current_execute_data ) - > opline - EG ( active_op_array ) - > opcodes ) ;
2013-11-18 14:09:25 +00:00
2013-11-18 02:14:17 +00:00
for ( next = self ; next < EG ( active_op_array ) - > last ; next + + ) {
2013-11-18 03:18:37 +00:00
switch ( EG ( active_op_array ) - > opcodes [ next ] . opcode ) {
case ZEND_RETURN :
case ZEND_THROW :
case ZEND_EXIT :
2013-11-18 10:32:33 +00:00
# ifdef ZEND_YIELD
case ZEND_YIELD :
# endif
2014-09-21 02:17:19 +00:00
zend_hash_index_update ( & PHPDBG_G ( seek ) , ( zend_ulong ) & EG ( active_op_array ) - > opcodes [ next ] , & EG ( active_op_array ) - > opcodes [ next ] , sizeof ( zend_op ) , NULL ) ;
2013-11-18 02:14:17 +00:00
break ;
}
}
}
2013-11-18 14:09:25 +00:00
2013-11-17 15:39:23 +00:00
return PHPDBG_LEAVE ;
} /* }}} */
2013-11-22 17:27:55 +00:00
PHPDBG_COMMAND ( frame ) /* {{{ */
{
2014-02-21 20:42:15 +00:00
if ( ! param ) {
2014-09-25 13:28:25 +00:00
phpdbg_notice ( " frame " , " id= \" %d \" " , " Currently in frame #%d " , PHPDBG_G ( frame ) . num ) ;
2014-09-21 02:17:19 +00:00
} else {
phpdbg_switch_frame ( param - > num TSRMLS_CC ) ;
}
2013-11-22 18:24:27 +00:00
return SUCCESS ;
2013-11-22 17:27:55 +00:00
} /* }}} */
2013-11-18 17:00:26 +00:00
static inline void phpdbg_handle_exception ( TSRMLS_D ) /* }}} */
{
zend_fcall_info fci ;
2014-09-21 02:17:19 +00:00
zval fname , * trace , exception ;
2013-11-18 17:00:26 +00:00
/* get filename and linenumber before unsetting exception */
const char * filename = zend_get_executed_filename ( TSRMLS_C ) ;
2014-09-21 02:17:19 +00:00
uint32_t lineno = zend_get_executed_lineno ( TSRMLS_C ) ;
2013-11-18 17:00:26 +00:00
/* copy exception */
exception = * EG ( exception ) ;
zval_copy_ctor ( & exception ) ;
EG ( exception ) = NULL ;
/* call __toString */
ZVAL_STRINGL ( & fname , " __tostring " , sizeof ( " __tostring " ) - 1 , 1 ) ;
fci . size = sizeof ( fci ) ;
fci . function_table = & Z_OBJCE ( exception ) - > function_table ;
fci . function_name = & fname ;
fci . symbol_table = NULL ;
fci . object_ptr = & exception ;
fci . retval_ptr_ptr = & trace ;
fci . param_count = 0 ;
fci . params = NULL ;
fci . no_separation = 1 ;
zend_call_function ( & fci , NULL TSRMLS_CC ) ;
2013-11-19 01:30:57 +00:00
2013-11-18 17:00:26 +00:00
if ( trace ) {
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " exception " , " name= \" %s \" trace= \" %s \" " , " Uncaught %s! \n %.*s " , Z_OBJCE ( exception ) - > name , Z_STRLEN_P ( trace ) , Z_STRVAL_P ( trace ) ) ;
2013-11-18 17:00:26 +00:00
zval_ptr_dtor ( & trace ) ;
2014-09-21 02:17:19 +00:00
} else {
phpdbg_error ( " exception " , " name= \" %s \" " " Uncaught %s! " , Z_OBJCE ( exception ) - > name ) ;
2013-11-18 17:00:26 +00:00
}
2013-11-19 01:30:57 +00:00
2013-11-18 17:00:26 +00:00
/* output useful information about address */
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " exception " , " opline= \" %p \" file= \" %s \" line= \" %u \" " , " Stack entered at %p in %s on line %u " , EG ( active_op_array ) - > opcodes , filename , lineno ) ;
2013-11-19 01:30:57 +00:00
2013-11-18 17:00:26 +00:00
zval_dtor ( & fname ) ;
zval_dtor ( & exception ) ;
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( run ) /* {{{ */
2013-11-10 18:29:05 +00:00
{
2013-11-17 12:07:01 +00:00
if ( EG ( in_execution ) ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" isrunning \" " , " Cannot start another execution while one is in progress " ) ;
2013-11-26 10:02:58 +00:00
return SUCCESS ;
2013-11-17 12:07:01 +00:00
}
2013-11-11 22:02:34 +00:00
2013-11-10 18:29:05 +00:00
if ( PHPDBG_G ( ops ) | | PHPDBG_G ( exec ) ) {
2013-11-13 14:22:01 +00:00
zend_op * * orig_opline = EG ( opline_ptr ) ;
zend_op_array * orig_op_array = EG ( active_op_array ) ;
zval * * orig_retval_ptr = EG ( return_value_ptr_ptr ) ;
2014-01-17 21:08:35 +00:00
zend_bool restore = 1 ;
2014-02-02 15:16:01 +00:00
zend_execute_data * ex = EG ( current_execute_data ) ;
2014-09-25 13:28:25 +00:00
2013-11-10 18:29:05 +00:00
if ( ! PHPDBG_G ( ops ) ) {
if ( phpdbg_compile ( TSRMLS_C ) = = FAILURE ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " compile " , " type= \" compilefailure \" context= \" %s \" " , " Failed to compile %s, cannot run " , PHPDBG_G ( exec ) ) ;
2013-11-16 23:35:11 +00:00
goto out ;
2013-11-10 18:29:05 +00:00
}
}
2013-11-10 15:21:20 +00:00
2013-11-10 18:29:05 +00:00
EG ( active_op_array ) = PHPDBG_G ( ops ) ;
EG ( return_value_ptr_ptr ) = & PHPDBG_G ( retval ) ;
2013-11-26 10:02:58 +00:00
if ( ! EG ( active_symbol_table ) ) {
zend_rebuild_symbol_table ( TSRMLS_C ) ;
}
2013-11-17 21:01:41 +00:00
2014-01-18 23:48:53 +00:00
/* clean up from last execution */
if ( ex & & ex - > symbol_table ) {
zend_hash_clean ( ex - > symbol_table ) ;
}
2013-11-18 03:18:37 +00:00
/* clean seek state */
PHPDBG_G ( flags ) & = ~ PHPDBG_SEEK_MASK ;
zend_hash_clean (
& PHPDBG_G ( seek ) ) ;
2013-11-18 14:09:25 +00:00
2013-11-27 13:15:52 +00:00
/* reset hit counters */
phpdbg_reset_breakpoints ( TSRMLS_C ) ;
2014-04-16 18:55:02 +00:00
if ( param & & param - > type ! = EMPTY_PARAM & & param - > len ! = 0 ) {
2014-04-12 22:27:46 +00:00
char * * argv = emalloc ( 5 * sizeof ( char * ) ) ;
int argc = 0 ;
int i ;
2014-04-13 07:43:19 +00:00
char * argv_str = strtok ( param - > str , " " ) ;
2014-09-25 13:28:25 +00:00
2014-04-12 22:27:46 +00:00
while ( argv_str ) {
if ( argc > = 4 & & argc = = ( argc & - argc ) ) {
argv = erealloc ( argv , ( argc * 2 + 1 ) * sizeof ( char * ) ) ;
}
argv [ + + argc ] = argv_str ;
argv_str = strtok ( 0 , " " ) ;
argv [ argc ] = estrdup ( argv [ argc ] ) ;
}
argv [ 0 ] = SG ( request_info ) . argv [ 0 ] ;
for ( i = SG ( request_info ) . argc ; - - i ; ) {
efree ( SG ( request_info ) . argv [ i ] ) ;
}
efree ( SG ( request_info ) . argv ) ;
SG ( request_info ) . argv = erealloc ( argv , + + argc * sizeof ( char * ) ) ;
SG ( request_info ) . argc = argc ;
2014-09-25 13:28:25 +00:00
2014-04-12 22:27:46 +00:00
php_hash_environment ( TSRMLS_C ) ;
}
2013-11-10 18:29:05 +00:00
zend_try {
2013-11-23 17:09:52 +00:00
PHPDBG_G ( flags ) ^ = PHPDBG_IS_INTERACTIVE ;
2013-11-26 10:02:58 +00:00
zend_execute ( EG ( active_op_array ) TSRMLS_CC ) ;
2013-11-23 17:09:52 +00:00
PHPDBG_G ( flags ) ^ = PHPDBG_IS_INTERACTIVE ;
2014-10-05 10:33:24 +00:00
phpdbg_notice ( " stop " , " type= \" normal \" " , " Script ended normally " ) ;
2013-11-10 18:29:05 +00:00
} zend_catch {
2013-11-26 10:02:58 +00:00
EG ( active_op_array ) = orig_op_array ;
EG ( opline_ptr ) = orig_opline ;
EG ( return_value_ptr_ptr ) = orig_retval_ptr ;
2013-11-23 22:03:17 +00:00
2013-11-12 01:24:53 +00:00
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_QUITTING ) ) {
2014-10-05 10:33:24 +00:00
phpdbg_error ( " stop " , " type= \" bailout \" " , " Caught exit/error from VM " ) ;
2014-01-17 21:08:35 +00:00
restore = 0 ;
2013-11-16 23:35:11 +00:00
}
2013-11-10 18:29:05 +00:00
} zend_end_try ( ) ;
2014-10-04 21:21:34 +00:00
if ( PHPDBG_G ( socket_fd ) ! = - 1 ) {
close ( PHPDBG_G ( socket_fd ) ) ;
PHPDBG_G ( socket_fd ) = - 1 ;
}
2014-01-17 21:08:35 +00:00
if ( restore ) {
if ( EG ( exception ) ) {
phpdbg_handle_exception ( TSRMLS_C ) ;
}
2013-11-18 14:09:25 +00:00
2014-01-17 21:08:35 +00:00
EG ( active_op_array ) = orig_op_array ;
EG ( opline_ptr ) = orig_opline ;
EG ( return_value_ptr_ptr ) = orig_retval_ptr ;
}
2013-11-10 18:29:05 +00:00
} else {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" nocontext \" " , " Nothing to execute! " ) ;
2013-11-10 18:29:05 +00:00
}
2013-11-17 11:28:14 +00:00
2013-11-16 23:35:11 +00:00
out :
2013-11-22 22:15:04 +00:00
PHPDBG_FRAME ( num ) = 0 ;
2013-11-16 23:35:11 +00:00
return SUCCESS ;
2013-11-10 14:43:46 +00:00
} /* }}} */
2014-10-03 10:43:32 +00:00
int phpdbg_output_ev_variable ( char * name , size_t len , char * keyname , size_t keylen , HashTable * parent , zval * * zv TSRMLS_DC ) {
2014-10-07 11:08:30 +00:00
phpdbg_notice ( " eval " , " variable= \" %.*s \" " , " Printing variable %.*s " , ( int ) len , name ) ;
phpdbg_xml ( " <eval> " ) ;
2014-10-03 10:43:32 +00:00
zend_print_zval_r ( * zv , 0 TSRMLS_CC ) ;
2014-10-07 11:08:30 +00:00
phpdbg_xml ( " </eval> " ) ;
phpdbg_out ( " \n " ) ;
2014-10-03 10:43:32 +00:00
efree ( name ) ;
efree ( keyname ) ;
return SUCCESS ;
}
2014-02-21 21:31:01 +00:00
PHPDBG_COMMAND ( ev ) /* {{{ */
2013-11-10 18:29:05 +00:00
{
2014-09-21 02:17:19 +00:00
zend_bool stepping = ( ( PHPDBG_G ( flags ) & PHPDBG_IS_STEPPING ) = = PHPDBG_IS_STEPPING ) ;
2014-02-21 21:31:01 +00:00
zval retval ;
2013-11-20 18:52:34 +00:00
2014-10-03 10:43:32 +00:00
if ( PHPDBG_G ( flags ) & PHPDBG_IN_SIGNAL_HANDLER ) {
phpdbg_try_access {
phpdbg_parse_variable ( param - > str , param - > len , & EG ( symbol_table ) , 0 , phpdbg_output_ev_variable , 0 TSRMLS_CC ) ;
} phpdbg_catch_access {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " signalsegv " , " " , " Could not fetch data, invalid data source " ) ;
2014-10-03 10:43:32 +00:00
} phpdbg_end_try_access ( ) ;
return SUCCESS ;
}
2014-02-21 21:31:01 +00:00
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_STEPONEVAL ) ) {
2014-09-21 02:17:19 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_STEPPING ;
2014-02-21 21:31:01 +00:00
}
2013-11-23 15:34:36 +00:00
2014-02-21 21:31:01 +00:00
/* disable stepping while eval() in progress */
PHPDBG_G ( flags ) | = PHPDBG_IN_EVAL ;
zend_try {
2014-09-21 02:17:19 +00:00
if ( zend_eval_stringl ( param - > str , param - > len , & retval , " eval()'d code " TSRMLS_CC ) = = SUCCESS ) {
phpdbg_xml ( " <eval> " ) ;
zend_print_zval_r ( & retval , 0 TSRMLS_CC ) ;
phpdbg_xml ( " </eval> " ) ;
phpdbg_out ( " \n " ) ;
2014-02-21 21:31:01 +00:00
zval_dtor ( & retval ) ;
}
} zend_end_try ( ) ;
PHPDBG_G ( flags ) & = ~ PHPDBG_IN_EVAL ;
2013-11-21 23:19:55 +00:00
2014-02-21 21:31:01 +00:00
/* switch stepping back on */
2014-09-21 02:17:19 +00:00
if ( stepping & & ! ( PHPDBG_G ( flags ) & PHPDBG_IS_STEPONEVAL ) ) {
2014-02-21 21:31:01 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IS_STEPPING ;
2013-11-17 12:07:01 +00:00
}
2013-11-16 14:34:49 +00:00
2014-02-21 21:31:01 +00:00
CG ( unclean_shutdown ) = 0 ;
2013-11-10 18:29:05 +00:00
return SUCCESS ;
2013-11-10 15:16:45 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( back ) /* {{{ */
2013-11-10 18:21:49 +00:00
{
2013-11-17 12:07:01 +00:00
if ( ! EG ( in_execution ) ) {
2014-10-02 09:18:36 +00:00
phpdbg_error ( " inactive " , " type= \" noexec \" " , " Not executing! " ) ;
2013-11-17 12:07:01 +00:00
return SUCCESS ;
}
2013-11-10 17:49:25 +00:00
2014-02-21 20:42:15 +00:00
if ( ! param ) {
2014-02-19 20:18:49 +00:00
phpdbg_dump_backtrace ( 0 TSRMLS_CC ) ;
2014-02-21 20:42:15 +00:00
} else {
phpdbg_dump_backtrace ( param - > num TSRMLS_CC ) ;
2013-11-17 12:07:01 +00:00
}
return SUCCESS ;
2013-11-10 15:16:45 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( print ) /* {{{ */
2013-11-10 18:15:00 +00:00
{
2014-09-21 02:17:19 +00:00
phpdbg_out ( " Execution Context Information \n \n " ) ;
phpdbg_xml ( " <printinfo> " ) ;
2013-11-12 08:26:11 +00:00
# ifdef HAVE_LIBREADLINE
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " readline= \" yes \" " , " Readline yes " ) ;
2013-11-12 08:26:11 +00:00
# else
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " readline= \" no \" " , " Readline no " ) ;
2013-11-12 08:26:11 +00:00
# endif
2014-06-29 09:26:03 +00:00
# ifdef HAVE_LIBEDIT
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " libedit= \" yes \" " , " Libedit yes " ) ;
2014-06-29 09:26:03 +00:00
# else
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " libedit= \" no \" " , " Libedit no " ) ;
2014-06-29 09:26:03 +00:00
# endif
2013-11-15 16:12:27 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " context= \" %s \" " , " Exec %s " , PHPDBG_G ( exec ) ? PHPDBG_G ( exec ) : " none " ) ;
phpdbg_writeln ( " print " , " compiled= \" %s \" " , " Compiled %s " , PHPDBG_G ( ops ) ? " yes " : " no " ) ;
phpdbg_writeln ( " print " , " stepping= \" %s \" " , " Stepping %s " , ( PHPDBG_G ( flags ) & PHPDBG_IS_STEPPING ) ? " on " : " off " ) ;
phpdbg_writeln ( " print " , " quiet= \" %s \" " , " Quietness %s " , ( PHPDBG_G ( flags ) & PHPDBG_IS_QUIET ) ? " on " : " off " ) ;
phpdbg_writeln ( " print " , " oplog= \" %s \" " , " Oplog %s " , PHPDBG_G ( oplog ) ? " on " : " off " ) ;
2013-11-17 12:07:01 +00:00
2014-02-21 20:42:15 +00:00
if ( PHPDBG_G ( ops ) ) {
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " ops= \" %d \" " , " Opcodes %d " , PHPDBG_G ( ops ) - > last ) ;
phpdbg_writeln ( " print " , " vars= \" %d \" " , " Variables %d " , PHPDBG_G ( ops ) - > last_var ? PHPDBG_G ( ops ) - > last_var - 1 : 0 ) ;
2014-02-21 20:42:15 +00:00
}
2013-11-24 11:43:05 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " executing= \" %d \" " , " Executing %s " , EG ( in_execution ) ? " yes " : " no " ) ;
2014-02-21 20:42:15 +00:00
if ( EG ( in_execution ) ) {
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " vmret= \" %d \" " , " VM Return %d " , PHPDBG_G ( vmret ) ) ;
2014-02-21 20:42:15 +00:00
}
2013-12-08 18:07:49 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " print " , " classes= \" %d \" " , " Classes %d " , zend_hash_num_elements ( EG ( class_table ) ) ) ;
phpdbg_writeln ( " print " , " functions= \" %d \" " , " Functions %d " , zend_hash_num_elements ( EG ( function_table ) ) ) ;
phpdbg_writeln ( " print " , " constants= \" %d \" " , " Constants %d " , zend_hash_num_elements ( EG ( zend_constants ) ) ) ;
phpdbg_writeln ( " print " , " includes= \" %d \" " , " Included %d " , zend_hash_num_elements ( & EG ( included_files ) ) ) ;
phpdbg_xml ( " </printinfo> " ) ;
2013-11-12 22:39:39 +00:00
2013-11-10 18:15:00 +00:00
return SUCCESS ;
2013-11-10 10:44:42 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( info ) /* {{{ */
2013-11-24 14:54:14 +00:00
{
2014-09-21 02:17:19 +00:00
phpdbg_error ( " info " , " type= \" toofewargs \" expected= \" 1 \" " , " No information command selected! " ) ;
2013-11-24 14:54:14 +00:00
return SUCCESS ;
} /* }}} */
PHPDBG_COMMAND ( set ) /* {{{ */
2013-11-17 15:42:34 +00:00
{
2014-09-21 02:17:19 +00:00
phpdbg_error ( " set " , " type= \" toofewargs \" expected= \" 1 \" " , " No set command selected! " ) ;
2013-11-21 23:19:55 +00:00
2013-11-17 15:42:34 +00:00
return SUCCESS ;
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( break ) /* {{{ */
2013-11-10 14:36:30 +00:00
{
2014-02-21 20:42:15 +00:00
if ( ! param ) {
2014-02-19 20:18:49 +00:00
phpdbg_set_breakpoint_file (
2014-09-21 02:17:19 +00:00
zend_get_executed_filename ( TSRMLS_C ) ,
zend_get_executed_lineno ( TSRMLS_C ) TSRMLS_CC ) ;
2014-02-19 20:18:49 +00:00
} else switch ( param - > type ) {
2013-11-13 23:13:41 +00:00
case ADDR_PARAM :
2013-11-16 14:34:49 +00:00
phpdbg_set_breakpoint_opline ( param - > addr TSRMLS_CC ) ;
2013-11-13 23:13:41 +00:00
break ;
case NUMERIC_PARAM :
2013-11-24 12:03:00 +00:00
if ( PHPDBG_G ( exec ) ) {
phpdbg_set_breakpoint_file ( phpdbg_current_file ( TSRMLS_C ) , param - > num TSRMLS_CC ) ;
} else {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" noexec \" " , " Execution context not set! " ) ;
2013-11-24 12:03:00 +00:00
}
2013-11-13 23:13:41 +00:00
break ;
case METHOD_PARAM :
2013-11-16 14:34:49 +00:00
phpdbg_set_breakpoint_method ( param - > method . class , param - > method . name TSRMLS_CC ) ;
2013-11-13 23:13:41 +00:00
break ;
2013-12-03 11:31:25 +00:00
case NUMERIC_METHOD_PARAM :
phpdbg_set_breakpoint_method_opline ( param - > method . class , param - > method . name , param - > num TSRMLS_CC ) ;
break ;
case NUMERIC_FUNCTION_PARAM :
phpdbg_set_breakpoint_function_opline ( param - > str , param - > num TSRMLS_CC ) ;
break ;
2013-11-13 23:13:41 +00:00
case FILE_PARAM :
2013-11-16 14:34:49 +00:00
phpdbg_set_breakpoint_file ( param - > file . name , param - > file . line TSRMLS_CC ) ;
2013-11-14 00:30:03 +00:00
break ;
2014-02-21 18:01:50 +00:00
case NUMERIC_FILE_PARAM :
phpdbg_set_breakpoint_file_opline ( param - > file . name , param - > file . line TSRMLS_CC ) ;
break ;
2014-02-21 14:44:16 +00:00
case COND_PARAM :
phpdbg_set_breakpoint_expression ( param - > str , param - > len TSRMLS_CC ) ;
break ;
2013-11-13 23:13:41 +00:00
case STR_PARAM :
2013-11-24 12:00:12 +00:00
phpdbg_set_breakpoint_symbol ( param - > str , param - > len TSRMLS_CC ) ;
2013-11-13 23:13:41 +00:00
break ;
2014-02-21 16:18:46 +00:00
case OP_PARAM :
phpdbg_set_breakpoint_opcode ( param - > str , param - > len TSRMLS_CC ) ;
break ;
2013-11-17 11:28:14 +00:00
2013-11-16 22:58:30 +00:00
phpdbg_default_switch_case ( ) ;
2013-11-10 14:36:30 +00:00
}
2013-11-16 10:59:50 +00:00
2013-11-10 14:36:30 +00:00
return SUCCESS ;
2013-11-10 10:44:42 +00:00
} /* }}} */
2014-02-21 21:31:01 +00:00
PHPDBG_COMMAND ( sh ) /* {{{ */
2013-11-18 12:46:10 +00:00
{
2014-02-21 21:31:01 +00:00
FILE * fd = NULL ;
if ( ( fd = VCWD_POPEN ( ( char * ) param - > str , " w " ) ) ) {
2014-09-21 02:17:19 +00:00
/* TODO: do something perhaps ?? do we want input ?? */
2014-02-21 21:31:01 +00:00
fclose ( fd ) ;
} else {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " sh " , " type= \" failure \" smd= \" %s \" " , " Failed to execute %s " , param - > str ) ;
2013-11-18 12:46:10 +00:00
}
2014-09-21 02:17:19 +00:00
2013-11-18 12:46:10 +00:00
return SUCCESS ;
2013-11-19 01:18:43 +00:00
} /* }}} */
2014-10-07 11:08:30 +00:00
static int add_module_info ( zend_module_entry * module TSRMLS_DC ) {
phpdbg_write ( " module " , " name= \" %s \" " , " %s \n " , module - > name ) ;
2014-09-09 00:15:33 +00:00
return 0 ;
}
static int add_zendext_info ( zend_extension * ext TSRMLS_DC ) {
2014-10-07 11:08:30 +00:00
phpdbg_write ( " extension " , " name= \" %s \" " , " %s \n " , ext - > name ) ;
2014-09-09 00:15:33 +00:00
return 0 ;
}
2014-10-07 11:08:30 +00:00
PHPDBG_API const char * phpdbg_load_module_or_extension ( char * * path , char * * name TSRMLS_DC ) {
2014-09-09 00:15:33 +00:00
DL_HANDLE handle ;
char * extension_dir ;
extension_dir = INI_STR ( " extension_dir " ) ;
if ( strchr ( * path , ' / ' ) ! = NULL | | strchr ( * path , DEFAULT_SLASH ) ! = NULL ) {
/* path is fine */
} else if ( extension_dir & & extension_dir [ 0 ] ) {
char * libpath ;
int extension_dir_len = strlen ( extension_dir ) ;
if ( IS_SLASH ( extension_dir [ extension_dir_len - 1 ] ) ) {
spprintf ( & libpath , 0 , " %s%s " , extension_dir , * path ) ; /* SAFE */
} else {
spprintf ( & libpath , 0 , " %s%c%s " , extension_dir , DEFAULT_SLASH , * path ) ; /* SAFE */
}
efree ( * path ) ;
* path = libpath ;
} else {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" relpath \" " , " Not a full path given or extension_dir ini setting is not set " ) ;
2014-09-09 00:15:33 +00:00
return NULL ;
}
handle = DL_LOAD ( * path ) ;
if ( ! handle ) {
# if PHP_WIN32
char * err = GET_DL_ERROR ( ) ;
2014-10-07 11:08:30 +00:00
if ( err & & * err ! = " " ) {
phpdbg_error ( " dl " , " type= \" unknown \" " , " %s " , err ) ;
2014-09-09 00:15:33 +00:00
LocalFree ( err ) ;
} else {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" unknown \" " , " Unknown reason " ) ;
2014-09-09 00:15:33 +00:00
}
# else
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" unknown \" " , " %s " , GET_DL_ERROR ( ) ) ;
2014-09-09 00:15:33 +00:00
# endif
return NULL ;
}
# if ZEND_EXTENSIONS_SUPPORT
do {
zend_extension * new_extension ;
zend_extension_version_info * extension_version_info ;
extension_version_info = ( zend_extension_version_info * ) DL_FETCH_SYMBOL ( handle , " extension_version_info " ) ;
if ( ! extension_version_info ) {
extension_version_info = ( zend_extension_version_info * ) DL_FETCH_SYMBOL ( handle , " _extension_version_info " ) ;
}
new_extension = ( zend_extension * ) DL_FETCH_SYMBOL ( handle , " zend_extension_entry " ) ;
if ( ! new_extension ) {
new_extension = ( zend_extension * ) DL_FETCH_SYMBOL ( handle , " _zend_extension_entry " ) ;
}
if ( ! extension_version_info | | ! new_extension ) {
break ;
}
if ( extension_version_info - > zend_extension_api_no ! = ZEND_EXTENSION_API_NO & & ( ! new_extension - > api_no_check | | new_extension - > api_no_check ( ZEND_EXTENSION_API_NO ) ! = SUCCESS ) ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" wrongapi \" extension= \" %s \" apineeded= \" %d \" apiinstalled= \" %d \" " , " %s requires Zend Engine API version %d, which does not match the installed Zend Engine API version %d " , new_extension - > name , extension_version_info - > zend_extension_api_no , ZEND_EXTENSION_API_NO ) ;
2014-09-09 00:15:33 +00:00
goto quit ;
} else if ( strcmp ( ZEND_EXTENSION_BUILD_ID , extension_version_info - > build_id ) & & ( ! new_extension - > build_id_check | | new_extension - > build_id_check ( ZEND_EXTENSION_BUILD_ID ) ! = SUCCESS ) ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" wrongbuild \" extension= \" %s \" buildneeded= \" %s \" buildinstalled= \" %s \" " , " %s was built with configuration %s, whereas running engine is %s " , new_extension - > name , extension_version_info - > build_id , ZEND_EXTENSION_BUILD_ID ) ;
2014-09-09 00:15:33 +00:00
goto quit ;
}
2014-10-07 11:08:30 +00:00
* name = new_extension - > name ;
2014-09-09 00:15:33 +00:00
zend_register_extension ( new_extension , handle ) ;
if ( new_extension - > startup ) {
if ( new_extension - > startup ( new_extension ) ! = SUCCESS ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" startupfailure \" extension= \" %s \" " , " Unable to startup Zend extension %s " , new_extension - > name ) ;
2014-09-09 00:15:33 +00:00
goto quit ;
}
zend_append_version_info ( new_extension ) ;
}
return " Zend extension " ;
} while ( 0 ) ;
# endif
do {
zend_module_entry * module_entry ;
zend_module_entry * ( * get_module ) ( void ) ;
get_module = ( zend_module_entry * ( * ) ( void ) ) DL_FETCH_SYMBOL ( handle , " get_module " ) ;
if ( ! get_module ) {
get_module = ( zend_module_entry * ( * ) ( void ) ) DL_FETCH_SYMBOL ( handle , " _get_module " ) ;
}
if ( ! get_module ) {
break ;
}
module_entry = get_module ( ) ;
2014-10-07 11:08:30 +00:00
* name = ( char * ) module_entry - > name ;
2014-09-09 00:15:33 +00:00
if ( strcmp ( ZEND_EXTENSION_BUILD_ID , module_entry - > build_id ) ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" wrongbuild \" module= \" %s \" buildneeded= \" %s \" buildinstalled= \" %s \" " , " %s was built with configuration %s, whereas running engine is %s " , module_entry - > name , module_entry - > build_id , ZEND_EXTENSION_BUILD_ID ) ;
2014-09-09 00:15:33 +00:00
goto quit ;
}
module_entry - > type = MODULE_PERSISTENT ;
module_entry - > module_number = zend_next_free_module ( ) ;
module_entry - > handle = handle ;
if ( ( module_entry = zend_register_module_ex ( module_entry TSRMLS_CC ) ) = = NULL ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" registerfailure \" module= \" %s \" " , " Unable to register module %s " , module_entry - > name ) ;
2014-09-09 00:15:33 +00:00
goto quit ;
}
if ( zend_startup_module_ex ( module_entry TSRMLS_CC ) = = FAILURE ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" startupfailure \" module= \" %s \" " , " Unable to startup module %s " , module_entry - > name ) ;
2014-09-09 00:15:33 +00:00
goto quit ;
}
if ( module_entry - > request_startup_func ) {
if ( module_entry - > request_startup_func ( MODULE_PERSISTENT , module_entry - > module_number TSRMLS_CC ) = = FAILURE ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" initfailure \" module= \" %s \" " , " Unable to initialize module %s " , module_entry - > name ) ;
2014-09-09 00:15:33 +00:00
goto quit ;
}
}
return " module " ;
} while ( 0 ) ;
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" nophpso \" " , " This shared object is nor a Zend extension nor a module " ) ;
2014-09-09 00:15:33 +00:00
quit :
DL_UNLOAD ( handle ) ;
return NULL ;
}
PHPDBG_COMMAND ( dl ) /* {{{ */
{
const char * type ;
char * name , * path ;
if ( ! param | | param - > type = = EMPTY_PARAM ) {
2014-10-07 11:08:30 +00:00
phpdbg_notice ( " dl " , " extensiontype= \" Zend extension \" " , " Zend extensions " ) ;
2014-09-09 00:15:33 +00:00
zend_llist_apply ( & zend_extensions , ( llist_apply_func_t ) add_zendext_info TSRMLS_CC ) ;
2014-10-07 11:08:30 +00:00
phpdbg_out ( " \n " ) ;
phpdbg_notice ( " dl " , " extensiontype= \" module \" " , " Modules " ) ;
zend_hash_apply ( & module_registry , ( apply_func_t ) add_module_info TSRMLS_CC ) ;
2014-09-09 00:15:33 +00:00
} else switch ( param - > type ) {
case STR_PARAM :
# ifdef HAVE_LIBDL
path = estrndup ( param - > str , param - > len ) ;
2014-10-07 11:08:30 +00:00
phpdbg_activate_err_buf ( 1 TSRMLS_CC ) ;
2014-09-09 00:15:33 +00:00
if ( ( type = phpdbg_load_module_or_extension ( & path , & name TSRMLS_CC ) ) = = NULL ) {
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " path= \" %s \" %b " , " Could not load %s, not found or invalid zend extension / module: %b " , path ) ;
2014-09-09 00:15:33 +00:00
efree ( name ) ;
} else {
2014-10-07 11:08:30 +00:00
phpdbg_notice ( " dl " , " extensiontype= \" %s \" name= \" %s \" path= \" %s \" " , " Successfully loaded the %s %s at path %s " , type , name , path ) ;
2014-09-09 00:15:33 +00:00
}
2014-10-07 11:08:30 +00:00
phpdbg_activate_err_buf ( 0 TSRMLS_CC ) ;
phpdbg_free_err_buf ( TSRMLS_C ) ;
2014-09-09 00:15:33 +00:00
efree ( path ) ;
# else
2014-10-07 11:08:30 +00:00
phpdbg_error ( " dl " , " type= \" unsupported \" path= \" %.*s \" " , " Cannot dynamically load %.*s - dynamic modules are not supported " , ( int ) param - > len , param - > str ) ;
2014-09-09 00:15:33 +00:00
# endif
break ;
phpdbg_default_switch_case ( ) ;
}
return SUCCESS ;
} /* }}} */
2013-11-25 16:39:14 +00:00
PHPDBG_COMMAND ( source ) /* {{{ */
{
2014-02-21 20:42:15 +00:00
struct stat sb ;
2014-09-21 02:17:19 +00:00
2014-02-21 20:42:15 +00:00
if ( VCWD_STAT ( param - > str , & sb ) ! = - 1 ) {
phpdbg_try_file_init ( param - > str , param - > len , 0 TSRMLS_CC ) ;
2014-02-24 19:03:55 +00:00
} else {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " source " , " type= \" notfound \" file= \" %s \" " , " Failed to stat %s, file does not exist " , param - > str ) ;
2014-02-24 19:03:55 +00:00
}
2014-09-21 02:17:19 +00:00
2013-11-25 16:39:14 +00:00
return SUCCESS ;
} /* }}} */
2014-02-24 19:03:55 +00:00
PHPDBG_COMMAND ( export ) /* {{{ */
{
FILE * handle = VCWD_FOPEN ( param - > str , " w+ " ) ;
2014-09-21 02:17:19 +00:00
2014-02-24 19:03:55 +00:00
if ( handle ) {
phpdbg_export_breakpoints ( handle TSRMLS_CC ) ;
fclose ( handle ) ;
} else {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " export " , " type= \" openfailure \" file= \" %s \" " , " Failed to open or create %s, check path and permissions " , param - > str ) ;
2013-11-25 16:39:14 +00:00
}
2014-09-21 02:17:19 +00:00
2013-11-25 16:39:14 +00:00
return SUCCESS ;
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( register ) /* {{{ */
2013-11-19 01:18:43 +00:00
{
2014-02-21 20:42:15 +00:00
zend_function * function ;
char * lcname = zend_str_tolower_dup ( param - > str , param - > len ) ;
size_t lcname_len = strlen ( lcname ) ;
if ( ! zend_hash_exists ( & PHPDBG_G ( registered ) , lcname , lcname_len + 1 ) ) {
if ( zend_hash_find ( EG ( function_table ) , lcname , lcname_len + 1 , ( void * * ) & function ) = = SUCCESS ) {
2014-09-21 02:17:19 +00:00
zend_hash_update ( & PHPDBG_G ( registered ) , lcname , lcname_len + 1 , ( void * ) & function , sizeof ( zend_function ) , NULL ) ;
2014-02-21 20:42:15 +00:00
function_add_ref ( function ) ;
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " register " , " function= \" %s \" " , " Registered %s " , lcname ) ;
2014-02-21 20:42:15 +00:00
} else {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " register " , " type= \" notfoundc \" function= \" %s \" " , " The requested function (%s) could not be found " , param - > str ) ;
2014-02-21 20:42:15 +00:00
}
} else {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " register " , " type= \" inuse \" function= \" %s \" " , " The requested name (%s) is already in use " , lcname ) ;
2013-11-19 01:18:43 +00:00
}
2014-02-21 20:42:15 +00:00
efree ( lcname ) ;
2013-11-19 01:18:43 +00:00
return SUCCESS ;
} /* }}} */
2013-11-18 12:46:10 +00:00
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( quit ) /* {{{ */
2013-11-10 01:30:32 +00:00
{
2013-11-26 10:02:58 +00:00
/* don't allow this to loop, ever ... */
2013-11-17 12:07:01 +00:00
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_QUITTING ) ) {
PHPDBG_G ( flags ) | = PHPDBG_IS_QUITTING ;
zend_bailout ( ) ;
}
2013-11-10 11:36:57 +00:00
2014-04-21 21:14:06 +00:00
return PHPDBG_NEXT ;
2013-11-10 01:30:32 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( clean ) /* {{{ */
2013-11-11 08:02:04 +00:00
{
2013-11-17 12:07:01 +00:00
if ( EG ( in_execution ) ) {
2014-09-25 13:28:25 +00:00
phpdbg_error ( " inactive " , " type= \" isrunning \" " , " Cannot clean environment while executing " ) ;
2013-11-17 12:07:01 +00:00
return SUCCESS ;
2013-11-13 21:43:54 +00:00
}
2013-11-13 21:31:33 +00:00
2014-09-24 23:29:08 +00:00
phpdbg_out ( " Cleaning Execution Environment \n " ) ;
2014-09-21 02:17:19 +00:00
phpdbg_xml ( " <cleaninfo> " ) ;
2013-11-12 00:27:48 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_writeln ( " clean " , " classes= \" %d \" " , " Classes %d " , zend_hash_num_elements ( EG ( class_table ) ) ) ;
phpdbg_writeln ( " clean " , " functions= \" %d \" " , " Functions %d " , zend_hash_num_elements ( EG ( function_table ) ) ) ;
phpdbg_writeln ( " clean " , " constants= \" %d \" " , " Constants %d " , zend_hash_num_elements ( EG ( zend_constants ) ) ) ;
phpdbg_writeln ( " clean " , " includes= \" %d \" " , " Includes %d " , zend_hash_num_elements ( & EG ( included_files ) ) ) ;
2013-11-12 00:27:48 +00:00
2013-11-13 21:43:54 +00:00
phpdbg_clean ( 1 TSRMLS_CC ) ;
2013-11-13 21:31:33 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_xml ( " </cleaninfo> " ) ;
2013-11-17 12:07:01 +00:00
return SUCCESS ;
2013-11-11 08:02:04 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( clear ) /* {{{ */
2013-11-11 13:31:41 +00:00
{
2014-09-24 23:29:08 +00:00
phpdbg_out ( " Clearing Breakpoints \n " ) ;
2014-09-21 02:17:19 +00:00
phpdbg_xml ( " <clearinfo> " ) ;
phpdbg_writeln ( " clear " , " files= \" %d \" " , " File %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE ] ) ) ;
phpdbg_writeln ( " clear " , " functions= \" %d \" " , " Functions %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_SYM ] ) ) ;
phpdbg_writeln ( " clear " , " methods= \" %d \" " , " Methods %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_METHOD ] ) ) ;
phpdbg_writeln ( " clear " , " oplines= \" %d \" " , " Oplines %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_OPLINE ] ) ) ;
phpdbg_writeln ( " clear " , " fileoplines= \" %d \" " , " File oplines %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FILE_OPLINE ] ) ) ;
phpdbg_writeln ( " clear " , " functionoplines= \" %d \" " , " Function oplines %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_FUNCTION_OPLINE ] ) ) ;
phpdbg_writeln ( " clear " , " methodoplines= \" %d \" " , " Method oplines %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_METHOD_OPLINE ] ) ) ;
phpdbg_writeln ( " clear " , " eval= \" %d \" " , " Conditionals %d " , zend_hash_num_elements ( & PHPDBG_G ( bp ) [ PHPDBG_BREAK_COND ] ) ) ;
2013-11-13 21:31:33 +00:00
2013-11-17 12:07:01 +00:00
phpdbg_clear_breakpoints ( TSRMLS_C ) ;
2013-11-11 22:02:34 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_xml ( " </clearinfo> " ) ;
2013-11-26 10:02:58 +00:00
return SUCCESS ;
2013-11-11 13:31:41 +00:00
} /* }}} */
2013-11-20 16:19:37 +00:00
PHPDBG_COMMAND ( list ) /* {{{ */
2013-11-11 23:40:03 +00:00
{
2014-02-21 20:42:15 +00:00
if ( ! param ) {
2014-02-18 19:48:33 +00:00
return PHPDBG_LIST_HANDLER ( lines ) ( PHPDBG_COMMAND_ARGS ) ;
} else switch ( param - > type ) {
2013-11-26 10:02:58 +00:00
case NUMERIC_PARAM :
2013-11-20 13:28:41 +00:00
return PHPDBG_LIST_HANDLER ( lines ) ( PHPDBG_COMMAND_ARGS ) ;
2013-11-17 11:28:14 +00:00
2013-11-16 23:11:39 +00:00
case FILE_PARAM :
2013-11-20 13:28:41 +00:00
return PHPDBG_LIST_HANDLER ( lines ) ( PHPDBG_COMMAND_ARGS ) ;
2013-11-17 11:28:14 +00:00
case STR_PARAM :
2013-11-26 10:02:58 +00:00
phpdbg_list_function_byname ( param - > str , param - > len TSRMLS_CC ) ;
2013-11-17 11:28:14 +00:00
break ;
2013-11-16 23:11:39 +00:00
case METHOD_PARAM :
2013-11-26 10:02:58 +00:00
return PHPDBG_LIST_HANDLER ( method ) ( PHPDBG_COMMAND_ARGS ) ;
2013-11-17 11:28:14 +00:00
2013-11-16 23:11:39 +00:00
phpdbg_default_switch_case ( ) ;
2013-11-26 10:02:58 +00:00
}
2013-11-14 15:46:06 +00:00
2013-11-12 00:24:24 +00:00
return SUCCESS ;
2013-11-11 23:40:03 +00:00
} /* }}} */
2013-12-11 20:27:03 +00:00
PHPDBG_COMMAND ( watch ) /* {{{ */
{
2014-04-13 10:42:47 +00:00
if ( ! param | | param - > type = = EMPTY_PARAM ) {
phpdbg_list_watchpoints ( TSRMLS_C ) ;
} else switch ( param - > type ) {
2013-12-11 20:27:03 +00:00
case STR_PARAM :
2014-04-13 15:34:27 +00:00
if ( phpdbg_create_var_watchpoint ( param - > str , param - > len TSRMLS_CC ) ! = FAILURE ) {
2014-09-21 02:17:19 +00:00
phpdbg_notice ( " watch " , " variable= \" %.*s \" " , " Set watchpoint on %.*s " , ( int ) param - > len , param - > str ) ;
2014-04-13 15:34:27 +00:00
}
2013-12-11 20:27:03 +00:00
break ;
phpdbg_default_switch_case ( ) ;
}
return SUCCESS ;
} /* }}} */
2014-10-02 23:29:41 +00:00
int phpdbg_interactive ( zend_bool allow_async_unsafe TSRMLS_DC ) /* { { { */
2013-11-10 01:30:32 +00:00
{
2013-11-17 12:07:01 +00:00
int ret = SUCCESS ;
2014-02-18 19:48:33 +00:00
char * input = NULL ;
phpdbg_param_t stack ;
2014-04-15 15:52:46 +00:00
2013-11-22 09:09:54 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IS_INTERACTIVE ;
2013-11-19 21:40:01 +00:00
2013-11-22 20:42:57 +00:00
input = phpdbg_read_input ( NULL TSRMLS_CC ) ;
2014-04-15 15:52:46 +00:00
2014-02-18 19:48:33 +00:00
if ( input ) {
2013-11-19 13:22:46 +00:00
do {
2014-02-18 19:48:33 +00:00
phpdbg_init_param ( & stack , STACK_PARAM ) ;
2014-04-15 15:52:46 +00:00
2014-06-08 22:02:10 +00:00
if ( phpdbg_do_parse ( & stack , input TSRMLS_CC ) < = 0 ) {
2014-09-21 02:17:19 +00:00
phpdbg_activate_err_buf ( 1 TSRMLS_CC ) ;
2014-10-07 11:08:30 +00:00
switch ( ret = phpdbg_stack_execute ( & stack , allow_async_unsafe TSRMLS_CC ) ) {
2014-02-18 19:48:33 +00:00
case FAILURE :
2014-04-21 20:43:19 +00:00
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IS_QUITTING ) ) {
2014-10-02 23:29:41 +00:00
if ( ! allow_async_unsafe | | phpdbg_call_register ( & stack TSRMLS_CC ) = = FAILURE ) {
2014-09-21 02:17:19 +00:00
phpdbg_output_err_buf ( NULL , " %b " , " %b " TSRMLS_CC ) ;
2014-02-21 20:42:15 +00:00
}
2014-04-21 20:43:19 +00:00
}
2014-02-18 19:48:33 +00:00
break ;
2013-11-13 21:31:33 +00:00
2014-02-18 19:48:33 +00:00
case PHPDBG_LEAVE :
case PHPDBG_FINISH :
case PHPDBG_UNTIL :
case PHPDBG_NEXT : {
2014-09-21 02:17:19 +00:00
phpdbg_activate_err_buf ( 0 TSRMLS_CC ) ;
phpdbg_free_err_buf ( TSRMLS_C ) ;
2014-04-21 21:14:06 +00:00
if ( ! EG ( in_execution ) & & ! ( PHPDBG_G ( flags ) & PHPDBG_IS_QUITTING ) ) {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " command " , " type= \" noexec \" " , " Not running " ) ;
2014-02-18 19:48:33 +00:00
}
goto out ;
2013-11-19 13:22:46 +00:00
}
2013-11-19 12:39:48 +00:00
}
2013-11-19 21:40:01 +00:00
2014-09-21 02:17:19 +00:00
phpdbg_activate_err_buf ( 0 TSRMLS_CC ) ;
phpdbg_free_err_buf ( TSRMLS_C ) ;
2014-02-19 00:33:49 +00:00
}
2014-02-23 07:33:48 +00:00
2014-02-18 19:48:33 +00:00
phpdbg_stack_free ( & stack ) ;
2013-11-19 19:24:21 +00:00
phpdbg_destroy_input ( & input TSRMLS_CC ) ;
2014-10-06 09:26:08 +00:00
PHPDBG_G ( req_id ) = 0 ;
2014-02-18 19:48:33 +00:00
} while ( ( input = phpdbg_read_input ( NULL TSRMLS_CC ) ) ) ;
2013-11-10 01:30:32 +00:00
}
2013-11-17 12:07:01 +00:00
2013-11-16 12:02:35 +00:00
out :
2014-02-18 19:48:33 +00:00
if ( input ) {
2014-04-15 15:52:46 +00:00
phpdbg_stack_free ( & stack ) ;
2014-02-18 19:48:33 +00:00
phpdbg_destroy_input ( & input TSRMLS_CC ) ;
2014-10-06 09:26:08 +00:00
PHPDBG_G ( req_id ) = 0 ;
2014-02-18 19:48:33 +00:00
}
2014-02-23 07:33:48 +00:00
2013-11-22 18:16:25 +00:00
if ( EG ( in_execution ) ) {
2013-11-22 19:06:31 +00:00
phpdbg_restore_frame ( TSRMLS_C ) ;
2013-11-22 18:16:25 +00:00
}
2013-11-22 09:09:54 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_INTERACTIVE ;
2013-11-12 09:52:59 +00:00
2014-03-23 01:27:25 +00:00
phpdbg_print_changed_zvals ( TSRMLS_C ) ;
2013-11-16 12:02:35 +00:00
return ret ;
2013-11-21 13:35:39 +00:00
} /* }}} */
2013-11-12 09:52:59 +00:00
void phpdbg_clean ( zend_bool full TSRMLS_DC ) /* { { { */
{
2013-11-17 12:07:01 +00:00
/* this is implicitly required */
if ( PHPDBG_G ( ops ) ) {
destroy_op_array ( PHPDBG_G ( ops ) TSRMLS_CC ) ;
efree ( PHPDBG_G ( ops ) ) ;
PHPDBG_G ( ops ) = NULL ;
}
2013-11-12 09:52:59 +00:00
2013-11-18 01:05:14 +00:00
if ( full ) {
2013-11-17 12:07:01 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IS_CLEANING ;
2013-11-16 10:59:50 +00:00
2013-11-17 12:07:01 +00:00
zend_bailout ( ) ;
}
2013-11-10 18:05:11 +00:00
} /* }}} */
2013-11-15 11:19:26 +00:00
static inline zend_execute_data * phpdbg_create_execute_data ( zend_op_array * op_array , zend_bool nested TSRMLS_DC ) /* { { { */
{
# if PHP_VERSION_ID >= 50500
2013-11-26 10:02:58 +00:00
return zend_create_execute_data_from_op_array ( op_array , nested TSRMLS_CC ) ;
2013-11-15 11:19:26 +00:00
# else
# undef EX
# define EX(element) execute_data->element
# undef EX_CV
# define EX_CV(var) EX(CVs)[var]
# undef EX_CVs
# define EX_CVs() EX(CVs)
# undef EX_T
# define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
# undef EX_Ts
# define EX_Ts() EX(Ts)
2013-11-26 10:02:58 +00:00
zend_execute_data * execute_data = ( zend_execute_data * ) zend_vm_stack_alloc (
2013-11-15 11:19:26 +00:00
ZEND_MM_ALIGNED_SIZE ( sizeof ( zend_execute_data ) ) +
ZEND_MM_ALIGNED_SIZE ( sizeof ( zval * * ) * op_array - > last_var * ( EG ( active_symbol_table ) ? 1 : 2 ) ) +
ZEND_MM_ALIGNED_SIZE ( sizeof ( temp_variable ) ) * op_array - > T TSRMLS_CC ) ;
2014-09-21 02:17:19 +00:00
EX ( CVs ) = ( zval * * * ) ( ( char * ) execute_data + ZEND_MM_ALIGNED_SIZE ( sizeof ( zend_execute_data ) ) ) ;
memset ( EX ( CVs ) , 0 , sizeof ( zval * * ) * op_array - > last_var ) ;
EX ( Ts ) = ( temp_variable * ) ( ( ( char * ) EX ( CVs ) ) + ZEND_MM_ALIGNED_SIZE ( sizeof ( zval * * ) * op_array - > last_var * ( EG ( active_symbol_table ) ? 1 : 2 ) ) ) ;
2013-11-15 11:19:26 +00:00
EX ( fbc ) = NULL ;
EX ( called_scope ) = NULL ;
EX ( object ) = NULL ;
EX ( old_error_reporting ) = NULL ;
EX ( op_array ) = op_array ;
EX ( symbol_table ) = EG ( active_symbol_table ) ;
EX ( prev_execute_data ) = EG ( current_execute_data ) ;
EG ( current_execute_data ) = execute_data ;
EX ( nested ) = nested ;
if ( ! op_array - > run_time_cache & & op_array - > last_cache_slot ) {
op_array - > run_time_cache = ecalloc ( op_array - > last_cache_slot , sizeof ( void * ) ) ;
}
if ( op_array - > this_var ! = - 1 & & EG ( This ) ) {
Z_ADDREF_P ( EG ( This ) ) ; /* For $this pointer */
if ( ! EG ( active_symbol_table ) ) {
2014-09-21 02:17:19 +00:00
EX_CV ( op_array - > this_var ) = ( zval * * ) EX_CVs ( ) + ( op_array - > last_var + op_array - > this_var ) ;
2013-11-15 11:19:26 +00:00
* EX_CV ( op_array - > this_var ) = EG ( This ) ;
} else {
2014-09-21 02:17:19 +00:00
if ( zend_hash_add ( EG ( active_symbol_table ) , " this " , sizeof ( " this " ) , & EG ( This ) , sizeof ( zval * ) , ( void * * ) & EX_CV ( op_array - > this_var ) ) = = FAILURE ) {
2013-11-15 11:19:26 +00:00
Z_DELREF_P ( EG ( This ) ) ;
}
}
}
2014-09-21 02:17:19 +00:00
EX ( opline ) = op_array - > opcodes ;
2013-11-15 11:19:26 +00:00
EG ( opline_ptr ) = & EX ( opline ) ;
EX ( function_state ) . function = ( zend_function * ) op_array ;
EX ( function_state ) . arguments = NULL ;
2013-11-16 10:59:50 +00:00
2013-11-15 11:19:26 +00:00
return execute_data ;
# endif
} /* }}} */
2014-10-02 23:29:41 +00:00
# define DO_INTERACTIVE(allow_async_unsafe) do { \
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IN_EVAL ) ) { \
phpdbg_list_file ( \
zend_get_executed_filename ( TSRMLS_C ) , \
3 , \
zend_get_executed_lineno ( TSRMLS_C ) - 1 , \
zend_get_executed_lineno ( TSRMLS_C ) \
TSRMLS_CC \
) ; \
} \
\
switch ( phpdbg_interactive ( allow_async_unsafe TSRMLS_CC ) ) { \
case PHPDBG_LEAVE : \
case PHPDBG_FINISH : \
case PHPDBG_UNTIL : \
case PHPDBG_NEXT : { \
goto next ; \
} \
} \
} while ( 0 )
2013-11-15 11:19:26 +00:00
# if PHP_VERSION_ID >= 50500
2013-11-10 18:21:49 +00:00
void phpdbg_execute_ex ( zend_execute_data * execute_data TSRMLS_DC ) /* { { { */
2013-11-10 13:01:46 +00:00
{
2013-11-15 11:19:26 +00:00
# else
void phpdbg_execute_ex ( zend_op_array * op_array TSRMLS_DC ) /* { { { */
{
2013-11-18 03:18:37 +00:00
long long flags = 0 ;
zend_ulong address = 0L ;
2013-11-17 12:07:01 +00:00
zend_execute_data * execute_data ;
zend_bool nested = 0 ;
2013-11-15 11:19:26 +00:00
# endif
2013-11-10 15:16:45 +00:00
zend_bool original_in_execution = EG ( in_execution ) ;
2013-11-21 13:35:39 +00:00
HashTable vars ;
2013-11-21 23:19:55 +00:00
2013-11-15 11:19:26 +00:00
# if PHP_VERSION_ID < 50500
2013-11-17 12:07:01 +00:00
if ( EG ( exception ) ) {
return ;
}
2013-11-15 11:19:26 +00:00
# endif
2013-11-10 13:01:46 +00:00
EG ( in_execution ) = 1 ;
2013-11-15 11:19:26 +00:00
# if PHP_VERSION_ID >= 50500
2013-11-10 13:01:46 +00:00
if ( 0 ) {
zend_vm_enter :
2013-11-15 11:19:26 +00:00
execute_data = phpdbg_create_execute_data ( EG ( active_op_array ) , 1 TSRMLS_CC ) ;
2013-11-10 13:01:46 +00:00
}
2013-11-21 13:35:39 +00:00
zend_hash_init ( & vars , EG ( active_op_array ) - > last , NULL , NULL , 0 ) ;
2013-11-15 11:19:26 +00:00
# else
zend_vm_enter :
2013-11-21 13:35:39 +00:00
execute_data = phpdbg_create_execute_data ( op_array , nested TSRMLS_CC ) ;
nested = 1 ;
zend_hash_init ( & vars , EG ( active_op_array ) - > last , NULL , NULL , 0 ) ;
2013-11-15 11:19:26 +00:00
# endif
2013-11-10 13:01:46 +00:00
while ( 1 ) {
2013-12-09 10:15:16 +00:00
if ( ( PHPDBG_G ( flags ) & PHPDBG_BP_RESOLVE_MASK ) ) {
/* resolve nth opline breakpoints */
phpdbg_resolve_op_array_breaks ( EG ( active_op_array ) TSRMLS_CC ) ;
}
2014-10-02 23:29:41 +00:00
2013-11-10 13:01:46 +00:00
# ifdef ZEND_WIN32
if ( EG ( timed_out ) ) {
zend_timeout ( 0 ) ;
}
# endif
2013-11-20 18:52:34 +00:00
/* allow conditional breakpoints and
2013-11-20 17:09:06 +00:00
initialization to access the vm uninterrupted */
2013-11-20 17:48:54 +00:00
if ( ( PHPDBG_G ( flags ) & PHPDBG_IN_COND_BP ) | |
( PHPDBG_G ( flags ) & PHPDBG_IS_INITIALIZING ) ) {
2013-11-16 10:59:50 +00:00
/* skip possible breakpoints */
goto next ;
}
2013-11-17 16:10:43 +00:00
2013-11-18 02:14:17 +00:00
/* perform seek operation */
if ( PHPDBG_G ( flags ) & PHPDBG_SEEK_MASK ) {
2013-11-18 03:18:37 +00:00
/* current address */
zend_ulong address = ( zend_ulong ) execute_data - > opline ;
2013-11-18 14:09:25 +00:00
2013-11-18 02:14:17 +00:00
/* run to next line */
if ( PHPDBG_G ( flags ) & PHPDBG_IN_UNTIL ) {
2013-11-18 03:18:37 +00:00
if ( zend_hash_index_exists ( & PHPDBG_G ( seek ) , address ) ) {
2013-11-18 02:14:17 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IN_UNTIL ;
2014-09-21 02:17:19 +00:00
zend_hash_clean ( & PHPDBG_G ( seek ) ) ;
2013-11-18 02:14:17 +00:00
} else {
/* skip possible breakpoints */
goto next ;
}
2013-11-17 13:59:21 +00:00
}
2013-11-17 16:10:43 +00:00
2013-11-18 02:14:17 +00:00
/* run to finish */
if ( PHPDBG_G ( flags ) & PHPDBG_IN_FINISH ) {
2013-11-18 03:18:37 +00:00
if ( zend_hash_index_exists ( & PHPDBG_G ( seek ) , address ) ) {
2013-11-18 02:14:17 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IN_FINISH ;
2014-09-21 02:17:19 +00:00
zend_hash_clean ( & PHPDBG_G ( seek ) ) ;
2013-11-18 02:14:17 +00:00
}
2013-11-17 13:59:21 +00:00
/* skip possible breakpoints */
goto next ;
}
2013-11-18 14:09:25 +00:00
2013-11-18 02:14:17 +00:00
/* break for leave */
if ( PHPDBG_G ( flags ) & PHPDBG_IN_LEAVE ) {
2013-11-18 03:18:37 +00:00
if ( zend_hash_index_exists ( & PHPDBG_G ( seek ) , address ) ) {
2013-11-18 02:14:17 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IN_LEAVE ;
2014-09-21 02:17:19 +00:00
zend_hash_clean ( & PHPDBG_G ( seek ) ) ;
phpdbg_notice ( " breakpoint " , " id= \" leave \" file= \" %s \" line= \" %u \" " , " Breaking for leave at %s:%u " ,
2013-11-18 02:14:17 +00:00
zend_get_executed_filename ( TSRMLS_C ) ,
zend_get_executed_lineno ( TSRMLS_C )
) ;
2014-10-02 23:29:41 +00:00
DO_INTERACTIVE ( 1 ) ;
2013-11-18 02:14:17 +00:00
} else {
/* skip possible breakpoints */
goto next ;
}
}
2013-11-17 13:59:21 +00:00
}
2013-11-13 21:31:33 +00:00
2013-11-16 10:59:50 +00:00
/* not while in conditionals */
2014-09-21 02:17:19 +00:00
phpdbg_print_opline_ex ( execute_data , & vars , 0 TSRMLS_CC ) ;
2013-11-17 16:10:43 +00:00
2014-04-20 18:20:59 +00:00
if ( PHPDBG_G ( flags ) & PHPDBG_IS_STEPPING & & ( PHPDBG_G ( flags ) & PHPDBG_STEP_OPCODE | | execute_data - > opline - > lineno ! = PHPDBG_G ( last_line ) ) ) {
2014-04-20 14:47:24 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_STEPPING ;
2014-10-02 23:29:41 +00:00
DO_INTERACTIVE ( 1 ) ;
2014-04-20 14:47:24 +00:00
}
2013-12-13 22:57:36 +00:00
/* check if some watchpoint was hit */
{
if ( phpdbg_print_changed_zvals ( TSRMLS_C ) = = SUCCESS ) {
2014-10-02 23:29:41 +00:00
DO_INTERACTIVE ( 1 ) ;
2013-12-13 22:57:36 +00:00
}
}
2013-11-27 13:01:57 +00:00
/* search for breakpoints */
{
phpdbg_breakbase_t * brake ;
2013-12-08 18:07:49 +00:00
2014-04-20 11:25:28 +00:00
if ( ( PHPDBG_G ( flags ) & PHPDBG_BP_MASK )
& & ( brake = phpdbg_find_breakpoint ( execute_data TSRMLS_CC ) )
& & ( brake - > type ! = PHPDBG_BREAK_FILE | | execute_data - > opline - > lineno ! = PHPDBG_G ( last_line ) ) ) {
phpdbg_hit_breakpoint ( brake , 1 TSRMLS_CC ) ;
2014-10-02 23:29:41 +00:00
DO_INTERACTIVE ( 1 ) ;
2013-11-27 13:01:57 +00:00
}
2013-11-23 22:03:17 +00:00
}
2013-11-20 19:16:07 +00:00
if ( PHPDBG_G ( flags ) & PHPDBG_IS_SIGNALED ) {
2014-10-03 10:43:32 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_SIGNALED ;
2014-09-21 02:17:19 +00:00
phpdbg_out ( " \n " ) ;
phpdbg_notice ( " signal " , " type= \" SIGINT \" " , " Program received signal SIGINT " ) ;
2014-10-02 23:29:41 +00:00
DO_INTERACTIVE ( 1 ) ;
2013-11-20 19:16:07 +00:00
}
2014-10-02 23:29:41 +00:00
next :
2014-04-20 11:25:28 +00:00
PHPDBG_G ( last_line ) = execute_data - > opline - > lineno ;
2014-10-05 11:29:56 +00:00
/* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */
if ( ( execute_data - > opline - > opcode = = ZEND_DO_FCALL_BY_NAME | | execute_data - > opline - > opcode = = ZEND_DO_FCALL ) & & execute_data - > function_state . function - > type = = ZEND_USER_FUNCTION ) {
2014-10-05 11:57:35 +00:00
# if PHP_VERSION_ID < 50500
zend_execute = execute ;
# else
2014-10-05 11:29:56 +00:00
zend_execute_ex = execute_ex ;
2014-10-05 11:57:35 +00:00
# endif
2014-10-05 11:29:56 +00:00
}
2013-11-21 23:19:55 +00:00
PHPDBG_G ( vmret ) = execute_data - > opline - > handler ( execute_data TSRMLS_CC ) ;
2014-10-05 11:57:35 +00:00
# if PHP_VERSION_ID < 50500
zend_execute = phpdbg_execute_ex ;
# else
2014-10-05 11:29:56 +00:00
zend_execute_ex = phpdbg_execute_ex ;
2014-10-05 11:57:35 +00:00
# endif
2013-11-21 23:19:55 +00:00
2013-11-17 12:07:01 +00:00
if ( PHPDBG_G ( vmret ) > 0 ) {
switch ( PHPDBG_G ( vmret ) ) {
case 1 :
EG ( in_execution ) = original_in_execution ;
2013-11-21 13:35:39 +00:00
zend_hash_destroy ( & vars ) ;
2013-11-17 12:07:01 +00:00
return ;
case 2 :
2013-11-15 11:19:26 +00:00
# if PHP_VERSION_ID < 50500
2013-11-17 12:07:01 +00:00
op_array = EG ( active_op_array ) ;
2013-11-15 11:19:26 +00:00
# endif
2013-11-21 13:35:39 +00:00
zend_hash_destroy ( & vars ) ;
2013-11-17 12:07:01 +00:00
goto zend_vm_enter ;
break ;
case 3 :
execute_data = EG ( current_execute_data ) ;
break ;
default :
2013-11-10 13:01:46 +00:00
break ;
}
}
}
zend_error_noreturn ( E_ERROR , " Arrived at end of main loop which shouldn't happen " ) ;
2013-11-10 18:21:49 +00:00
} /* }}} */
2014-09-28 00:57:12 +00:00
2014-10-02 23:29:41 +00:00
/* only if *not* interactive and while executing */
2014-09-28 00:57:12 +00:00
void phpdbg_force_interruption ( TSRMLS_D ) {
zend_execute_data * data = EG ( current_execute_data ) ; /* should be always readable if not NULL */
2014-10-02 23:29:41 +00:00
PHPDBG_G ( flags ) | = PHPDBG_IN_SIGNAL_HANDLER ;
2014-09-28 00:57:12 +00:00
if ( data ) {
if ( data - > op_array ) {
2014-10-07 11:08:30 +00:00
phpdbg_notice ( " hardinterrupt " , " opline= \" %p \" num= \" %lu \" file= \" %s \" line= \" %u \" " , " Current opline: %p (op #%lu) in %s:%u " , data - > opline , ( data - > opline - data - > op_array - > opcodes ) / sizeof ( data - > opline ) , data - > op_array - > filename , data - > opline - > lineno ) ;
2014-09-28 00:57:12 +00:00
} else {
2014-10-07 11:08:30 +00:00
phpdbg_notice ( " hardinterrupt " , " opline= \" %p \" " , " Current opline: %p (op_array information unavailable) " , data - > opline ) ;
2014-09-28 00:57:12 +00:00
}
} else {
2014-10-07 11:08:30 +00:00
phpdbg_notice ( " hardinterrupt " , " " , " No information available about executing context " ) ;
2014-09-28 00:57:12 +00:00
}
2014-10-02 23:29:41 +00:00
DO_INTERACTIVE ( 0 ) ;
next :
PHPDBG_G ( flags ) & = ~ PHPDBG_IN_SIGNAL_HANDLER ;
if ( PHPDBG_G ( flags ) & PHPDBG_IS_QUITTING ) {
zend_bailout ( ) ;
}
2014-09-28 00:57:12 +00:00
}