12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574 |
- /*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2016 The PHP Group |
- +----------------------------------------------------------------------+
- | 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> |
- | Authors: Joe Watkins <joe.watkins@live.co.uk> |
- | Authors: Bob Weinand <bwoebi@php.net> |
- +----------------------------------------------------------------------+
- */
- #if !defined(ZEND_SIGNALS) || defined(_WIN32)
- # include <signal.h>
- #endif
- #include "phpdbg.h"
- #include "phpdbg_prompt.h"
- #include "phpdbg_bp.h"
- #include "phpdbg_break.h"
- #include "phpdbg_list.h"
- #include "phpdbg_utils.h"
- #include "phpdbg_set.h"
- #include "zend_alloc.h"
- /* {{{ remote console headers */
- #ifndef _WIN32
- # include <sys/socket.h>
- # include <sys/select.h>
- # include <sys/time.h>
- # include <sys/types.h>
- # include <netinet/in.h>
- # include <unistd.h>
- # include <arpa/inet.h>
- #endif /* }}} */
- #if defined(PHP_WIN32) && defined(HAVE_OPENSSL)
- # include "openssl/applink.c"
- #endif
- ZEND_DECLARE_MODULE_GLOBALS(phpdbg);
- static zend_bool phpdbg_booted = 0;
- #if PHP_VERSION_ID >= 50500
- void (*zend_execute_old)(zend_execute_data *execute_data TSRMLS_DC);
- #else
- void (*zend_execute_old)(zend_op_array *op_array TSRMLS_DC);
- #endif
- static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
- {
- pg->prompt[0] = NULL;
- pg->prompt[1] = NULL;
- pg->colors[0] = NULL;
- pg->colors[1] = NULL;
- pg->colors[2] = NULL;
- pg->exec = NULL;
- pg->exec_len = 0;
- pg->buffer = NULL;
- pg->ops = NULL;
- pg->vmret = 0;
- pg->bp_count = 0;
- pg->flags = PHPDBG_DEFAULT_FLAGS;
- pg->oplog = NULL;
- pg->io[PHPDBG_STDIN] = NULL;
- pg->io[PHPDBG_STDOUT] = NULL;
- pg->io[PHPDBG_STDERR] = NULL;
- pg->frame.num = 0;
- } /* }}} */
- static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
- {
- ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
- #if PHP_VERSION_ID >= 50500
- zend_execute_old = zend_execute_ex;
- zend_execute_ex = phpdbg_execute_ex;
- #else
- zend_execute_old = zend_execute;
- zend_execute = phpdbg_execute_ex;
- #endif
- REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT);
-
- REGISTER_LONG_CONSTANT("PHPDBG_FILE", FILE_PARAM, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_METHOD", METHOD_PARAM, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_LINENO", NUMERIC_PARAM, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_FUNC", STR_PARAM, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_COLOR_PROMPT", PHPDBG_COLOR_PROMPT, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_COLOR_NOTICE", PHPDBG_COLOR_NOTICE, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_COLOR_ERROR", PHPDBG_COLOR_ERROR, CONST_CS|CONST_PERSISTENT);
- return SUCCESS;
- } /* }}} */
- static void php_phpdbg_destroy_bp_file(void *brake) /* {{{ */
- {
- zend_hash_destroy((HashTable*)brake);
- } /* }}} */
- static void php_phpdbg_destroy_bp_symbol(void *brake) /* {{{ */
- {
- efree((char*)((phpdbg_breaksymbol_t*)brake)->symbol);
- } /* }}} */
- static void php_phpdbg_destroy_bp_opcode(void *brake) /* {{{ */
- {
- efree((char*)((phpdbg_breakop_t*)brake)->name);
- } /* }}} */
- static void php_phpdbg_destroy_bp_methods(void *brake) /* {{{ */
- {
- zend_hash_destroy((HashTable*)brake);
- } /* }}} */
- static void php_phpdbg_destroy_bp_condition(void *data) /* {{{ */
- {
- phpdbg_breakcond_t *brake = (phpdbg_breakcond_t*) data;
- if (brake) {
- if (brake->ops) {
- TSRMLS_FETCH();
- destroy_op_array(
- brake->ops TSRMLS_CC);
- efree(brake->ops);
- }
- efree((char*)brake->code);
- }
- } /* }}} */
- static void php_phpdbg_destroy_registered(void *data) /* {{{ */
- {
- zend_function *function = (zend_function*) data;
- TSRMLS_FETCH();
- destroy_zend_function(
- function TSRMLS_CC);
- } /* }}} */
- static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
- {
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], 8, NULL, php_phpdbg_destroy_bp_symbol, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], 8, NULL, NULL, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], 8, NULL, php_phpdbg_destroy_bp_opcode, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0);
- zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0);
- zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
- zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0);
- return SUCCESS;
- } /* }}} */
- static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
- {
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
- zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]);
- zend_hash_destroy(&PHPDBG_G(seek));
- zend_hash_destroy(&PHPDBG_G(registered));
- zend_hash_destroy(&PHPDBG_G(watchpoints));
- zend_llist_destroy(&PHPDBG_G(watchlist_mem));
- if (PHPDBG_G(buffer)) {
- efree(PHPDBG_G(buffer));
- PHPDBG_G(buffer) = NULL;
- }
-
- if (PHPDBG_G(exec)) {
- efree(PHPDBG_G(exec));
- PHPDBG_G(exec) = NULL;
- }
- if (PHPDBG_G(prompt)[0]) {
- free(PHPDBG_G(prompt)[0]);
- }
- if (PHPDBG_G(prompt)[1]) {
- free(PHPDBG_G(prompt)[1]);
- }
- PHPDBG_G(prompt)[0] = NULL;
- PHPDBG_G(prompt)[1] = NULL;
- if (PHPDBG_G(oplog)) {
- fclose(
- PHPDBG_G(oplog));
- PHPDBG_G(oplog) = NULL;
- }
- if (PHPDBG_G(ops)) {
- destroy_op_array(PHPDBG_G(ops) TSRMLS_CC);
- efree(PHPDBG_G(ops));
- PHPDBG_G(ops) = NULL;
- }
- return SUCCESS;
- } /* }}} */
- /* {{{ proto mixed phpdbg_exec(string context)
- Attempt to set the execution context for phpdbg
- If the execution context was set previously it is returned
- If the execution context was not set previously boolean true is returned
- If the request to set the context fails, boolean false is returned, and an E_WARNING raised */
- static PHP_FUNCTION(phpdbg_exec)
- {
- char *exec = NULL;
- int exec_len = 0;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &exec, &exec_len) == FAILURE) {
- return;
- }
- {
- struct stat sb;
- zend_bool result = 1;
- if (VCWD_STAT(exec, &sb) != FAILURE) {
- if (sb.st_mode & (S_IFREG|S_IFLNK)) {
- if (PHPDBG_G(exec)) {
- ZVAL_STRINGL(return_value, PHPDBG_G(exec), PHPDBG_G(exec_len), 1);
- efree(PHPDBG_G(exec));
- result = 0;
- }
- PHPDBG_G(exec) = estrndup(exec, exec_len);
- PHPDBG_G(exec_len) = exec_len;
- if (result)
- ZVAL_BOOL(return_value, 1);
- } else {
- zend_error(
- E_WARNING, "Failed to set execution context (%s), not a regular file or symlink", exec);
- ZVAL_BOOL(return_value, 0);
- }
- } else {
- zend_error(
- E_WARNING, "Failed to set execution context (%s) the file does not exist", exec);
- ZVAL_BOOL(return_value, 0);
- }
- }
- } /* }}} */
- /* {{{ proto void phpdbg_break_next()
- instructs phpdbg to insert a breakpoint at the next opcode */
- static PHP_FUNCTION(phpdbg_break_next)
- {
- if (zend_parse_parameters_none() != SUCCESS) {
- return;
- } else if (EG(current_execute_data) && EG(active_op_array)) {
- zend_ulong opline_num = (EG(current_execute_data)->opline -
- EG(active_op_array)->opcodes);
- phpdbg_set_breakpoint_opline_ex(
- &EG(active_op_array)->opcodes[opline_num+1] TSRMLS_CC);
- }
- } /* }}} */
- /* {{{ proto void phpdbg_break_file(string file, integer line) */
- static PHP_FUNCTION(phpdbg_break_file)
- {
- char *file = NULL;
- int flen = 0;
- long line;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &file, &flen, &line) == FAILURE) {
- return;
- }
- phpdbg_set_breakpoint_file(file, line TSRMLS_CC);
- } /* }}} */
- /* {{{ proto void phpdbg_break_method(string class, string method) */
- static PHP_FUNCTION(phpdbg_break_method)
- {
- char *class = NULL,
- *method = NULL;
- int clen = 0,
- mlen = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &class, &clen, &method, &mlen) == FAILURE) {
- return;
- }
- phpdbg_set_breakpoint_method(class, method TSRMLS_CC);
- } /* }}} */
- /* {{{ proto void phpdbg_break_function(string function) */
- static PHP_FUNCTION(phpdbg_break_function)
- {
- char *function = NULL;
- int function_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &function, &function_len) == FAILURE) {
- return;
- }
- phpdbg_set_breakpoint_symbol(function, function_len TSRMLS_CC);
- } /* }}} */
- /* {{{ proto void phpdbg_clear(void)
- instructs phpdbg to clear breakpoints */
- static PHP_FUNCTION(phpdbg_clear)
- {
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
- } /* }}} */
- /* {{{ proto void phpdbg_color(integer element, string color) */
- static PHP_FUNCTION(phpdbg_color)
- {
- long element = 0L;
- char *color = NULL;
- int color_len = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &element, &color, &color_len) == FAILURE) {
- return;
- }
- switch (element) {
- case PHPDBG_COLOR_NOTICE:
- case PHPDBG_COLOR_ERROR:
- case PHPDBG_COLOR_PROMPT:
- phpdbg_set_color_ex(element, color, color_len TSRMLS_CC);
- break;
- default: zend_error(E_ERROR, "phpdbg detected an incorrect color constant");
- }
- } /* }}} */
- /* {{{ proto void phpdbg_prompt(string prompt) */
- static PHP_FUNCTION(phpdbg_prompt)
- {
- char *prompt = NULL;
- int prompt_len = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &prompt, &prompt_len) == FAILURE) {
- return;
- }
- phpdbg_set_prompt(prompt TSRMLS_CC);
- } /* }}} */
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_break_next_arginfo, 0, 0, 0)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_break_file_arginfo, 0, 0, 2)
- ZEND_ARG_INFO(0, file)
- ZEND_ARG_INFO(0, line)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_break_method_arginfo, 0, 0, 2)
- ZEND_ARG_INFO(0, class)
- ZEND_ARG_INFO(0, method)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_break_function_arginfo, 0, 0, 1)
- ZEND_ARG_INFO(0, function)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_color_arginfo, 0, 0, 0)
- ZEND_ARG_INFO(0, element)
- ZEND_ARG_INFO(0, color)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_prompt_arginfo, 0, 0, 0)
- ZEND_ARG_INFO(0, string)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_exec_arginfo, 0, 0, 0)
- ZEND_ARG_INFO(0, context)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(phpdbg_clear_arginfo, 0, 0, 0)
- ZEND_END_ARG_INFO()
- zend_function_entry phpdbg_user_functions[] = {
- PHP_FE(phpdbg_clear, phpdbg_clear_arginfo)
- PHP_FE(phpdbg_break_next, phpdbg_break_next_arginfo)
- PHP_FE(phpdbg_break_file, phpdbg_break_file_arginfo)
- PHP_FE(phpdbg_break_method, phpdbg_break_method_arginfo)
- PHP_FE(phpdbg_break_function, phpdbg_break_function_arginfo)
- PHP_FE(phpdbg_exec, phpdbg_exec_arginfo)
- PHP_FE(phpdbg_color, phpdbg_color_arginfo)
- PHP_FE(phpdbg_prompt, phpdbg_prompt_arginfo)
- #ifdef PHP_FE_END
- PHP_FE_END
- #else
- {NULL,NULL,NULL}
- #endif
- };
- static zend_module_entry sapi_phpdbg_module_entry = {
- STANDARD_MODULE_HEADER,
- PHPDBG_NAME,
- phpdbg_user_functions,
- PHP_MINIT(phpdbg),
- NULL,
- PHP_RINIT(phpdbg),
- PHP_RSHUTDOWN(phpdbg),
- NULL,
- PHPDBG_VERSION,
- STANDARD_MODULE_PROPERTIES
- };
- static inline int php_sapi_phpdbg_module_startup(sapi_module_struct *module) /* {{{ */
- {
- if (php_module_startup(module, &sapi_phpdbg_module_entry, 1) == FAILURE) {
- return FAILURE;
- }
- phpdbg_booted=1;
- return SUCCESS;
- } /* }}} */
- static char* php_sapi_phpdbg_read_cookies(TSRMLS_D) /* {{{ */
- {
- return NULL;
- } /* }}} */
- static int php_sapi_phpdbg_header_handler(sapi_header_struct *h, sapi_header_op_enum op, sapi_headers_struct *s TSRMLS_DC) /* {{{ */
- {
- return 0;
- }
- /* }}} */
- static int php_sapi_phpdbg_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) /* {{{ */
- {
- /* We do nothing here, this function is needed to prevent that the fallback
- * header handling is called. */
- return SAPI_HEADER_SENT_SUCCESSFULLY;
- }
- /* }}} */
- static void php_sapi_phpdbg_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC) /* {{{ */
- {
- }
- /* }}} */
- static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */
- {
- /*
- * We must not request TSRM before being boot
- */
- if (phpdbg_booted) {
- phpdbg_error("%s", message);
- switch (PG(last_error_type)) {
- case E_ERROR:
- case E_CORE_ERROR:
- case E_COMPILE_ERROR:
- case E_USER_ERROR:
- case E_PARSE:
- case E_RECOVERABLE_ERROR:
- 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
- );
- }
- do {
- switch (phpdbg_interactive(TSRMLS_C)) {
- case PHPDBG_LEAVE:
- case PHPDBG_FINISH:
- case PHPDBG_UNTIL:
- case PHPDBG_NEXT:
- return;
- }
- } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING));
- }
- } else fprintf(stdout, "%s\n", message);
- }
- /* }}} */
- static int php_sapi_phpdbg_deactivate(TSRMLS_D) /* {{{ */
- {
- fflush(stdout);
- if(SG(request_info).argv0) {
- free(SG(request_info).argv0);
- SG(request_info).argv0 = NULL;
- }
- return SUCCESS;
- }
- /* }}} */
- static void php_sapi_phpdbg_register_vars(zval *track_vars_array TSRMLS_DC) /* {{{ */
- {
- unsigned int len;
- char *docroot = "";
- /* In phpdbg mode, we consider the environment to be a part of the server variables
- */
- php_import_environment_variables(track_vars_array TSRMLS_CC);
- if (PHPDBG_G(exec)) {
- len = PHPDBG_G(exec_len);
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("PHP_SELF", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
- }
- if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("SCRIPT_NAME", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
- }
- if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("SCRIPT_FILENAME", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
- }
- if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("PATH_TRANSLATED", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
- }
- }
- /* any old docroot will doo */
- len = 0U;
- if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT",
- &docroot, len, &len TSRMLS_CC)) {
- php_register_variable("DOCUMENT_ROOT", docroot, track_vars_array TSRMLS_CC);
- }
- }
- /* }}} */
- static inline int php_sapi_phpdbg_ub_write(const char *message, unsigned int length TSRMLS_DC) /* {{{ */
- {
- return phpdbg_write("%s", message);
- } /* }}} */
- #if PHP_VERSION_ID >= 50700
- static inline void php_sapi_phpdbg_flush(void *context TSRMLS_DC) /* {{{ */
- {
- #else
- static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */
- {
- TSRMLS_FETCH();
- #endif
- fflush(PHPDBG_G(io)[PHPDBG_STDOUT]);
- } /* }}} */
- /* copied from sapi/cli/php_cli.c cli_register_file_handles */
- static void phpdbg_register_file_handles(TSRMLS_D) /* {{{ */
- {
- zval *zin, *zout, *zerr;
- php_stream *s_in, *s_out, *s_err;
- php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
- zend_constant ic, oc, ec;
- MAKE_STD_ZVAL(zin);
- MAKE_STD_ZVAL(zout);
- MAKE_STD_ZVAL(zerr);
- s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
- s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
- s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
- if (s_in==NULL || s_out==NULL || s_err==NULL) {
- FREE_ZVAL(zin);
- FREE_ZVAL(zout);
- FREE_ZVAL(zerr);
- if (s_in) php_stream_close(s_in);
- if (s_out) php_stream_close(s_out);
- if (s_err) php_stream_close(s_err);
- return;
- }
- #if PHP_DEBUG
- /* do not close stdout and stderr */
- s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
- s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
- #endif
- php_stream_to_zval(s_in, zin);
- php_stream_to_zval(s_out, zout);
- php_stream_to_zval(s_err, zerr);
- ic.value = *zin;
- ic.flags = CONST_CS;
- ic.name = zend_strndup(ZEND_STRL("STDIN"));
- ic.name_len = sizeof("STDIN");
- ic.module_number = 0;
- zend_register_constant(&ic TSRMLS_CC);
- oc.value = *zout;
- oc.flags = CONST_CS;
- oc.name = zend_strndup(ZEND_STRL("STDOUT"));
- oc.name_len = sizeof("STDOUT");
- oc.module_number = 0;
- zend_register_constant(&oc TSRMLS_CC);
- ec.value = *zerr;
- ec.flags = CONST_CS;
- ec.name = zend_strndup(ZEND_STRL("STDERR"));
- ec.name_len = sizeof("STDERR");
- ec.module_number = 0;
- zend_register_constant(&ec TSRMLS_CC);
- FREE_ZVAL(zin);
- FREE_ZVAL(zout);
- FREE_ZVAL(zerr);
- }
- /* }}} */
- /* {{{ sapi_module_struct phpdbg_sapi_module
- */
- static sapi_module_struct phpdbg_sapi_module = {
- "phpdbg", /* name */
- "phpdbg", /* pretty name */
- php_sapi_phpdbg_module_startup, /* startup */
- php_module_shutdown_wrapper, /* shutdown */
- NULL, /* activate */
- php_sapi_phpdbg_deactivate, /* deactivate */
- php_sapi_phpdbg_ub_write, /* unbuffered write */
- php_sapi_phpdbg_flush, /* flush */
- NULL, /* get uid */
- NULL, /* getenv */
- php_error, /* error handler */
- php_sapi_phpdbg_header_handler, /* header handler */
- php_sapi_phpdbg_send_headers, /* send headers handler */
- php_sapi_phpdbg_send_header, /* send header handler */
- NULL, /* read POST data */
- php_sapi_phpdbg_read_cookies, /* read Cookies */
- php_sapi_phpdbg_register_vars, /* register server variables */
- php_sapi_phpdbg_log_message, /* Log message */
- NULL, /* Get request time */
- NULL, /* Child terminate */
- STANDARD_SAPI_MODULE_PROPERTIES
- };
- /* }}} */
- const opt_struct OPTIONS[] = { /* {{{ */
- {'c', 1, "ini path override"},
- {'d', 1, "define ini entry on command line"},
- {'n', 0, "no php.ini"},
- {'z', 1, "load zend_extension"},
- /* phpdbg options */
- {'q', 0, "no banner"},
- {'v', 0, "disable quietness"},
- {'s', 0, "enable stepping"},
- {'b', 0, "boring colours"},
- {'i', 1, "specify init"},
- {'I', 0, "ignore init"},
- {'O', 1, "opline log"},
- {'r', 0, "run"},
- {'E', 0, "step-through-eval"},
- {'S', 1, "sapi-name"},
- #ifndef _WIN32
- {'l', 1, "listen"},
- {'a', 1, "address-or-any"},
- #endif
- {'V', 0, "version"},
- {'-', 0, NULL}
- }; /* }}} */
- const char phpdbg_ini_hardcoded[] =
- "html_errors=Off\n"
- "register_argc_argv=On\n"
- "implicit_flush=On\n"
- "display_errors=Off\n"
- "log_errors=On\n"
- "max_execution_time=0\n"
- "max_input_time=-1\n"
- "error_log=\n"
- "output_buffering=off\0";
- /* overwriteable ini defaults must be set in phpdbg_ini_defaults() */
- #define INI_DEFAULT(name, value) \
- Z_SET_REFCOUNT(tmp, 0); \
- Z_UNSET_ISREF(tmp); \
- ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0); \
- zend_hash_update(configuration_hash, name, sizeof(name), &tmp, sizeof(zval), NULL);
- void phpdbg_ini_defaults(HashTable *configuration_hash) /* {{{ */
- {
- zval tmp;
- INI_DEFAULT("report_zend_debug", "0");
- } /* }}} */
- static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */
- {
- /* print blurb */
- if (!cleaning) {
- phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s",
- PHPDBG_VERSION);
- phpdbg_writeln("To get help using phpdbg type \"help\" and press enter");
- phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES);
- } else {
- phpdbg_notice("Clean Execution Environment");
- phpdbg_writeln("Classes\t\t\t%d", zend_hash_num_elements(EG(class_table)));
- phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(EG(function_table)));
- phpdbg_writeln("Constants\t\t%d", zend_hash_num_elements(EG(zend_constants)));
- phpdbg_writeln("Includes\t\t%d", zend_hash_num_elements(&EG(included_files)));
- }
- } /* }}} */
- static inline void phpdbg_sigint_handler(int signo) /* {{{ */
- {
- TSRMLS_FETCH();
- if (EG(in_execution)) {
- /* set signalled only when not interactive */
- if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) {
- PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED;
- }
- } else {
- /* we quit remote consoles on recv SIGINT */
- if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
- PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
- zend_bailout();
- }
- }
- } /* }}} */
- #ifndef _WIN32
- int phpdbg_open_socket(const char *interface, short port) /* {{{ */
- {
- int fd = socket(AF_INET, SOCK_STREAM, 0);
- switch (fd) {
- case -1:
- return -1;
- default: {
- int reuse = 1;
- switch (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse))) {
- case -1:
- close(fd);
- return -2;
- default: {
- struct sockaddr_in address;
- memset(&address, 0, sizeof(address));
- address.sin_port = htons(port);
- address.sin_family = AF_INET;
- if ((*interface == '*')) {
- address.sin_addr.s_addr = htonl(INADDR_ANY);
- } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) {
- close(fd);
- return -3;
- }
- switch (bind(fd, (struct sockaddr *)&address, sizeof(address))) {
- case -1:
- close(fd);
- return -4;
- default: {
- listen(fd, 5);
- }
- }
- }
- }
- }
- }
- return fd;
- } /* }}} */
- static inline void phpdbg_close_sockets(int (*socket)[2], FILE *streams[2]) /* {{{ */
- {
- if ((*socket)[0] >= 0) {
- shutdown(
- (*socket)[0], SHUT_RDWR);
- close((*socket)[0]);
- }
- if (streams[0]) {
- fclose(streams[0]);
- }
- if ((*socket)[1] >= 0) {
- shutdown(
- (*socket)[1], SHUT_RDWR);
- close((*socket)[1]);
- }
- if (streams[1]) {
- fclose(streams[1]);
- }
- } /* }}} */
- /* don't inline this, want to debug it easily, will inline when done */
- int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*socket)[2], FILE* streams[2]) /* {{{ */
- {
- if (((*listen)[0]) < 0 && ((*listen)[1]) < 0) {
- ((*listen)[0]) = phpdbg_open_socket(address, (short)port[0]);
- ((*listen)[1]) = phpdbg_open_socket(address, (short)port[1]);
- }
- streams[0] = NULL;
- streams[1] = NULL;
- if ((*listen)[0] < 0 || (*listen)[1] < 0) {
- if ((*listen)[0] < 0) {
- phpdbg_rlog(stderr,
- "console failed to initialize (stdin) on %s:%d", address, port[0]);
- }
- if ((*listen)[1] < 0) {
- phpdbg_rlog(stderr,
- "console failed to initialize (stdout) on %s:%d", address, port[1]);
- }
- if ((*listen)[0] >= 0) {
- close((*listen)[0]);
- }
- if ((*listen)[1] >= 0) {
- close((*listen)[1]);
- }
- return FAILURE;
- }
- phpdbg_close_sockets(socket, streams);
- phpdbg_rlog(stderr,
- "accepting connections on %s:%d/%d", address, port[0], port[1]);
- {
- struct sockaddr_in address;
- socklen_t size = sizeof(address);
- char buffer[20] = {0};
- {
- memset(&address, 0, size);
- (*socket)[0] = accept(
- (*listen)[0], (struct sockaddr *) &address, &size);
- inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer));
- phpdbg_rlog(stderr, "connection (stdin) from %s", buffer);
- }
- {
- memset(&address, 0, size);
- (*socket)[1] = accept(
- (*listen)[1], (struct sockaddr *) &address, &size);
- inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer));
- phpdbg_rlog(stderr, "connection (stdout) from %s", buffer);
- }
- }
- dup2((*socket)[0], fileno(stdin));
- dup2((*socket)[1], fileno(stdout));
- setbuf(stdout, NULL);
- streams[0] = fdopen((*socket)[0], "r");
- streams[1] = fdopen((*socket)[1], "w");
- return SUCCESS;
- } /* }}} */
- void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
- {
- int is_handled = FAILURE;
- TSRMLS_FETCH();
- switch (sig) {
- case SIGBUS:
- case SIGSEGV:
- is_handled = phpdbg_watchpoint_segfault_handler(info, context TSRMLS_CC);
- if (is_handled == FAILURE) {
- #ifdef ZEND_SIGNALS
- zend_sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL TSRMLS_CC);
- #else
- sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL);
- #endif
- }
- break;
- }
- } /* }}} */
- #endif
- static inline zend_mm_heap *phpdbg_mm_get_heap() /* {{{ */
- {
- zend_mm_heap *mm_heap;
- TSRMLS_FETCH();
- mm_heap = zend_mm_set_heap(NULL TSRMLS_CC);
- zend_mm_set_heap(mm_heap TSRMLS_CC);
- return mm_heap;
- } /* }}} */
- void *phpdbg_malloc_wrapper(size_t size) /* {{{ */
- {
- return zend_mm_alloc(phpdbg_mm_get_heap(), size);
- } /* }}} */
- void phpdbg_free_wrapper(void *p) /* {{{ */
- {
- zend_mm_free(phpdbg_mm_get_heap(), p);
- } /* }}} */
- void *phpdbg_realloc_wrapper(void *ptr, size_t size) /* {{{ */
- {
- return zend_mm_realloc(phpdbg_mm_get_heap(), ptr, size);
- } /* }}} */
- int main(int argc, char **argv) /* {{{ */
- {
- sapi_module_struct *phpdbg = &phpdbg_sapi_module;
- char *sapi_name;
- char *ini_entries;
- int ini_entries_len;
- char **zend_extensions = NULL;
- zend_ulong zend_extensions_len = 0L;
- zend_bool ini_ignore;
- char *ini_override;
- char *exec;
- size_t exec_len;
- char *init_file;
- size_t init_file_len;
- zend_bool init_file_default;
- char *oplog_file;
- size_t oplog_file_len;
- zend_ulong flags;
- char *php_optarg;
- int php_optind, opt, show_banner = 1;
- long cleaning = 0;
- zend_bool remote = 0;
- int run = 0;
- int step = 0;
- #ifdef _WIN32
- char *bp_tmp_file = NULL;
- #else
- char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX";
- #endif
- #ifndef _WIN32
- char *address;
- int listen[2];
- int server[2];
- int socket[2];
- FILE* streams[2] = {NULL, NULL};
- #endif
- #ifdef ZTS
- void ***tsrm_ls;
- #endif
- #ifndef _WIN32
- struct sigaction signal_struct;
- signal_struct.sa_sigaction = phpdbg_signal_handler;
- signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER;
- address = strdup("127.0.0.1");
- socket[0] = -1;
- socket[1] = -1;
- listen[0] = -1;
- listen[1] = -1;
- server[0] = -1;
- server[1] = -1;
- streams[0] = NULL;
- streams[1] = NULL;
- #endif
- #ifdef PHP_WIN32
- _fmode = _O_BINARY; /* sets default for file streams to binary */
- setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
- setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
- setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
- #endif
- #ifdef ZTS
- tsrm_startup(1, 1, 0, NULL);
- tsrm_ls = ts_resource(0);
- #endif
- phpdbg_main:
- if (!cleaning) {
-
- #ifdef _WIN32
- bp_tmp_file = malloc(L_tmpnam);
- if (bp_tmp_file) {
- if (!tmpnam(bp_tmp_file)) {
- free(bp_tmp_file);
- bp_tmp_file = NULL;
- }
- }
- if (!bp_tmp_file) {
- phpdbg_error("Unable to create temporary file");
- return 1;
- }
- #else
- if (!mkstemp(bp_tmp_file)) {
- memset(bp_tmp_file, 0, sizeof(bp_tmp_file));
- }
- #endif
- }
- ini_entries = NULL;
- ini_entries_len = 0;
- ini_ignore = 0;
- ini_override = NULL;
- zend_extensions = NULL;
- zend_extensions_len = 0L;
- exec = NULL;
- exec_len = 0;
- init_file = NULL;
- init_file_len = 0;
- init_file_default = 1;
- oplog_file = NULL;
- oplog_file_len = 0;
- flags = PHPDBG_DEFAULT_FLAGS;
- php_optarg = NULL;
- php_optind = 1;
- opt = 0;
- run = 0;
- step = 0;
- sapi_name = NULL;
- while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
- switch (opt) {
- case 'r':
- run++;
- break;
- case 'n':
- ini_ignore = 1;
- break;
- case 'c':
- if (ini_override) {
- free(ini_override);
- }
- ini_override = strdup(php_optarg);
- break;
- case 'd': {
- int len = strlen(php_optarg);
- char *val;
- if ((val = strchr(php_optarg, '='))) {
- val++;
- if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
- ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0"));
- memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg));
- ini_entries_len += (val - php_optarg);
- memcpy(ini_entries + ini_entries_len, "\"", 1);
- ini_entries_len++;
- memcpy(ini_entries + ini_entries_len, val, len - (val - php_optarg));
- ini_entries_len += len - (val - php_optarg);
- memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0"));
- ini_entries_len += sizeof("\n\0\"") - 2;
- } else {
- ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0"));
- memcpy(ini_entries + ini_entries_len, php_optarg, len);
- memcpy(ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0"));
- ini_entries_len += len + sizeof("\n\0") - 2;
- }
- } else {
- ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0"));
- memcpy(ini_entries + ini_entries_len, php_optarg, len);
- memcpy(ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0"));
- ini_entries_len += len + sizeof("=1\n\0") - 2;
- }
- } break;
- case 'z':
- zend_extensions_len++;
- if (zend_extensions) {
- zend_extensions = realloc(zend_extensions, sizeof(char*) * zend_extensions_len);
- } else zend_extensions = malloc(sizeof(char*) * zend_extensions_len);
- zend_extensions[zend_extensions_len-1] = strdup(php_optarg);
- break;
- /* begin phpdbg options */
- case 'S': { /* set SAPI name */
- if (sapi_name) {
- free(sapi_name);
- }
- sapi_name = strdup(php_optarg);
- } break;
- case 'I': { /* ignore .phpdbginit */
- init_file_default = 0;
- } break;
- case 'i': { /* set init file */
- if (init_file) {
- free(init_file);
- }
- init_file_len = strlen(php_optarg);
- if (init_file_len) {
- init_file = strdup(php_optarg);
- }
- } break;
- case 'O': { /* set oplog output */
- oplog_file_len = strlen(php_optarg);
- if (oplog_file_len) {
- oplog_file = strdup(php_optarg);
- }
- } break;
- case 'v': /* set quietness off */
- flags &= ~PHPDBG_IS_QUIET;
- break;
- case 's': /* set stepping on */
- step = 1;
- break;
- case 'E': /* stepping through eval on */
- flags |= PHPDBG_IS_STEPONEVAL;
- break;
- case 'b': /* set colours off */
- flags &= ~PHPDBG_IS_COLOURED;
- break;
- case 'q': /* hide banner */
- show_banner = 0;
- break;
- #ifndef _WIN32
- /* if you pass a listen port, we will accept input on listen port */
- /* and write output to listen port * 2 */
- case 'l': { /* set listen ports */
- if (sscanf(php_optarg, "%d/%d", &listen[0], &listen[1]) != 2) {
- if (sscanf(php_optarg, "%d", &listen[0]) != 1) {
- /* default to hardcoded ports */
- listen[0] = 4000;
- listen[1] = 8000;
- } else {
- listen[1] = (listen[0] * 2);
- }
- }
- } break;
- case 'a': { /* set bind address */
- free(address);
- if (!php_optarg) {
- address = strdup("*");
- } else address = strdup(php_optarg);
- } break;
- #endif
- case 'V': {
- sapi_startup(phpdbg);
- phpdbg->startup(phpdbg);
- printf(
- "phpdbg %s (built: %s %s)\nPHP %s, Copyright (c) 1997-2016 The PHP Group\n%s",
- PHPDBG_VERSION,
- __DATE__,
- __TIME__,
- PHP_VERSION,
- get_zend_version()
- );
- sapi_deactivate(TSRMLS_C);
- sapi_shutdown();
- return 0;
- } break;
- }
- }
-
- /* set exec if present on command line */
- if ((argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS))
- {
- exec_len = strlen(argv[php_optind]);
- if (exec_len) {
- if (exec) {
- free(exec);
- }
- exec = strdup(argv[php_optind]);
- }
- php_optind++;
- }
- #ifndef _WIN32
- /* setup remote server if necessary */
- if (!cleaning &&
- (listen[0] > 0 && listen[1] > 0)) {
- if (phpdbg_open_sockets(address, listen, &server, &socket, streams) == FAILURE) {
- remote = 0;
- exit(0);
- }
- /* set remote flag to stop service shutting down upon quit */
- remote = 1;
- }
- #endif
- if (sapi_name) {
- phpdbg->name = sapi_name;
- }
- phpdbg->ini_defaults = phpdbg_ini_defaults;
- phpdbg->phpinfo_as_text = 1;
- phpdbg->php_ini_ignore_cwd = 1;
- sapi_startup(phpdbg);
- phpdbg->executable_location = argv[0];
- phpdbg->phpinfo_as_text = 1;
- phpdbg->php_ini_ignore = ini_ignore;
- phpdbg->php_ini_path_override = ini_override;
- if (ini_entries) {
- ini_entries = realloc(ini_entries, ini_entries_len + sizeof(phpdbg_ini_hardcoded));
- memmove(ini_entries + sizeof(phpdbg_ini_hardcoded) - 2, ini_entries, ini_entries_len + 1);
- memcpy(ini_entries, phpdbg_ini_hardcoded, sizeof(phpdbg_ini_hardcoded) - 2);
- } else {
- ini_entries = malloc(sizeof(phpdbg_ini_hardcoded));
- memcpy(ini_entries, phpdbg_ini_hardcoded, sizeof(phpdbg_ini_hardcoded));
- }
- ini_entries_len += sizeof(phpdbg_ini_hardcoded) - 2;
- if (zend_extensions_len) {
- zend_ulong zend_extension = 0L;
- while (zend_extension < zend_extensions_len) {
- const char *ze = zend_extensions[zend_extension];
- size_t ze_len = strlen(ze);
- ini_entries = realloc(
- ini_entries, ini_entries_len + (ze_len + (sizeof("zend_extension=\n"))));
- memcpy(&ini_entries[ini_entries_len], "zend_extension=", (sizeof("zend_extension=\n")-1));
- ini_entries_len += (sizeof("zend_extension=")-1);
- memcpy(&ini_entries[ini_entries_len], ze, ze_len);
- ini_entries_len += ze_len;
- memcpy(&ini_entries[ini_entries_len], "\n", (sizeof("\n") - 1));
- free(zend_extensions[zend_extension]);
- zend_extension++;
- }
- free(zend_extensions);
- }
- phpdbg->ini_entries = ini_entries;
- if (phpdbg->startup(phpdbg) == SUCCESS) {
- #ifdef _WIN32
- EXCEPTION_POINTERS *xp;
- __try {
- #endif
- zend_mm_heap *mm_heap = phpdbg_mm_get_heap();
- if (mm_heap->use_zend_alloc) {
- mm_heap->_malloc = phpdbg_malloc_wrapper;
- mm_heap->_realloc = phpdbg_realloc_wrapper;
- mm_heap->_free = phpdbg_free_wrapper;
- mm_heap->use_zend_alloc = 0;
- }
- zend_activate(TSRMLS_C);
- PHPDBG_G(original_free_function) = mm_heap->_free;
- mm_heap->_free = phpdbg_watch_efree;
- phpdbg_setup_watchpoints(TSRMLS_C);
- #if defined(ZEND_SIGNALS) && !defined(_WIN32)
- zend_try {
- zend_signal_activate(TSRMLS_C);
- } zend_end_try();
- #endif
- #if defined(ZEND_SIGNALS) && !defined(_WIN32)
- zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try();
- zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try();
- #elif !defined(_WIN32)
- sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal));
- sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal));
- #endif
- if (php_request_startup(TSRMLS_C) == SUCCESS) {
- int i;
-
- SG(request_info).argc = argc - php_optind + 1;
- SG(request_info).argv = emalloc(SG(request_info).argc * sizeof(char *));
- for (i = SG(request_info).argc; --i;) {
- SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]);
- }
- SG(request_info).argv[i] = exec ? estrndup(exec, exec_len) : estrdup("");
- php_hash_environment(TSRMLS_C);
- }
- /* make sure to turn off buffer for ev command */
- php_output_activate(TSRMLS_C);
- php_output_deactivate(TSRMLS_C);
-
- /* do not install sigint handlers for remote consoles */
- /* sending SIGINT then provides a decent way of shutting down the server */
- #ifndef _WIN32
- if (listen[0] < 0) {
- #endif
- #if defined(ZEND_SIGNALS) && !defined(_WIN32)
- zend_try { zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); } zend_end_try();
- #else
- signal(SIGINT, phpdbg_sigint_handler);
- #endif
- #ifndef _WIN32
- }
- #endif
- PG(modules_activated) = 0;
- /* set flags from command line */
- PHPDBG_G(flags) = flags;
- #ifndef _WIN32
- /* setup io here */
- if (streams[0] && streams[1]) {
- PHPDBG_G(flags) |= PHPDBG_IS_REMOTE;
- signal(SIGPIPE, SIG_IGN);
- }
- #endif
- PHPDBG_G(io)[PHPDBG_STDIN] = stdin;
- PHPDBG_G(io)[PHPDBG_STDOUT] = stdout;
- PHPDBG_G(io)[PHPDBG_STDERR] = stderr;
- if (exec) { /* set execution context */
- PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC);
- PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec));
- free(exec);
- }
- if (oplog_file) { /* open oplog */
- PHPDBG_G(oplog) = fopen(oplog_file, "w+");
- if (!PHPDBG_G(oplog)) {
- phpdbg_error(
- "Failed to open oplog %s", oplog_file);
- }
- free(oplog_file);
- }
- /* set default colors */
- phpdbg_set_color_ex(PHPDBG_COLOR_PROMPT, PHPDBG_STRL("white-bold") TSRMLS_CC);
- phpdbg_set_color_ex(PHPDBG_COLOR_ERROR, PHPDBG_STRL("red-bold") TSRMLS_CC);
- phpdbg_set_color_ex(PHPDBG_COLOR_NOTICE, PHPDBG_STRL("green") TSRMLS_CC);
- /* set default prompt */
- phpdbg_set_prompt(PROMPT TSRMLS_CC);
- /* Make stdin, stdout and stderr accessible from PHP scripts */
- phpdbg_register_file_handles(TSRMLS_C);
- if (show_banner) {
- /* print blurb */
- phpdbg_welcome((cleaning > 0) TSRMLS_CC);
- }
- /* auto compile */
- if (PHPDBG_G(exec)) {
- phpdbg_compile(TSRMLS_C);
- }
- /* initialize from file */
- PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING;
- zend_try {
- phpdbg_init(init_file, init_file_len, init_file_default TSRMLS_CC);
- phpdbg_try_file_init(bp_tmp_file, strlen(bp_tmp_file), 0 TSRMLS_CC);
- } zend_end_try();
- PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING;
-
- /* quit if init says so */
- if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
- goto phpdbg_out;
- }
- /* step from here, not through init */
- if (step) {
- PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
- }
- if (run) {
- /* no need to try{}, run does it ... */
- PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC);
- if (run > 1) {
- /* if -r is on the command line more than once just quit */
- goto phpdbg_out;
- }
- }
- /* #ifndef for making compiler shutting up */
- #ifndef _WIN32
- phpdbg_interact:
- #endif
- /* phpdbg main() */
- do {
- zend_try {
- phpdbg_interactive(TSRMLS_C);
- } zend_catch {
- if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) {
- FILE *bp_tmp_fp = fopen(bp_tmp_file, "w");
- phpdbg_export_breakpoints(bp_tmp_fp TSRMLS_CC);
- fclose(bp_tmp_fp);
- cleaning = 1;
- } else {
- cleaning = 0;
- }
- #ifndef _WIN32
- if (!cleaning) {
- /* remote client disconnected */
- if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) {
-
- if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
- /* renegociate connections */
- phpdbg_open_sockets(
- address, listen, &server, &socket, streams);
-
- /* set streams */
- if (streams[0] && streams[1]) {
- PHPDBG_G(flags) &= ~PHPDBG_IS_QUITTING;
- }
-
- /* this must be forced */
- CG(unclean_shutdown) = 0;
- } else {
- /* local consoles cannot disconnect, ignore EOF */
- PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED;
- }
- }
- }
- #endif
- } zend_end_try();
- } while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING));
-
- /* this must be forced */
- CG(unclean_shutdown) = 0;
-
- /* this is just helpful */
- PG(report_memleaks) = 0;
-
- #ifndef _WIN32
- phpdbg_out:
- if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) {
- PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED;
- goto phpdbg_interact;
- }
- #endif
- #ifdef _WIN32
- } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) {
- phpdbg_error("Access violation (Segmentation fault) encountered\ntrying to abort cleanly...");
- }
- phpdbg_out:
- #endif
-
- {
- int i;
- /* free argv */
- for (i = SG(request_info).argc; --i;) {
- efree(SG(request_info).argv[i]);
- }
- efree(SG(request_info).argv);
- }
- #ifndef ZTS
- /* force cleanup of auto and core globals */
- zend_hash_clean(CG(auto_globals));
- memset(
- &core_globals, 0, sizeof(php_core_globals));
- #endif
- if (ini_entries) {
- free(ini_entries);
- }
- if (ini_override) {
- free(ini_override);
- }
-
- /* this must be forced */
- CG(unclean_shutdown) = 0;
-
- /* this is just helpful */
- PG(report_memleaks) = 0;
- php_request_shutdown((void*)0);
- zend_try {
- php_module_shutdown(TSRMLS_C);
- } zend_end_try();
- sapi_shutdown();
- }
- if (cleaning || remote) {
- goto phpdbg_main;
- }
-
- #ifdef ZTS
- /* bugggy */
- /* tsrm_shutdown(); */
- #endif
- #ifndef _WIN32
- if (address) {
- free(address);
- }
- #endif
- if (sapi_name) {
- free(sapi_name);
- }
-
- #ifdef _WIN32
- free(bp_tmp_file);
- #else
- unlink(bp_tmp_file);
- #endif
- return 0;
- } /* }}} */
|