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"
# 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"
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-02-19 00:33:49 +00:00
PHPDBG_COMMAND_D ( exec , " set execution context " , ' e ' , NULL , " s " ) ,
2014-04-20 14:47:24 +00:00
PHPDBG_COMMAND_D ( step , " step through execution " , ' s ' , NULL , 0 ) ,
2014-04-20 16:10:52 +00:00
PHPDBG_COMMAND_D ( continue , " continue execution " , ' c ' , NULL , 0 ) ,
2014-04-13 07:43:19 +00:00
PHPDBG_COMMAND_D ( run , " attempt execution " , ' r ' , NULL , " |s " ) ,
2014-09-21 02:17:19 +00:00
PHPDBG_COMMAND_D ( ev , " evaluate some code " , 0 , NULL , " i " ) ,
2013-11-18 00:42:07 +00:00
PHPDBG_COMMAND_D ( until , " continue past the current line " , ' u ' , NULL , 0 ) ,
2013-11-22 17:27:55 +00:00
PHPDBG_COMMAND_D ( finish , " continue past the end of the stack " , ' F ' , NULL , 0 ) ,
2013-11-17 21:01:41 +00:00
PHPDBG_COMMAND_D ( leave , " continue until the end of the stack " , ' L ' , NULL , 0 ) ,
2014-02-21 20:42:15 +00:00
PHPDBG_COMMAND_D ( print , " print something " , ' p ' , phpdbg_print_commands , 0 ) ,
PHPDBG_COMMAND_D ( break , " set breakpoint " , ' b ' , phpdbg_break_commands , " |*c " ) ,
2014-02-19 20:18:49 +00:00
PHPDBG_COMMAND_D ( back , " show trace " , ' t ' , NULL , " |n " ) ,
PHPDBG_COMMAND_D ( frame , " switch to a frame " , ' f ' , NULL , " |n " ) ,
2014-02-19 00:33:49 +00:00
PHPDBG_COMMAND_D ( list , " lists some code " , ' l ' , phpdbg_list_commands , " * " ) ,
PHPDBG_COMMAND_D ( info , " displays some informations " , ' i ' , phpdbg_info_commands , " s " ) ,
2013-11-17 21:01:41 +00:00
PHPDBG_COMMAND_D ( clean , " clean the execution environment " , ' X ' , NULL , 0 ) ,
PHPDBG_COMMAND_D ( clear , " clear breakpoints " , ' C ' , NULL , 0 ) ,
2014-02-19 00:33:49 +00:00
PHPDBG_COMMAND_D ( help , " show help menu " , ' h ' , phpdbg_help_commands , " |s " ) ,
PHPDBG_COMMAND_D ( set , " set phpdbg configuration " , ' S ' , phpdbg_set_commands , " s " ) ,
PHPDBG_COMMAND_D ( register , " register a function " , ' R ' , NULL , " s " ) ,
2014-02-24 19:03:55 +00:00
PHPDBG_COMMAND_D ( source , " execute a phpdbginit " , ' < ' , NULL , " s " ) ,
PHPDBG_COMMAND_D ( export , " export breaks to a .phpdbginit script " , ' > ' , NULL , " s " ) ,
2014-09-21 02:17:19 +00:00
PHPDBG_COMMAND_D ( sh , " shell a command " , 0 , NULL , " i " ) ,
2013-11-17 21:01:41 +00:00
PHPDBG_COMMAND_D ( quit , " exit phpdbg " , ' q ' , NULL , 0 ) ,
2014-04-13 10:42:47 +00:00
PHPDBG_COMMAND_D ( watch , " set watchpoint " , ' w ' , phpdbg_watch_commands , " |ss " ) ,
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
2013-11-10 11:03:29 +00:00
ZEND_EXTERN_MODULE_GLOBALS ( phpdbg ) ;
2013-11-14 14:14:13 +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 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-09-21 02:17:19 +00:00
switch ( phpdbg_stack_execute ( & stack 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-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-21 02:17:19 +00:00
phpdbg_error ( " compile " , " 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-21 02:17:19 +00:00
phpdbg_error ( " compile " , " 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-21 02:17:19 +00:00
phpdbg_error ( " compile " , " 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-21 02:17:19 +00:00
phpdbg_error ( " until " , " 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-21 02:17:19 +00:00
phpdbg_error ( " finish " , " 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-21 02:17:19 +00:00
phpdbg_error ( " leave " , " 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-21 02:17:19 +00:00
phpdbg_notice ( " frame " , " num= \" %d \" " , " Currently in frame #%d " , PHPDBG_G ( frame ) . num ) ;
} 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-21 02:17:19 +00:00
phpdbg_error ( " run " , " 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-01-17 21:08:35 +00:00
2013-11-10 18:29:05 +00:00
if ( ! PHPDBG_G ( ops ) ) {
if ( phpdbg_compile ( TSRMLS_C ) = = FAILURE ) {
2014-09-21 02:17:19 +00:00
phpdbg_error ( " run " , " 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-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-04-13 07:43:19 +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-20 14:19:15 +00:00
php_output_activate ( TSRMLS_C ) ;
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 ;
2013-11-20 14:19:15 +00:00
php_output_deactivate ( TSRMLS_C ) ;
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-09-21 02:17:19 +00:00
phpdbg_error ( " run " , " 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-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-21 02:17:19 +00:00
phpdbg_error ( " run " , " type= \" noexec \" " , " 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-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-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-09-21 02:17:19 +00:00
phpdbg_error ( " back " , " 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-21 02:17:19 +00:00
phpdbg_error ( " break " , " 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
} /* }}} */
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-21 02:17:19 +00:00
phpdbg_error ( " source " , " type= \" nofile \" 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-21 02:17:19 +00:00
phpdbg_error ( " register " , " type= \" notfound \" 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-21 02:17:19 +00:00
phpdbg_error ( " clean " , " 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-21 02:17:19 +00:00
phpdbg_out ( " Cleaning Execution Environment " ) ;
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-21 02:17:19 +00:00
phpdbg_out ( " Clearing Breakpoints " ) ;
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 ;
} /* }}} */
2013-11-11 08:08:26 +00:00
int phpdbg_interactive ( TSRMLS_D ) /* { { { */
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 ) ;
switch ( ret = phpdbg_stack_execute ( & stack 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-02-21 20:42:15 +00:00
if ( 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-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-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
} /* }}} */
# 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 ) ;
}
2013-12-09 09:33:32 +00:00
2013-11-10 13:01:46 +00:00
# ifdef ZEND_WIN32
if ( EG ( timed_out ) ) {
zend_timeout ( 0 ) ;
}
# endif
2013-11-26 10:02:58 +00:00
# define DO_INTERACTIVE() do { \
if ( ! ( PHPDBG_G ( flags ) & PHPDBG_IN_EVAL ) ) { \
phpdbg_list_file ( \
2013-11-20 17:01:37 +00:00
zend_get_executed_filename ( TSRMLS_C ) , \
3 , \
zend_get_executed_lineno ( TSRMLS_C ) - 1 , \
zend_get_executed_lineno ( TSRMLS_C ) \
2013-11-26 10:02:58 +00:00
TSRMLS_CC \
) ; \
} \
2013-11-17 12:07:01 +00:00
\
2014-04-16 18:55:41 +00:00
/* do { */ \
2013-11-26 10:02:58 +00:00
switch ( phpdbg_interactive ( TSRMLS_C ) ) { \
case PHPDBG_LEAVE : \
case PHPDBG_FINISH : \
case PHPDBG_UNTIL : \
case PHPDBG_NEXT : { \
goto next ; \
} \
} \
2014-04-16 18:55:41 +00:00
/* } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); */ \
2013-11-26 10:02:58 +00:00
} while ( 0 )
2013-11-13 14:41:25 +00:00
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 )
) ;
DO_INTERACTIVE ( ) ;
} 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 ;
DO_INTERACTIVE ( ) ;
}
2013-12-13 22:57:36 +00:00
/* check if some watchpoint was hit */
{
if ( phpdbg_print_changed_zvals ( TSRMLS_C ) = = SUCCESS ) {
DO_INTERACTIVE ( ) ;
}
}
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 ) ;
2013-11-27 13:01:57 +00:00
DO_INTERACTIVE ( ) ;
}
2013-11-23 22:03:17 +00:00
}
2013-11-14 16:14:20 +00:00
next :
2013-11-20 19:16:07 +00:00
if ( 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 " ) ;
2013-11-20 19:16:07 +00:00
PHPDBG_G ( flags ) & = ~ PHPDBG_IS_SIGNALED ;
DO_INTERACTIVE ( ) ;
}
2014-04-20 11:25:28 +00:00
PHPDBG_G ( last_line ) = execute_data - > opline - > lineno ;
2013-11-21 23:19:55 +00:00
PHPDBG_G ( vmret ) = execute_data - > opline - > handler ( execute_data TSRMLS_CC ) ;
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
} /* }}} */