php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
phpdbg.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Felipe Pena <felipe@php.net> |
14 | Authors: Joe Watkins <joe.watkins@live.co.uk> |
15 | Authors: Bob Weinand <bwoebi@php.net> |
16 +----------------------------------------------------------------------+
17*/
18
19#include "phpdbg.h"
20#include "phpdbg_prompt.h"
21#include "phpdbg_bp.h"
22#include "phpdbg_break.h"
23#include "phpdbg_list.h"
24#include "phpdbg_utils.h"
25#include "phpdbg_set.h"
26#include "phpdbg_io.h"
27#include "zend_alloc.h"
28#include "phpdbg_print.h"
29#include "phpdbg_help.h"
30#include "phpdbg_arginfo.h"
31#include "zend_vm.h"
32#include "php_ini_builder.h"
33#include "php_main.h"
34
36
37#if defined(PHP_WIN32) && defined(HAVE_OPENSSL_EXT)
38# include "openssl/applink.c"
39#endif
40
41#if defined(PHP_WIN32) && defined(ZTS)
43#endif
44
47
48static bool phpdbg_booted = 0;
49static bool phpdbg_fully_started = 0;
50static bool use_mm_wrappers = 1;
51
52static void php_phpdbg_destroy_bp_file(zval *brake) /* {{{ */
53{
55 efree(Z_ARRVAL_P(brake));
56} /* }}} */
57
58static void php_phpdbg_destroy_bp_symbol(zval *brake) /* {{{ */
59{
60 efree((char *) ((phpdbg_breaksymbol_t *) Z_PTR_P(brake))->symbol);
61 efree(Z_PTR_P(brake));
62} /* }}} */
63
64static void php_phpdbg_destroy_bp_opcode(zval *brake) /* {{{ */
65{
66 efree((char *) ((phpdbg_breakop_t *) Z_PTR_P(brake))->name);
67 efree(Z_PTR_P(brake));
68} /* }}} */
69
70static void php_phpdbg_destroy_bp_opline(zval *brake) /* {{{ */
71{
72 efree(Z_PTR_P(brake));
73} /* }}} */
74
75static void php_phpdbg_destroy_bp_methods(zval *brake) /* {{{ */
76{
78 efree(Z_ARRVAL_P(brake));
79} /* }}} */
80
81static void php_phpdbg_destroy_bp_condition(zval *data) /* {{{ */
82{
84
85 if (brake->ops) {
86 destroy_op_array(brake->ops);
87 efree(brake->ops);
88 }
89 efree((char*) brake->code);
90 efree(brake);
91} /* }}} */
92
93static void php_phpdbg_destroy_file_source(zval *data) /* {{{ */
94{
96 destroy_op_array(&source->op_array);
97 if (source->buf) {
98 efree(source->buf);
99 }
100 efree(source);
101} /* }}} */
102
103static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
104{
105 pg->prompt[0] = NULL;
106 pg->prompt[1] = NULL;
107
108 pg->colors[0] = NULL;
109 pg->colors[1] = NULL;
110 pg->colors[2] = NULL;
111
112 pg->lines = phpdbg_get_terminal_height();
113 pg->exec = NULL;
114 pg->exec_len = 0;
115 pg->buffer = NULL;
116 pg->last_was_newline = 1;
117 pg->ops = NULL;
118 pg->vmret = 0;
119 pg->in_execution = 0;
120 pg->bp_count = 0;
121 pg->flags = PHPDBG_DEFAULT_FLAGS;
122 memset(pg->io, 0, sizeof(pg->io));
123 pg->frame.num = 0;
124 pg->sapi_name_ptr = NULL;
125 pg->unclean_eval = 0;
126
127 pg->req_id = 0;
128 pg->err_buf.active = 0;
129 pg->err_buf.type = 0;
130
131 pg->input_buflen = 0;
132 pg->sigsafe_mem.mem = NULL;
133 pg->sigsegv_bailout = NULL;
134
135 pg->oplog_list = NULL;
136 pg->stdin_file = NULL;
137
138 pg->cur_command = NULL;
139 pg->last_line = 0;
140
141#ifdef HAVE_USERFAULTFD_WRITEFAULT
142 pg->watch_userfaultfd = 0;
143 pg->watch_userfault_thread = 0;
144#endif
145} /* }}} */
146
147static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
148{
149 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0);
150 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], 8, NULL, php_phpdbg_destroy_bp_file, 0);
151 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], 8, NULL, php_phpdbg_destroy_bp_symbol, 0);
152 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
153 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
154 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
155 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], 8, NULL, php_phpdbg_destroy_bp_opline, 0);
156 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], 8, NULL, php_phpdbg_destroy_bp_opcode, 0);
157 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
158 zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0);
160
163
164 zend_hash_init(&PHPDBG_G(file_sources), 0, NULL, php_phpdbg_destroy_file_source, 0);
166
168
169 register_phpdbg_symbols(module_number);
170
171 return SUCCESS;
172} /* }}} */
173
174static PHP_MSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
175{
178
180 phpdbg_notice("Script ended normally");
181 }
182
183 /* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
184 if (use_mm_wrappers) {
185 /* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
186 *(int *) zend_mm_get_heap() = 0;
187 }
188
189 if (PHPDBG_G(buffer)) {
190 free(PHPDBG_G(buffer));
192 }
193
194 if (PHPDBG_G(exec)) {
195 free(PHPDBG_G(exec));
196 PHPDBG_G(exec) = NULL;
197 }
198
199 if (PHPDBG_G(oplog_list)) {
201 do {
203 efree(cur);
204 cur = prev;
205 } while (cur != NULL);
206
207 zend_arena_destroy(PHPDBG_G(oplog_arena));
209 }
210
211 fflush(stdout);
212 if (SG(request_info).argv0) {
213 free(SG(request_info).argv0);
214 SG(request_info).argv0 = NULL;
215 }
216
217 return SUCCESS;
218}
219/* }}} */
220
221static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
222{
223 /* deactivate symbol table caching to have these properly destroyed upon stack leaving (especially important for watchpoints) */
224 EG(symtable_cache_limit) = EG(symtable_cache);
225
227 /* phpdbg cannot work JIT-ed code */
228 zend_string *key = zend_string_init(ZEND_STRL("opcache.jit"), false);
229 zend_string *value = zend_string_init(ZEND_STRL("off"), false);
230
232
235 }
236
237 return SUCCESS;
238} /* }}} */
239
240static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
241{
242 if (PHPDBG_G(stdin_file)) {
245 }
246
247 return SUCCESS;
248} /* }}} */
249
250/* {{{ Attempt to set the execution context for phpdbg
251 If the execution context was set previously it is returned
252 If the execution context was not set previously boolean true is returned
253 If the request to set the context fails, boolean false is returned, and an E_WARNING raised */
255{
257
260 }
261
262 {
263 zend_stat_t sb = {0};
264 bool result = 1;
265
266 if (VCWD_STAT(ZSTR_VAL(exec), &sb) != FAILURE) {
267 if (sb.st_mode & (S_IFREG|S_IFLNK)) {
268 if (PHPDBG_G(exec)) {
270 free(PHPDBG_G(exec));
271 result = 0;
272 }
273
276
277 if (result) {
279 }
280 } else {
281 zend_error(E_WARNING, "Failed to set execution context (%s), not a regular file or symlink", ZSTR_VAL(exec));
283 }
284 } else {
285 zend_error(E_WARNING, "Failed to set execution context (%s) the file does not exist", ZSTR_VAL(exec));
286
288 }
289 }
290} /* }}} */
291
292/* {{{ instructs phpdbg to insert a breakpoint at the next opcode */
294{
296
299 }
300
301 ex = EG(current_execute_data);
302 while (ex && ex->func && !ZEND_USER_CODE(ex->func->type)) {
303 ex = ex->prev_execute_data;
304 }
305
306 if (!ex) {
307 return;
308 }
309
311} /* }}} */
312
313/* {{{ */
315{
316 char *file;
317 size_t flen;
319
320 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl", &file, &flen, &line) == FAILURE) {
322 }
323
325} /* }}} */
326
327/* {{{ */
329{
330 char *class, *method;
331 size_t clen, mlen;
332
333 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &class, &clen, &method, &mlen) == FAILURE) {
335 }
336
337 phpdbg_set_breakpoint_method(class, method);
338} /* }}} */
339
340/* {{{ */
342{
343 char *function;
344 size_t function_len;
345
346 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &function, &function_len) == FAILURE) {
348 }
349
351} /* }}} */
352
353/* {{{ instructs phpdbg to clear breakpoints */
371
372/* {{{ */
374{
375 zend_long element;
376 char *color;
377 size_t color_len;
378
379 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &element, &color, &color_len) == FAILURE) {
381 }
382
383 switch (element) {
387 phpdbg_set_color_ex(element, color, color_len);
388 break;
389
390 default:
391 zend_argument_value_error(1, "must be one of PHPDBG_COLOR_PROMPT, PHPDBG_COLOR_NOTICE, or PHPDBG_COLOR_ERROR");
392 }
393} /* }}} */
394
395/* {{{ */
397{
398 char *prompt = NULL;
399 size_t prompt_len = 0;
400
401 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &prompt, &prompt_len) == FAILURE) {
403 }
404
406} /* }}} */
407
408/* {{{ */
410{
412
415 }
416
418
419 if (!prev) {
420 PHPDBG_G(oplog_arena) = zend_arena_create(64 * 1024);
421 }
422
424 PHPDBG_G(oplog_list)->prev = prev;
426 PHPDBG_G(oplog_cur)->next = NULL;
427}
428
429static zend_always_inline bool phpdbg_is_ignored_opcode(uint8_t opcode) {
430 return
431 opcode == ZEND_NOP || opcode == ZEND_OP_DATA || opcode == ZEND_FE_FREE || opcode == ZEND_FREE || opcode == ZEND_ASSERT_CHECK || opcode == ZEND_VERIFY_RETURN_TYPE
432 || opcode == ZEND_DECLARE_CONST || opcode == ZEND_DECLARE_CLASS || opcode == ZEND_DECLARE_FUNCTION
433 || opcode == ZEND_DECLARE_CLASS_DELAYED
434 || opcode == ZEND_DECLARE_ANON_CLASS || opcode == ZEND_FAST_RET || opcode == ZEND_TICKS
435 || opcode == ZEND_EXT_STMT || opcode == ZEND_EXT_FCALL_BEGIN || opcode == ZEND_EXT_FCALL_END
436 || opcode == ZEND_BIND_GLOBAL || opcode == ZEND_BIND_INIT_STATIC_OR_JMP
437 ;
438}
439
440static void phpdbg_oplog_fill_executable(zend_op_array *op_array, HashTable *insert_ht, bool by_opcode) {
441 /* ignore RECV_* opcodes */
442 zend_op *cur = op_array->opcodes + op_array->num_args + !!(op_array->fn_flags & ZEND_ACC_VARIADIC);
443 zend_op *end = op_array->opcodes + op_array->last;
444
445 zend_long insert_idx;
446 zval zero;
447 ZVAL_LONG(&zero, 0);
448
449 /* ignore autogenerated return (well, not too precise with finally branches, but that's okay) */
450 if (op_array->last >= 1 && (((end - 1)->opcode == ZEND_RETURN || (end - 1)->opcode == ZEND_RETURN_BY_REF || (end - 1)->opcode == ZEND_GENERATOR_RETURN)
451 && ((op_array->last > 1 && ((end - 2)->opcode == ZEND_RETURN || (end - 2)->opcode == ZEND_RETURN_BY_REF || (end - 2)->opcode == ZEND_GENERATOR_RETURN || (end - 2)->opcode == ZEND_THROW))
452 || op_array->function_name == NULL || (end - 1)->extended_value == -1))) {
453 end--;
454 }
455
456 for (; cur < end; cur++) {
457 uint8_t opcode = cur->opcode;
458 if (phpdbg_is_ignored_opcode(opcode)) {
459 continue;
460 }
461
462 if (by_opcode) {
463 insert_idx = cur - op_array->opcodes;
464 } else {
465 insert_idx = cur->lineno;
466 }
467
468 if (opcode == ZEND_NEW && cur[1].opcode == ZEND_DO_FCALL) {
469 cur++;
470 }
471
472 zend_hash_index_update(insert_ht, insert_idx, &zero);
473 }
474}
475
476static inline HashTable* phpdbg_add_empty_array(HashTable *ht, zend_string *name) {
477 zval *ht_zv = zend_hash_find(ht, name);
478 if (!ht_zv) {
479 zval zv;
480 array_init(&zv);
481 ht_zv = zend_hash_add_new(ht, name, &zv);
482 }
483 return Z_ARR_P(ht_zv);
484}
485
486/* {{{ */
488{
490 zval *option_buffer;
491 bool by_function = false;
492 bool by_opcode = false;
493 HashTable *insert_ht;
494
499 HashTable files_tmp;
500
503 }
504
505 if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("functions")))) {
506 by_function = zend_is_true(option_buffer);
507 }
508
509 if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("opcodes")))) {
510 if (by_function) {
511 by_opcode = zend_is_true(option_buffer);
512 }
513 }
514
515 if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("files")))) {
516 ZVAL_DEREF(option_buffer);
517 if (Z_TYPE_P(option_buffer) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(option_buffer)) > 0) {
518 zval *filename;
519
520 files = &files_tmp;
521 zend_hash_init(files, 0, NULL, NULL, 0);
522
523 ZEND_HASH_FOREACH_VAL(Z_ARR_P(option_buffer), filename) {
524 zend_hash_add_empty_element(files, zval_get_string(filename));
526 } else {
527 GC_ADDREF(files);
528 }
529 } else {
530 GC_ADDREF(files);
531 }
532
534
535 ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(function_table), name, func) {
536 if (func->type == ZEND_USER_FUNCTION) {
537 if (zend_hash_exists(files, func->op_array.filename)) {
538 insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), func->op_array.filename);
539
540 if (by_function) {
541 insert_ht = phpdbg_add_empty_array(insert_ht, name);
542 }
543
544 phpdbg_oplog_fill_executable(&func->op_array, insert_ht, by_opcode);
545 }
546 }
548
549 ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), name, ce) {
550 if (ce->type == ZEND_USER_CLASS) {
551 if (zend_hash_exists(files, ce->info.user.filename)) {
553 if (func->type == ZEND_USER_FUNCTION && zend_hash_exists(files, func->op_array.filename)) {
554 insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), func->op_array.filename);
555
556 if (by_function) {
557 zend_string *fn_name = strpprintf(ZSTR_LEN(name) + ZSTR_LEN(func->op_array.function_name) + 2, "%.*s::%.*s", (int) ZSTR_LEN(name), ZSTR_VAL(name), (int) ZSTR_LEN(func->op_array.function_name), ZSTR_VAL(func->op_array.function_name));
558 insert_ht = phpdbg_add_empty_array(insert_ht, fn_name);
559 zend_string_release(fn_name);
560 }
561
562 phpdbg_oplog_fill_executable(&func->op_array, insert_ht, by_opcode);
563 }
565 }
566 }
568
570 phpdbg_file_source *source = zend_hash_find_ptr(&PHPDBG_G(file_sources), name);
571 if (source) {
572 phpdbg_oplog_fill_executable(
573 &source->op_array,
574 phpdbg_add_empty_array(Z_ARR_P(return_value), source->op_array.filename),
575 by_opcode);
576 }
578
579 if (!GC_DELREF(files)) {
580 zend_hash_destroy(files);
581 }
582}
583
584/* {{{ */
586{
589
591 zval *option_buffer;
592 bool by_function = false;
593 bool by_opcode = false;
594
597 }
598
599 if (!PHPDBG_G(oplog_list)) {
600 zend_error(E_WARNING, "Cannot end an oplog without starting it");
601 return;
602 }
603
604 cur = PHPDBG_G(oplog_list)->start.next;
605 prev = PHPDBG_G(oplog_list)->prev;
606
609
610 if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("functions")))) {
611 by_function = zend_is_true(option_buffer);
612 }
613
614 if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("opcodes")))) {
615 if (by_function) {
616 by_opcode = zend_is_true(option_buffer);
617 }
618 }
619
621
622 {
623 zend_string *last_file = NULL;
624 HashTable *file_ht = NULL;
625 zend_string *last_function = (void *)~(uintptr_t)0;
626 zend_class_entry *last_scope = NULL;
627
628 HashTable *insert_ht = NULL;
629 zend_long insert_idx;
630
631 do {
632 zval zero;
633 ZVAL_LONG(&zero, 0);
634
635 if (cur->filename != last_file) {
636 last_file = cur->filename;
637 file_ht = insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), last_file);
638 }
639
640 if (by_function) {
641 if (cur->function_name == NULL) {
642 if (last_function != NULL) {
643 insert_ht = file_ht;
644 }
645 last_function = NULL;
646 } else if (cur->function_name != last_function || cur->scope != last_scope) {
647 zend_string *fn_name;
648 last_function = cur->function_name;
649 last_scope = cur->scope;
650 if (last_scope == NULL) {
651 fn_name = zend_string_copy(last_function);
652 } else {
653 fn_name = strpprintf(ZSTR_LEN(last_function) + ZSTR_LEN(last_scope->name) + 2, "%.*s::%.*s", (int) ZSTR_LEN(last_scope->name), ZSTR_VAL(last_scope->name), (int) ZSTR_LEN(last_function), ZSTR_VAL(last_function));
654 }
655 insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), fn_name);
656 zend_string_release(fn_name);
657 }
658 }
659
660 if (by_opcode) {
661 insert_idx = cur->op - cur->opcodes;
662 } else {
663 if (phpdbg_is_ignored_opcode(cur->op->opcode)) {
664 continue;
665 }
666
667 insert_idx = cur->op->lineno;
668 }
669
670 ZEND_ASSERT(insert_ht && file_ht);
671 {
672 zval *num = zend_hash_index_find(insert_ht, insert_idx);
673 if (!num) {
674 num = zend_hash_index_add_new(insert_ht, insert_idx, &zero);
675 }
676 Z_LVAL_P(num)++;
677 }
678
679 } while ((cur = cur->next));
680 }
681
682 if (!prev) {
683 zend_arena_destroy(PHPDBG_G(oplog_arena));
684 }
685}
686
687static zend_module_entry sapi_phpdbg_module_entry = {
690 ext_functions,
695 NULL,
698};
699
700static inline int php_sapi_phpdbg_module_startup(sapi_module_struct *module) /* {{{ */
701{
702 if (php_module_startup(module, &sapi_phpdbg_module_entry) == FAILURE) {
703 return FAILURE;
704 }
705
706 phpdbg_booted = 1;
707
708 return SUCCESS;
709} /* }}} */
710
711static char* php_sapi_phpdbg_read_cookies(void) /* {{{ */
712{
713 return NULL;
714} /* }}} */
715
716static int php_sapi_phpdbg_header_handler(sapi_header_struct *h, sapi_header_op_enum op, sapi_headers_struct *s) /* {{{ */
717{
718 return 0;
719}
720/* }}} */
721
722static int php_sapi_phpdbg_send_headers(sapi_headers_struct *sapi_headers) /* {{{ */
723{
724 /* We do nothing here, this function is needed to prevent that the fallback
725 * header handling is called. */
727}
728/* }}} */
729
730static void php_sapi_phpdbg_send_header(sapi_header_struct *sapi_header, void *server_context) /* {{{ */
731{
732}
733/* }}} */
734
735static void php_sapi_phpdbg_log_message(const char *message, int syslog_type_int) /* {{{ */
736{
737 /*
738 * We must not request TSRM before being booted
739 */
740 if (phpdbg_booted) {
742 phpdbg_error("%s", message);
743 return;
744 }
745
746 phpdbg_error("%s", message);
747
749 return;
750 }
751
752 if (PG(last_error_type) & E_FATAL_ERRORS) {
753 const char *file_char = zend_get_executed_filename();
754 zend_string *file = zend_string_init(file_char, strlen(file_char), 0);
756 zend_string_release(file);
757
758 if (!phpdbg_fully_started) {
759 return;
760 }
761
762 do {
763 switch (phpdbg_interactive(1, NULL)) {
764 case PHPDBG_LEAVE:
765 case PHPDBG_FINISH:
766 case PHPDBG_UNTIL:
767 case PHPDBG_NEXT:
768 return;
769 }
770 } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING));
771 }
772 } else {
773 fprintf(stdout, "%s\n", message);
774 }
775}
776/* }}} */
777
778static int php_sapi_phpdbg_activate(void) /* {{{ */
779{
780 return SUCCESS;
781}
782
783static int php_sapi_phpdbg_deactivate(void) /* {{{ */
784{
785 /* Everything using ZMM should be freed here... */
799
800 if (PHPDBG_G(ops)) {
803 PHPDBG_G(ops) = NULL;
804 }
805
806 return SUCCESS;
807}
808
809static void php_sapi_phpdbg_register_vars(zval *track_vars_array) /* {{{ */
810{
811 size_t len;
812 char *docroot = "";
813
814 /* In phpdbg mode, we consider the environment to be a part of the server variables
815 */
816 php_import_environment_variables(track_vars_array);
817
818 if (PHPDBG_G(exec)) {
820 if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len)) {
821 php_register_variable("PHP_SELF", PHPDBG_G(exec), track_vars_array);
822 }
823 if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len)) {
824 php_register_variable("SCRIPT_NAME", PHPDBG_G(exec), track_vars_array);
825 }
826
827 if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len)) {
828 php_register_variable("SCRIPT_FILENAME", PHPDBG_G(exec), track_vars_array);
829 }
830 if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len)) {
831 php_register_variable("PATH_TRANSLATED", PHPDBG_G(exec), track_vars_array);
832 }
833 }
834
835 /* any old docroot will do */
836 len = 0;
837 if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", &docroot, len, &len)) {
838 php_register_variable("DOCUMENT_ROOT", docroot, track_vars_array);
839 }
840}
841/* }}} */
842
843static inline size_t php_sapi_phpdbg_ub_write(const char *message, size_t length) /* {{{ */
844{
845 return phpdbg_process_print(PHPDBG_G(io)[PHPDBG_STDOUT].fd, P_STDOUT, message, (int) length);
846} /* }}} */
847
848/* beginning of struct, see main/streams/plain_wrapper.c line 111 */
849typedef struct {
850 FILE *file;
851 int fd;
853
854static ssize_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t count) {
856
857 while (data->fd >= 0) {
858 struct stat stat[3];
859 memset(stat, 0, sizeof(stat));
860 int stat_stderr = fstat(fileno(stderr), &stat[2]);
861 int stat_stdout = fstat(fileno(stdout), &stat[0]);
862 int stat_datafd = fstat(data->fd, &stat[1]);
863 if ((stat_stderr < 0 && stat_stdout < 0) || stat_datafd < 0) {
864 break;
865 }
866
867 if (stat[0].st_dev == stat[1].st_dev && stat[0].st_ino == stat[1].st_ino) {
868 phpdbg_script(P_STDOUT, "%.*s", (int) count, buf);
869 return count;
870 }
871 if (stat[2].st_dev == stat[1].st_dev && stat[2].st_ino == stat[1].st_ino) {
872 phpdbg_script(P_STDERR, "%.*s", (int) count, buf);
873 return count;
874 }
875 break;
876 }
877
878 return PHPDBG_G(php_stdiop_write)(stream, buf, count);
879}
880
881/* copied from sapi/cli/php_cli.c cli_register_file_handles */
883{
884 zval zin, zout, zerr;
885 php_stream *s_in, *s_out, *s_err;
886 php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
887 zend_constant ic, oc, ec;
888
889 s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
890 s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
891 s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
892
893 if (s_in==NULL || s_out==NULL || s_err==NULL) {
894 if (s_in) php_stream_close(s_in);
895 if (s_out) php_stream_close(s_out);
896 if (s_err) php_stream_close(s_err);
897 return;
898 }
899
900#if PHP_DEBUG
901 /* do not close stdout and stderr */
904#endif
905
906 php_stream_to_zval(s_in, &zin);
907 php_stream_to_zval(s_out, &zout);
908 php_stream_to_zval(s_err, &zerr);
909
910 ic.value = zin;
911 Z_CONSTANT_FLAGS(ic.value) = 0;
912 ic.name = zend_string_init(ZEND_STRL("STDIN"), 0);
913 zend_hash_del(EG(zend_constants), ic.name);
915
916 oc.value = zout;
917 Z_CONSTANT_FLAGS(oc.value) = 0;
918 oc.name = zend_string_init(ZEND_STRL("STDOUT"), 0);
919 zend_hash_del(EG(zend_constants), oc.name);
921
922 ec.value = zerr;
923 Z_CONSTANT_FLAGS(ec.value) = 0;
924 ec.name = zend_string_init(ZEND_STRL("STDERR"), 0);
925 zend_hash_del(EG(zend_constants), ec.name);
927}
928/* }}} */
929
930/* {{{ sapi_module_struct phpdbg_sapi_module */
931static sapi_module_struct phpdbg_sapi_module = {
932 "phpdbg", /* name */
933 "phpdbg", /* pretty name */
934
935 php_sapi_phpdbg_module_startup, /* startup */
936 php_module_shutdown_wrapper, /* shutdown */
937
938 php_sapi_phpdbg_activate, /* activate */
939 php_sapi_phpdbg_deactivate, /* deactivate */
940
941 php_sapi_phpdbg_ub_write, /* unbuffered write */
942 NULL, /* flush */
943 NULL, /* get uid */
944 NULL, /* getenv */
945
946 php_error, /* error handler */
947
948 php_sapi_phpdbg_header_handler, /* header handler */
949 php_sapi_phpdbg_send_headers, /* send headers handler */
950 php_sapi_phpdbg_send_header, /* send header handler */
951
952 NULL, /* read POST data */
953 php_sapi_phpdbg_read_cookies, /* read Cookies */
954
955 php_sapi_phpdbg_register_vars, /* register server variables */
956 php_sapi_phpdbg_log_message, /* Log message */
957 NULL, /* Get request time */
958 NULL, /* Child terminate */
960};
961/* }}} */
962
963static const opt_struct OPTIONS[] = { /* {{{ */
964 {'c', 1, "ini path override"},
965 {'d', 1, "define ini entry on command line"},
966 {'n', 0, "no php.ini"},
967 {'z', 1, "load zend_extension"},
968 /* phpdbg options */
969 {'q', 0, "no banner"},
970 {'v', 0, "disable quietness"},
971 {'b', 0, "boring colours"},
972 {'i', 1, "specify init"},
973 {'I', 0, "ignore init"},
974 {'O', 1, "opline log"},
975 {'r', 0, "run"},
976 {'e', 0, "generate ext_stmt opcodes"},
977 {'E', 0, "step-through-eval"},
978 {'s', 1, "script from stdin"},
979 {'S', 1, "sapi-name"},
980 {'p', 2, "show opcodes"},
981 {'h', 0, "help"},
982 {'V', 0, "version"},
983 {'-', 0, NULL}
984}; /* }}} */
985
987"html_errors=Off\n"
988"register_argc_argv=On\n"
989"implicit_flush=On\n"
990"display_errors=Off\n"
991"log_errors=On\n"
992"max_execution_time=0\n"
993"max_input_time=-1\n"
994"error_log=\n"
995"output_buffering=off\n";
996
997static void phpdbg_welcome(bool cleaning) /* {{{ */
998{
999 /* print blurb */
1000 if (!cleaning) {
1001 phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION);
1002 phpdbg_writeln("To get help using phpdbg type \"help\" and press enter");
1003 phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES);
1004 } else if (phpdbg_startup_run == 0) {
1006 "Classes %d\n"
1007 "Functions %d\n"
1008 "Constants %d\n"
1009 "Includes %d\n",
1010 zend_hash_num_elements(EG(class_table)),
1011 zend_hash_num_elements(EG(function_table)),
1012 zend_hash_num_elements(EG(zend_constants)),
1013 zend_hash_num_elements(&EG(included_files)));
1014 }
1015} /* }}} */
1016
1017static inline void phpdbg_sigint_handler(int signo) /* {{{ */
1018{
1020 /* set signalled only when not interactive */
1022 char mem[PHPDBG_SIGSAFE_MEM_SIZE + 1];
1023
1025 zend_try {
1027 } zend_end_try()
1029
1031
1033 zend_bailout();
1034 }
1035 } else {
1040 }
1041 }
1042 }
1043} /* }}} */
1044
1045#ifndef _WIN32
1046static void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
1047{
1048 int is_handled = FAILURE;
1049
1050 switch (sig) {
1051 case SIGBUS:
1052 case SIGSEGV:
1053 is_handled = phpdbg_watchpoint_segfault_handler(info, context);
1054 if (is_handled == FAILURE) {
1057 }
1059 }
1060 break;
1061 }
1062
1063} /* }}} */
1064
1065
1066static ZEND_NORETURN void phpdbg_sighup_handler(int sig) /* {{{ */
1067{
1068 exit(0);
1069} /* }}} */
1070#endif
1071
1076
1078{
1080 if (UNEXPECTED(heap == p)) {
1081 /* TODO: heap maybe allocated by mmap(zend_mm_init) or malloc(USE_ZEND_ALLOC=0)
1082 * let's prevent it from segfault for now
1083 */
1084 } else {
1087 }
1088} /* }}} */
1089
1094
1095php_stream *phpdbg_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) /* {{{ */
1096{
1097 if (!strncasecmp(path, "php://", 6)) {
1098 path += 6;
1099 }
1100
1101 if (!strncasecmp(path, "stdin", 6) && PHPDBG_G(stdin_file)) {
1102 php_stream *stream = php_stream_fopen_from_fd(dup(fileno(PHPDBG_G(stdin_file))), "r", NULL);
1103#ifdef PHP_WIN32
1104 if (context != NULL) {
1105 zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking");
1106 if (blocking_pipes) {
1107 convert_to_long(blocking_pipes);
1109 }
1110 }
1111#endif
1112 return stream;
1113 }
1114
1115 return PHPDBG_G(orig_url_wrap_php)->wops->stream_opener(wrapper, path, mode, options, opened_path, context STREAMS_CC);
1116} /* }}} */
1117
1118int main(int argc, char **argv) /* {{{ */
1119{
1120 sapi_module_struct *phpdbg = &phpdbg_sapi_module;
1121 char *sapi_name;
1122 struct php_ini_builder ini_builder;
1123 char **zend_extensions = NULL;
1124 zend_ulong zend_extensions_len = 0L;
1125 bool ini_ignore;
1126 char *ini_override;
1127 char *exec = NULL;
1128 char *first_command = NULL;
1129 char *init_file;
1130 size_t init_file_len;
1131 bool init_file_default;
1132 uint64_t flags;
1133 char *php_optarg;
1134 int php_optind, opt, show_banner = 1;
1135 long cleaning = -1;
1136 volatile bool quit_immediately = 0; /* somehow some gcc release builds will play a bit around with order in combination with setjmp..., hence volatile */
1137 zend_phpdbg_globals *settings = NULL;
1138 char *bp_tmp = NULL;
1139 char *print_opline_func;
1140 bool ext_stmt = 0;
1141 bool is_exit;
1142 int exit_status;
1143 char *read_from_stdin = NULL;
1144 zend_string *backup_phpdbg_compile = NULL;
1145 bool show_help = 0, show_version = 0;
1146 void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
1148 void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
1149 php_stream_wrapper wrapper;
1151
1152#ifdef PHP_WIN32
1153 _fmode = _O_BINARY; /* sets default for file streams to binary */
1154 _setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
1155 _setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
1156 _setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
1157#else
1158 struct sigaction signal_struct;
1159 signal_struct.sa_sigaction = phpdbg_signal_handler;
1160 signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER;
1161#endif
1162
1163phpdbg_main:
1164#ifdef ZTS
1165 php_tsrm_startup();
1166# ifdef PHP_WIN32
1168# endif
1169#endif
1170
1172
1173 php_ini_builder_init(&ini_builder);
1174 ini_ignore = 0;
1175 ini_override = NULL;
1177 zend_extensions_len = 0L;
1178 init_file = NULL;
1179 init_file_len = 0;
1180 init_file_default = 1;
1182 is_exit = 0;
1183 php_optarg = NULL;
1184 php_optind = 1;
1185 opt = 0;
1186 sapi_name = NULL;
1187 exit_status = 0;
1188 if (settings) {
1189 exec = settings->exec;
1190 }
1191
1192 while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
1193 switch (opt) {
1194 case 'r':
1195 if (settings == NULL) {
1197 }
1198 break;
1199 case 'n':
1200 ini_ignore = 1;
1201 break;
1202 case 'c':
1203 if (ini_override) {
1204 free(ini_override);
1205 }
1206 ini_override = strdup(php_optarg);
1207 break;
1208 case 'd':
1209 /* define ini entries on command line */
1210 php_ini_builder_define(&ini_builder, php_optarg);
1211 break;
1212
1213 case 'z':
1214 zend_extensions_len++;
1215 if (zend_extensions) {
1216 zend_extensions = realloc(zend_extensions, sizeof(char*) * zend_extensions_len);
1217 } else zend_extensions = malloc(sizeof(char*) * zend_extensions_len);
1218 zend_extensions[zend_extensions_len-1] = strdup(php_optarg);
1219 break;
1220
1221 /* begin phpdbg options */
1222
1223 case 's': { /* read script from stdin */
1224 if (settings == NULL) {
1225 read_from_stdin = strdup(php_optarg);
1226 }
1227 } break;
1228
1229 case 'S': { /* set SAPI name */
1230 sapi_name = strdup(php_optarg);
1231 } break;
1232
1233 case 'I': { /* ignore .phpdbginit */
1234 init_file_default = 0;
1235 } break;
1236
1237 case 'i': { /* set init file */
1238 if (init_file) {
1239 free(init_file);
1240 init_file = NULL;
1241 }
1242
1243 init_file_len = strlen(php_optarg);
1244 if (init_file_len) {
1245 init_file = strdup(php_optarg);
1246 }
1247 } break;
1248
1249 case 'v': /* set quietness off */
1251 break;
1252
1253 case 'e':
1254 ext_stmt = 1;
1255 break;
1256
1257 case 'E': /* stepping through eval on */
1259 break;
1260
1261 case 'b': /* set colours off */
1263 break;
1264
1265 case 'q': /* hide banner */
1266 show_banner = 0;
1267 break;
1268
1269 case 'p': {
1270 print_opline_func = php_optarg;
1271 show_banner = 0;
1272 settings = (void *) 0x1;
1273 } break;
1274
1275 case 'h': {
1276 show_help = 1;
1277 } break;
1278
1279 case 'V': {
1280 show_version = 1;
1281 } break;
1282 }
1283
1284 php_optarg = NULL;
1285 }
1286
1287 quit_immediately = phpdbg_startup_run > 1;
1288
1289 /* set exec if present on command line */
1290 if (!read_from_stdin && argc > php_optind) {
1291 if (!exec && strlen(argv[php_optind])) {
1292 exec = strdup(argv[php_optind]);
1293 }
1294 php_optind++;
1295 }
1296
1297 if (sapi_name) {
1298 phpdbg->name = sapi_name;
1299 }
1300
1301 phpdbg->ini_defaults = NULL;
1302 phpdbg->phpinfo_as_text = 1;
1303 phpdbg->php_ini_ignore_cwd = 1;
1304
1306
1307 phpdbg->executable_location = argv[0];
1308 phpdbg->phpinfo_as_text = 1;
1309 phpdbg->php_ini_ignore = ini_ignore;
1310 phpdbg->php_ini_path_override = ini_override;
1311
1313
1314 if (zend_extensions_len) {
1316
1317 while (zend_extension < zend_extensions_len) {
1318 const char *ze = zend_extensions[zend_extension];
1319 size_t ze_len = strlen(ze);
1320
1321 php_ini_builder_unquoted(&ini_builder, "zend_extension", strlen("zend_extension"), ze, ze_len);
1322
1325 }
1326
1327 free(zend_extensions);
1328 }
1329
1330 phpdbg->ini_entries = php_ini_builder_finish(&ini_builder);
1331
1332 ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
1333
1334 /* set default colors */
1338
1339 if (settings > (zend_phpdbg_globals *) 0x2) {
1340#ifdef ZTS
1341 zend_phpdbg_globals *ptr = TSRMG_BULK_STATIC(phpdbg_globals_id, zend_phpdbg_globals *);
1342 *ptr = *settings;
1343#else
1344 phpdbg_globals = *settings;
1345#endif
1346 free(settings);
1347 } else {
1348 /* set default prompt */
1350 }
1351
1352 /* set flags from command line */
1353 PHPDBG_G(flags) = flags;
1354
1355 if (phpdbg->startup(phpdbg) == SUCCESS) {
1356 zend_mm_heap *mm_heap;
1357#ifdef _WIN32
1358 EXCEPTION_POINTERS *xp;
1359 __try {
1360#endif
1361
1362 if (show_version || show_help) {
1363 /* It ain't gonna proceed to real execution anyway,
1364 but the correct descriptor is needed already. */
1365 PHPDBG_G(io)[PHPDBG_STDOUT].fd = fileno(stdout);
1366 if (show_help) {
1368 } else if (show_version) {
1369 char *version_info = php_get_version(&phpdbg_sapi_module);
1370 /* we also want to include phpdbg version */
1371 char *prepended_version_info;
1372 spprintf(&prepended_version_info, 0,
1373 "phpdbg %s, %s", PHPDBG_VERSION, version_info);
1374 phpdbg_out("%s", prepended_version_info);
1375 efree(prepended_version_info);
1376 efree(version_info);
1377 }
1381 sapi_shutdown();
1382 php_ini_builder_deinit(&ini_builder);
1383 if (ini_override) {
1384 free(ini_override);
1385 }
1386 if (exec) {
1387 free(exec);
1388 }
1389 if (init_file) {
1390 free(init_file);
1391 }
1392 goto free_and_return;
1393 }
1394
1395 zend_try {
1397 } zend_end_try();
1398
1399#ifndef _WIN32
1400 zend_signal(SIGHUP, phpdbg_sighup_handler);
1401#endif
1402
1403 mm_heap = zend_mm_get_heap();
1404 zend_mm_get_custom_handlers(mm_heap, &_malloc, &_free, &_realloc);
1405
1406 use_mm_wrappers = !_malloc && !_realloc && !_free;
1407
1409 _free = phpdbg_watch_efree;
1410
1411 if (use_mm_wrappers) {
1413 } else {
1414 zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc);
1415 }
1416
1418
1419
1421
1422 PHPDBG_G(sapi_name_ptr) = sapi_name;
1423
1424 if (exec) { /* set execution context */
1427
1428 free(exec);
1429 exec = NULL;
1430 }
1431
1434
1435 if (SG(sapi_headers).mimetype) {
1436 efree(SG(sapi_headers).mimetype);
1437 SG(sapi_headers).mimetype = NULL;
1438 }
1439
1441
1442 {
1443 int i;
1444
1445 SG(request_info).argc = argc - php_optind + 1;
1446 SG(request_info).argv = emalloc(SG(request_info).argc * sizeof(char *));
1447 for (i = SG(request_info).argc; --i;) {
1448 SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]);
1449 }
1450 SG(request_info).argv[0] = PHPDBG_G(exec) ? estrdup(PHPDBG_G(exec)) : estrdup("");
1451 }
1452
1453 if (php_request_startup() == FAILURE) {
1454 PUTS("Could not startup");
1455 return 1;
1456 }
1457
1458#ifndef _WIN32
1459#ifdef HAVE_USERFAULTFD_WRITEFAULT
1460 if (!PHPDBG_G(watch_userfaultfd))
1461#endif
1462 {
1465 }
1466#endif
1467 zend_try { zend_signal(SIGINT, phpdbg_sigint_handler); } zend_end_try();
1468
1469
1470 PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin);
1471 PHPDBG_G(io)[PHPDBG_STDOUT].fd = fileno(stdout);
1472 PHPDBG_G(io)[PHPDBG_STDERR].fd = fileno(stderr);
1473
1474#ifndef _WIN32
1476 php_stream_stdio_ops.write = phpdbg_stdiop_write;
1477#endif
1478
1479 {
1481 php_stream_wrapper *tmp_wrapper = Z_PTR_P(zv);
1482 PHPDBG_G(orig_url_wrap_php) = tmp_wrapper;
1483 memcpy(&wrapper, tmp_wrapper, sizeof(wrapper));
1484 memcpy(&wops, tmp_wrapper->wops, sizeof(wops));
1486 wrapper.wops = (const php_stream_wrapper_ops*)&wops;
1487 Z_PTR_P(zv) = &wrapper;
1488 }
1489
1490 /* Make stdin, stdout and stderr accessible from PHP scripts */
1492
1494
1495 if (show_banner && cleaning < 2) {
1496 /* print blurb */
1497 phpdbg_welcome(cleaning == 1);
1498 }
1499
1500 cleaning = -1;
1501
1502 if (ext_stmt) {
1503 CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
1504 }
1505
1506 /* initialize from file */
1508 zend_try {
1509 phpdbg_init(init_file, init_file_len, init_file_default);
1510 } zend_end_try();
1512
1513 /* quit if init says so */
1515 goto phpdbg_out;
1516 }
1517
1518 /* auto compile */
1519 if (read_from_stdin) {
1520 if (!read_from_stdin[0]) {
1521 if (!quit_immediately) {
1522 phpdbg_error("Impossible to not specify a stdin delimiter without -rr");
1524 goto phpdbg_out;
1525 }
1526 }
1527 if (show_banner || read_from_stdin[0]) {
1528 phpdbg_notice("Reading input from stdin; put '%s' followed by a newline on an own line after code to end input", read_from_stdin);
1529 }
1530
1531 if (phpdbg_startup_run > 0) {
1533 }
1534
1535 zend_try {
1536 phpdbg_param_t cmd;
1537 cmd.str = read_from_stdin;
1538 cmd.len = strlen(read_from_stdin);
1539 PHPDBG_COMMAND_HANDLER(stdin)(&cmd);
1540 } zend_end_try();
1541
1543 } else if (PHPDBG_G(exec)) {
1544 if (settings || phpdbg_startup_run > 0) {
1546 }
1547
1548 zend_try {
1549 if (backup_phpdbg_compile) {
1550 phpdbg_compile_stdin(backup_phpdbg_compile);
1551 } else {
1553 }
1554 } zend_end_try();
1555 backup_phpdbg_compile = NULL;
1556
1558 }
1559
1560 if (bp_tmp) {
1562 phpdbg_string_init(bp_tmp);
1563 free(bp_tmp);
1564 bp_tmp = NULL;
1566 }
1567
1568 if (settings == (void *) 0x1) {
1569 if (PHPDBG_G(ops)) {
1570 phpdbg_print_opcodes(print_opline_func);
1571 } else {
1572 zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("No opcodes could be compiled | No file specified or compilation failed?\n"));
1573 }
1574 goto phpdbg_out;
1575 }
1576
1577 PG(during_request_startup) = 0;
1578
1579 phpdbg_fully_started = 1;
1580
1581 /* phpdbg main() */
1582 do {
1583 zend_try {
1584 if (phpdbg_startup_run) {
1586 if (quit_immediately) {
1588 } else {
1590 }
1591 zend_try {
1592 if (first_command) {
1593 phpdbg_interactive(1, estrdup(first_command));
1594 } else {
1596 }
1597 } zend_end_try();
1598 if (quit_immediately) {
1599 /* if -r is on the command line more than once just quit */
1600 EG(bailout) = __orig_bailout; /* reset zend_try */
1601 exit_status = EG(exit_status);
1602 break;
1603 }
1604 }
1605
1606 CG(unclean_shutdown) = 0;
1608 } zend_catch {
1610 char *bp_tmp_str;
1614 if (bp_tmp_str) {
1615 bp_tmp = strdup(bp_tmp_str);
1616 free(bp_tmp_str);
1617 }
1618 cleaning = 1;
1619 } else {
1620 cleaning = 0;
1621 }
1622 } zend_end_try();
1623 } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING));
1624
1625#ifdef _WIN32
1626 } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) {
1627 phpdbg_error("Segmentation fault encountered\ntrying to abort cleanly...");
1628 }
1629#endif
1631
1633
1634 if (first_command) {
1635 free(first_command);
1636 first_command = NULL;
1637 }
1638
1639 if (cleaning <= 0) {
1641 cleaning = -1;
1642 }
1643
1644 {
1645 int i;
1646 /* free argv */
1647 for (i = SG(request_info).argc; i--;) {
1648 efree(SG(request_info).argv[i]);
1649 }
1650 efree(SG(request_info).argv);
1651 }
1652
1653 php_ini_builder_deinit(&ini_builder);
1654
1655 if (ini_override) {
1656 free(ini_override);
1657 }
1658
1659 /* In case we aborted during script execution, we may not reset CG(unclean_shutdown) */
1660 if (!(PHPDBG_G(flags) & PHPDBG_IS_RUNNING)) {
1661 is_exit = !PHPDBG_G(in_execution);
1662 CG(unclean_shutdown) = is_exit || PHPDBG_G(unclean_eval);
1663 }
1664
1667 zend_objects_store_mark_destructed(&EG(objects_store));
1668 }
1669
1670 if (PHPDBG_G(exec) && strcmp("Standard input code", PHPDBG_G(exec)) == SUCCESS) { /* i.e. execution context has been read from stdin - back it up */
1671 phpdbg_file_source *data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), PHPDBG_G(exec), PHPDBG_G(exec_len));
1672 size_t size = data->len + 2;
1673 backup_phpdbg_compile = zend_string_alloc(size, 1);
1674 GC_MAKE_PERSISTENT_LOCAL(backup_phpdbg_compile);
1675 snprintf(ZSTR_VAL(backup_phpdbg_compile), size + 1, "?>%.*s", (int) data->len, data->buf);
1676 }
1677
1678 zend_try {
1680 } zend_end_try();
1681
1682 /* backup globals when cleaning */
1683 if ((cleaning > 0) && !quit_immediately) {
1684 settings = calloc(1, sizeof(zend_phpdbg_globals));
1685
1686 php_phpdbg_globals_ctor(settings);
1687
1688 if (PHPDBG_G(exec)) {
1689 settings->exec = zend_strndup(PHPDBG_G(exec), PHPDBG_G(exec_len));
1690 settings->exec_len = PHPDBG_G(exec_len);
1691 }
1692 settings->prompt[0] = PHPDBG_G(prompt)[0];
1693 settings->prompt[1] = PHPDBG_G(prompt)[1];
1694 memcpy(ZEND_VOIDP(settings->colors), PHPDBG_G(colors), sizeof(settings->colors));
1695 settings->input_buflen = PHPDBG_G(input_buflen);
1696 memcpy(settings->input_buffer, PHPDBG_G(input_buffer), settings->input_buflen);
1697 settings->flags = PHPDBG_G(flags) & PHPDBG_PRESERVE_FLAGS_MASK;
1698 first_command = PHPDBG_G(cur_command);
1699 } else {
1700 if (PHPDBG_G(prompt)[0]) {
1701 free(PHPDBG_G(prompt)[0]);
1702 }
1703 if (PHPDBG_G(prompt)[1]) {
1704 free(PHPDBG_G(prompt)[1]);
1705 }
1706 if (PHPDBG_G(cur_command)) {
1707 free(PHPDBG_G(cur_command));
1708 }
1709 }
1710
1711 if (exit_status == 0) {
1712 exit_status = EG(exit_status);
1713 }
1714
1716
1717 if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
1719 if (PHPDBG_G(in_execution) || is_exit) {
1720 if (!quit_immediately && !phpdbg_startup_run) {
1722 cleaning++;
1723 }
1724 }
1725 }
1726
1727 {
1730 }
1731
1732#ifndef _WIN32
1733 /* force override (no zend_signals) to prevent crashes due to signal recursion in SIGSEGV/SIGBUS handlers */
1734 signal(SIGSEGV, SIG_DFL);
1735 signal(SIGBUS, SIG_DFL);
1736
1737 /* reset it... else we risk a stack overflow upon next run (when clean'ing) */
1739#endif
1740 }
1741
1743
1744 sapi_shutdown();
1745
1746 if (sapi_name) {
1747 free(sapi_name);
1748 }
1749
1750free_and_return:
1751 if (read_from_stdin) {
1752 free(read_from_stdin);
1753 read_from_stdin = NULL;
1754 }
1755
1756#ifdef ZTS
1757 /* reset to original handlers - otherwise PHPDBG_G() in phpdbg_watch_efree will be segfaulty (with e.g. USE_ZEND_ALLOC=0) */
1758 if (!use_mm_wrappers) {
1759 zend_mm_set_custom_handlers(zend_mm_get_heap(), _malloc, _free, _realloc);
1760 }
1761
1762 ts_free_id(phpdbg_globals_id);
1763
1764 tsrm_shutdown();
1765#endif
1766
1767 if ((cleaning > 0) && !quit_immediately) {
1768 /* reset internal php_getopt state */
1769 php_getopt(-1, argv, OPTIONS, NULL, &php_optind, 0, 0);
1770
1771 goto phpdbg_main;
1772 }
1773
1774 if (backup_phpdbg_compile) {
1775 zend_string_free(backup_phpdbg_compile);
1776 }
1777
1778 /* usually 0; just for -rr */
1779 return exit_status;
1780} /* }}} */
SAPI_API sapi_module_struct sapi_module
Definition SAPI.c:65
SAPI_API void sapi_deactivate(void)
Definition SAPI.c:549
SAPI_API void sapi_startup(sapi_module_struct *sf)
Definition SAPI.c:68
SAPI_API void sapi_shutdown(void)
Definition SAPI.c:89
sapi_header_op_enum
Definition SAPI.h:191
#define SG(v)
Definition SAPI.h:160
#define SAPI_HEADER_SENT_SUCCESSFULLY
Definition SAPI.h:303
#define STANDARD_SAPI_MODULE_PROPERTIES
Definition SAPI.h:324
struct _sapi_module_struct sapi_module_struct
Definition SAPI.h:60
size_t len
Definition apprentice.c:174
PHPAPI void php_free_shutdown_functions(void)
fprintf($stream, string $format, mixed ... $values)
file(string $filename, int $flags=0, $context=null)
fstat($stream)
prev(array|object &$array)
fclose($stream)
count(Countable|array $value, int $mode=COUNT_NORMAL)
fflush($stream)
stat(string $filename)
char s[4]
Definition cdf.c:77
Definition test.php:8
zval * zv
Definition ffi.c:3975
new_type size
Definition ffi.c:4365
void * ptr
Definition ffi.c:3814
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
HashTable * ht
Definition ffi.c:4838
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define O_BINARY
Definition file.h:643
const php_stream_filter_ops * ops
Definition filters.c:1899
char * mode
#define NULL
Definition gdcache.h:45
int main(void)
Definition gddemo.c:7
PHPAPI int php_getopt(int argc, char *const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err, int arg_start)
Definition getopt.c:55
#define SUCCESS
Definition hash_sha3.c:261
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
void php_request_shutdown(void *dummy)
Definition main.c:1885
zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_module)
Definition main.c:2103
PHPAPI char * php_get_version(sapi_module_struct *sapi_module)
Definition main.c:110
void php_module_shutdown(void)
Definition main.c:2424
zend_result php_request_startup(void)
Definition main.c:1801
int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals)
Definition main.c:2416
PHPAPI int php_output_activate(void)
Definition output.c:159
PHPAPI void php_output_deactivate(void)
Definition output.c:176
const SIGINT
const SIGSEGV
const SIG_DFL
const SIGHUP
const SIGBUS
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MSHUTDOWN_FUNCTION
Definition php.h:401
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_RINIT
Definition php.h:394
#define PHP_MSHUTDOWN
Definition php.h:393
#define PHP_RSHUTDOWN
Definition php.h:395
#define PHP_RINIT_FUNCTION
Definition php.h:402
#define PHP_RSHUTDOWN_FUNCTION
Definition php.h:403
#define PHP_MINIT
Definition php.h:392
#define php_error
Definition php.h:310
short color
int line
Definition php_ffi.h:54
unsigned const char * end
Definition php_ffi.h:51
JMP_BUF bailout
Definition php_ffi.h:49
struct _opt_struct opt_struct
#define PG(v)
Definition php_globals.h:31
PHPAPI void php_ini_builder_define(struct php_ini_builder *b, const char *arg)
PHPAPI void php_ini_builder_unquoted(struct php_ini_builder *b, const char *name, size_t name_length, const char *value, size_t value_length)
#define php_ini_builder_prepend_literal(b, l)
PHP_JSON_API size_t int options
Definition php_json.h:102
#define PUTS(str)
unsigned char key[REFLECTION_KEY_LEN]
PHPAPI zval * php_stream_context_get_option(php_stream_context *context, const char *wrappername, const char *optionname)
Definition streams.c:2407
#define php_stream_fopen_from_fd(fd, mode, persistent_id)
PHPAPI php_stream_ops php_stream_stdio_ops
struct _php_stream_wrapper_ops php_stream_wrapper_ops
struct _php_stream php_stream
Definition php_streams.h:96
struct _php_stream_context php_stream_context
Definition php_streams.h:98
#define STREAMS_DC
Definition php_streams.h:53
#define PHP_STREAM_FLAG_NO_CLOSE
#define STREAMS_CC
Definition php_streams.h:54
#define php_stream_to_zval(stream, zval)
#define php_stream_open_wrapper_ex(path, mode, options, opened, context)
#define php_stream_close(stream)
#define php_stream_get_url_stream_wrappers_hash()
struct _php_stream_wrapper php_stream_wrapper
Definition php_streams.h:97
#define php_stream_set_option(stream, option, value, ptrvalue)
#define PHP_STREAM_OPTION_PIPE_BLOCKING
PHPAPI void(* php_import_environment_variables)(zval *array_ptr)
PHPAPI void php_register_variable(const char *var, const char *strval, zval *track_vars_array)
#define PARSE_SERVER
void phpdbg_register_file_handles(void)
Definition phpdbg.c:882
const char phpdbg_ini_hardcoded[]
Definition phpdbg.c:986
int phpdbg_startup_run
Definition phpdbg.c:46
void phpdbg_free_wrapper(void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Definition phpdbg.c:1077
void * phpdbg_realloc_wrapper(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Definition phpdbg.c:1090
php_stream * phpdbg_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC)
Definition phpdbg.c:1095
HashTable seek
Definition phpdbg.h:233
struct _phpdbg_oplog_entry phpdbg_oplog_entry
Definition phpdbg.h:212
HashTable bp[PHPDBG_BREAK_TABLES]
Definition phpdbg.h:231
#define PHPDBG_DEFAULT_PROMPT
Definition phpdbg.h:96
struct @234323133100145062121301312242002332057146367313 io[PHPDBG_IO_FDS]
#define PHPDBG_STDIN
Definition phpdbg.h:189
ssize_t(* php_stdiop_write)(php_stream *, const char *, size_t)
Definition phpdbg.h:284
#define PHPDBG_STDOUT
Definition phpdbg.h:190
char * sapi_name_ptr
Definition phpdbg.h:310
zend_arena * oplog_arena
Definition phpdbg.h:277
#define PHPDBG_IS_STEPONEVAL
Definition phpdbg.h:157
FILE * stdin_file
Definition phpdbg.h:299
#define PHPDBG_PRESERVE_FLAGS_MASK
Definition phpdbg.h:173
#define PHPDBG_NEXT
Definition phpdbg.h:116
char * exec
Definition phpdbg.h:263
#define PHPDBG_IS_INTERACTIVE
Definition phpdbg.h:160
#define PHPDBG_G(v)
Definition phpdbg.h:102
#define PHPDBG_DISCARD_OUTPUT
Definition phpdbg.h:165
#define PHPDBG_IS_INITIALIZING
Definition phpdbg.h:158
#define PHPDBG_IS_QUIET
Definition phpdbg.h:146
#define PHPDBG_LEAVE
Definition phpdbg.h:119
char input_buffer[PHPDBG_MAX_CMD]
Definition phpdbg.h:302
int fd
Definition phpdbg.h:282
#define PHPDBG_IN_EVAL
Definition phpdbg.h:142
#define PHPDBG_STDERR
Definition phpdbg.h:191
#define PHPDBG_HAS_PAGINATION
Definition phpdbg.h:166
#define PHPDBG_IS_COLOURED
Definition phpdbg.h:148
bool in_execution
Definition phpdbg.h:269
size_t exec_len
Definition phpdbg.h:264
#define PHPDBG_NAME
Definition phpdbg.h:91
JMP_BUF * sigsegv_bailout
Definition phpdbg.h:306
#define PHPDBG_ISSUES
Definition phpdbg.h:93
HashTable file_sources
Definition phpdbg.h:275
struct sigaction old_sigsegv_signal
Definition phpdbg.h:244
const php_stream_wrapper * orig_url_wrap_php
Definition phpdbg.h:300
HashTable registered
Definition phpdbg.h:232
const phpdbg_color_t * colors[PHPDBG_COLORS]
Definition phpdbg.h:295
bool unclean_eval
Definition phpdbg.h:270
#define PHPDBG_FINISH
Definition phpdbg.h:118
#define PHPDBG_VERSION
Definition phpdbg.h:94
#define PHPDBG_DEFAULT_FLAGS
Definition phpdbg.h:183
#define PHPDBG_IS_SIGNALED
Definition phpdbg.h:159
#define PHPDBG_UNTIL
Definition phpdbg.h:117
int input_buflen
Definition phpdbg.h:303
#define PHPDBG_PREVENT_INTERACTIVE
Definition phpdbg.h:161
#define PHPDBG_IS_RUNNING
Definition phpdbg.h:150
#define PHPDBG_IS_QUITTING
Definition phpdbg.h:147
phpdbg_oplog_list * oplog_list
Definition phpdbg.h:278
void(* original_free_function)(void *ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Definition phpdbg.h:260
#define PHPDBG_IS_STOPPING
Definition phpdbg.h:171
#define PHPDBG_IS_CLEANING
Definition phpdbg.h:149
phpdbg_oplog_entry * oplog_cur
Definition phpdbg.h:279
struct _phpdbg_oplog_list phpdbg_oplog_list
Definition phpdbg.h:222
char * cur_command
Definition phpdbg.h:239
phpdbg_break_next()
phpdbg_clear()
phpdbg_break_function(string $function)
phpdbg_prompt(string $string)
phpdbg_exec(string $context)
phpdbg_break_method(string $class, string $method)
phpdbg_start_oplog()
phpdbg_end_oplog(array $options=[])
phpdbg_get_executable(array $options=[])
phpdbg_color(int $element, string $color)
phpdbg_break_file(string $file, int $line)
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, size_t path_len, zend_ulong line_num)
Definition phpdbg_bp.c:256
PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline)
Definition phpdbg_bp.c:806
PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str)
Definition phpdbg_bp.c:117
PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len)
Definition phpdbg_bp.c:404
PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char *func_name)
Definition phpdbg_bp.c:435
#define PHPDBG_BREAK_FUNCTION_OPLINE
Definition phpdbg_bp.h:30
#define PHPDBG_BREAK_COND
Definition phpdbg_bp.h:28
#define PHPDBG_BREAK_FILE_OPLINE
Definition phpdbg_bp.h:32
#define PHPDBG_BREAK_OPLINE
Definition phpdbg_bp.h:26
#define PHPDBG_BREAK_SYM
Definition phpdbg_bp.h:25
#define PHPDBG_BREAK_FILE_PENDING
Definition phpdbg_bp.h:24
#define PHPDBG_BREAK_METHOD
Definition phpdbg_bp.h:27
#define PHPDBG_BREAK_OPCODE
Definition phpdbg_bp.h:29
#define PHPDBG_BREAK_METHOD_OPLINE
Definition phpdbg_bp.h:31
struct _phpdbg_breakop_t phpdbg_breakop_t
#define PHPDBG_BREAK_MAP
Definition phpdbg_bp.h:33
struct _zend_op * phpdbg_opline_ptr_t
Definition phpdbg_bp.h:37
#define PHPDBG_BREAK_FILE
Definition phpdbg_bp.h:23
struct _phpdbg_breakcond_t phpdbg_breakcond_t
struct _phpdbg_breaksymbol_t phpdbg_breaksymbol_t
struct _phpdbg_param phpdbg_param_t
Definition phpdbg_cmd.h:51
#define PHPDBG_STRL(s)
Definition phpdbg_cmd.h:104
#define PHPDBG_COMMAND_HANDLER(name)
Definition phpdbg_cmd.h:156
void phpdbg_do_help_cmd(const char *type)
zend_constant * data
void phpdbg_init_list(void)
void phpdbg_list_update(void)
void phpdbg_list_file(zend_string *filename, uint32_t count, int offset, uint32_t highlight)
int phpdbg_process_print(int fd, int type, const char *msg, int msglen)
Definition phpdbg_out.c:43
#define phpdbg_error(strfmt,...)
Definition phpdbg_out.h:43
#define phpdbg_out(fmt,...)
Definition phpdbg_out.h:49
#define phpdbg_write(strfmt,...)
Definition phpdbg_out.h:46
#define phpdbg_script(type, strfmt,...)
Definition phpdbg_out.h:51
#define phpdbg_notice(strfmt,...)
Definition phpdbg_out.h:44
#define phpdbg_writeln(strfmt,...)
Definition phpdbg_out.h:45
@ P_STDERR
Definition phpdbg_out.h:35
@ P_STDOUT
Definition phpdbg_out.h:34
void phpdbg_print_opcodes(const char *function)
void phpdbg_init(char *init_file, size_t init_file_len, bool use_default)
void phpdbg_string_init(char *buffer)
zend_object * ex
int phpdbg_compile_stdin(zend_string *code)
int phpdbg_compile(void)
void phpdbg_force_interruption(void)
void phpdbg_execute_ex(zend_execute_data *execute_data)
int phpdbg_interactive(bool allow_async_unsafe, char *input)
void phpdbg_clear_sigsafe_mem(void)
void phpdbg_set_sigsafe_mem(char *buffer)
#define PHPDBG_SIGSAFE_MEM_SIZE
PHPDBG_API char * phpdbg_resolve_path(const char *path)
PHPDBG_API void phpdbg_set_color_ex(int element, const char *name, size_t name_length)
PHPDBG_API void phpdbg_set_prompt(const char *prompt)
PHPDBG_API uint32_t phpdbg_get_terminal_height(void)
#define PHPDBG_COLOR_PROMPT
#define PHPDBG_COLOR_NOTICE
#define PHPDBG_COLOR_ERROR
int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context)
void phpdbg_purge_watchpoint_tree(void)
void phpdbg_destroy_watchpoints(void)
void phpdbg_watch_efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
void phpdbg_setup_watchpoints(void)
int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp)
Definition phpdbg_win.c:27
char * prompt
p
Definition session.c:1105
#define strpprintf
Definition spprintf.h:30
#define spprintf
Definition spprintf.h:29
php_stream *(* stream_opener)(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC)
const php_stream_wrapper_ops * wops
uint32_t flags
void * abstract
zend_op_array * ops
Definition phpdbg_bp.h:115
zend_string * function_name
Definition phpdbg.h:215
zend_class_entry * scope
Definition phpdbg.h:216
zend_op * opcodes
Definition phpdbg.h:218
zend_string * filename
Definition phpdbg.h:217
zend_op * op
Definition phpdbg.h:219
phpdbg_oplog_entry * next
Definition phpdbg.h:214
phpdbg_oplog_list * prev
Definition phpdbg.h:224
struct _zend_class_entry::@126215362204241324314155352336150042254204116267::@166057154351252324007362117353350250255142166322 user
zend_string * filename
Definition zend.h:228
zend_string * name
Definition zend.h:149
union _zend_class_entry::@126215362204241324314155352336150042254204116267 info
char type
Definition zend.h:148
HashTable function_table
Definition zend.h:163
zend_string * name
zend_string * filename
uint32_t num_args
zend_op * opcodes
zend_string * function_name
uint32_t fn_flags
uint8_t opcode
uint32_t lineno
Definition file.h:177
Definition dce.c:49
zend_op_array op_array
Definition phpdbg_list.h:45
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
#define ZEND_TSRMLS_CACHE_UPDATE()
Definition zend.h:69
#define zend_catch
Definition zend.h:277
#define zend_try
Definition zend.h:270
#define zend_end_try()
Definition zend.h:280
#define ZEND_TSRMLS_CACHE_DEFINE()
Definition zend.h:68
#define zend_bailout()
Definition zend.h:268
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1300
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor)
Definition zend_API.h:272
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
Definition zend_API.h:268
#define zend_parse_parameters_none()
Definition zend_API.h:353
#define RETURN_THROWS()
Definition zend_API.h:1060
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
#define array_init(arg)
Definition zend_API.h:537
ZEND_API void ZEND_FASTCALL _zend_mm_free(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
ZEND_API char *ZEND_FASTCALL zend_strndup(const char *s, size_t length)
void *ZEND_FASTCALL _zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap, void *(*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), void(*_free)(void *ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), void *(*_realloc)(void *, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap, void *(**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), void(**_free)(void *ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), void *(**_realloc)(void *, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
ZEND_API zend_mm_heap * zend_mm_get_heap(void)
ZEND_API void *ZEND_FASTCALL _zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
struct _zend_mm_heap zend_mm_heap
Definition zend_alloc.h:244
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
exit(string|int $status=0)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
execute_data func
struct _zend_op zend_op
#define ZEND_USER_CODE(type)
ZEND_API void destroy_op_array(zend_op_array *op_array)
#define ZEND_COMPILE_EXTENDED_INFO
#define ZEND_USER_FUNCTION
struct _zend_op_array zend_op_array
#define ZEND_ACC_VARIADIC
#define ZEND_USER_CLASS
#define strncasecmp(s1, s2, n)
#define snprintf
ZEND_API zend_result zend_register_constant(zend_constant *c)
struct _zend_constant zend_constant
#define E_WARNING
Definition zend_errors.h:24
#define E_FATAL_ERRORS
Definition zend_errors.h:47
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API uint32_t zend_get_executed_lineno(void)
ZEND_API const char * zend_get_executed_filename(void)
ZEND_API void(* zend_execute_ex)(zend_execute_data *execute_data)
ZEND_API zend_llist zend_extensions
struct _zend_extension zend_extension
union _zend_function zend_function
#define CG(v)
#define EG(v)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
Definition zend_hash.c:1727
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
Definition zend_hash.c:2689
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
Definition zend_hash.c:1214
ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
Definition zend_hash.c:1869
ZEND_API zval *ZEND_FASTCALL zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:1007
ZEND_API zval *ZEND_FASTCALL zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData)
Definition zend_hash.c:1219
ZEND_API zval *ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_string *key)
Definition zend_hash.c:1067
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
Definition zend_hash.c:1534
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
Definition zend_hash.c:2668
ZEND_API zval *ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h)
Definition zend_hash.c:2701
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
Definition zend_hash.h:108
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
Definition zend_hash.h:1326
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
Definition zend_hash.h:1346
#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
Definition zend_hash.h:1433
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZEND_HASH_FOREACH_VAL(ht, _val)
Definition zend_hash.h:1102
ZEND_API zend_result zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, bool force_change)
Definition zend_ini.c:356
#define ZEND_INI_SYSTEM
Definition zend_ini.h:26
#define ZEND_INI_STAGE_STARTUP
Definition zend_ini.h:227
int32_t zend_long
Definition zend_long.h:42
uint32_t zend_ulong
Definition zend_long.h:43
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES
ZEND_API void ZEND_FASTCALL zend_objects_store_mark_destructed(zend_objects_store *objects)
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
ZEND_API void ZEND_FASTCALL convert_to_long(zval *op)
#define zend_quiet_write(...)
#define LONGJMP(a, b)
#define ZEND_FILE_LINE_DC
#define zend_always_inline
#define ZEND_FILE_LINE_ORIG_RELAY_CC
#define ZEND_ASSERT(c)
#define ZEND_ATTRIBUTE_MALLOC
#define ZEND_STRL(str)
#define ZEND_VOIDP(ptr)
#define ZEND_ATTRIBUTE_ALLOC_SIZE(X)
#define UNEXPECTED(condition)
#define ZEND_NORETURN
#define ZEND_FILE_LINE_RELAY_CC
#define ZEND_FILE_LINE_ORIG_DC
struct _zend_class_entry zend_class_entry
#define zend_signal_activate()
#define zend_signal_startup()
#define zend_sigaction(signo, act, oldact)
#define zend_signal(signo, handler)
struct stat zend_stat_t
Definition zend_stream.h:94
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define ZVAL_FALSE(z)
#define Z_CONSTANT_FLAGS(zval)
Definition zend_types.h:692
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define ZVAL_TRUE(z)
#define ZVAL_DEREF(z)
#define ZVAL_LONG(z, l)
struct _zend_array HashTable
Definition zend_types.h:386
#define IS_ARRAY
Definition zend_types.h:607
#define Z_PTR_P(zval_p)
#define GC_DELREF(p)
Definition zend_types.h:710
#define GC_ADDREF(p)
Definition zend_types.h:709
#define GC_MAKE_PERSISTENT_LOCAL(p)
@ FAILURE
Definition zend_types.h:61
struct _zend_execute_data zend_execute_data
Definition zend_types.h:91
#define Z_ARR_P(zval_p)
Definition zend_types.h:984
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
#define VCWD_STAT(path, buff)
#define S_IFLNK
ZEND_API int zend_vm_kind(void)
zval * return_value
zend_string * name
bool result
function(EX_VAR(opline->result.var))
value
#define ZEND_FE_FREE
#define ZEND_DECLARE_ANON_CLASS
#define ZEND_EXT_FCALL_END
#define ZEND_NEW
#define ZEND_VERIFY_RETURN_TYPE
#define ZEND_RETURN
#define ZEND_THROW
#define ZEND_TICKS
#define ZEND_ASSERT_CHECK
#define ZEND_EXT_STMT
#define ZEND_OP_DATA
#define ZEND_RETURN_BY_REF
#define ZEND_DECLARE_CONST
#define ZEND_DECLARE_CLASS_DELAYED
#define ZEND_NOP
#define ZEND_DECLARE_FUNCTION
#define ZEND_EXT_FCALL_BEGIN
#define ZEND_VM_KIND_HYBRID
#define ZEND_DO_FCALL
#define ZEND_BIND_INIT_STATIC_OR_JMP
#define ZEND_BIND_GLOBAL
#define ZEND_GENERATOR_RETURN
#define ZEND_DECLARE_CLASS
#define ZEND_FREE
#define ZEND_FAST_RET