php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
phpdbg_prompt.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 <stdio.h>
20#include <string.h>
21#include "zend.h"
22#include "zend_compile.h"
23#include "zend_exceptions.h"
24#include "zend_vm.h"
25#include "zend_generators.h"
26#include "zend_interfaces.h"
27#include "zend_smart_str.h"
28#include "phpdbg.h"
29#include "phpdbg_io.h"
30
31#include "phpdbg_help.h"
32#include "phpdbg_print.h"
33#include "phpdbg_info.h"
34#include "phpdbg_break.h"
35#include "phpdbg_list.h"
36#include "phpdbg_utils.h"
37#include "phpdbg_prompt.h"
38#include "phpdbg_cmd.h"
39#include "phpdbg_set.h"
40#include "phpdbg_frame.h"
41#include "phpdbg_lexer.h"
42#include "phpdbg_parser.h"
43
44#if ZEND_VM_KIND != ZEND_VM_KIND_CALL && ZEND_VM_KIND != ZEND_VM_KIND_HYBRID
45#error "phpdbg can only be built with CALL zend vm kind"
46#endif
47
49extern int phpdbg_startup_run;
50
51#ifdef HAVE_LIBDL
52#ifdef PHP_WIN32
53#include "win32/param.h"
54#include "win32/winutil.h"
55#define GET_DL_ERROR() php_win_err()
56#else
57#include <sys/param.h>
58#define GET_DL_ERROR() DL_ERROR()
59#endif
60#endif
61
62/* {{{ command declarations */
64 PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s", 0),
65 PHPDBG_COMMAND_D(stdin, "read script from stdin", 0 , NULL, "s", 0),
66 PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0, PHPDBG_ASYNC_SAFE),
67 PHPDBG_COMMAND_D(continue, "continue execution", 'c', NULL, 0, PHPDBG_ASYNC_SAFE),
68 PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s", 0),
69 PHPDBG_COMMAND_D(ev, "evaluate some code", 0 , NULL, "i", PHPDBG_ASYNC_SAFE), /* restricted ASYNC_SAFE */
70 PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0, 0),
71 PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0, 0),
72 PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0, 0),
73 PHPDBG_COMMAND_D(generator, "inspect or switch to a generator", 'g', NULL, "|n", 0),
74 PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, "|*c", 0),
75 PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "|*c", 0),
76 PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n", PHPDBG_ASYNC_SAFE),
77 PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n", PHPDBG_ASYNC_SAFE),
78 PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*", PHPDBG_ASYNC_SAFE),
79 PHPDBG_COMMAND_D(info, "displays some information", 'i', phpdbg_info_commands, "|s", PHPDBG_ASYNC_SAFE),
80 PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0, 0),
81 PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0, 0),
82 PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s", PHPDBG_ASYNC_SAFE),
83 PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s", PHPDBG_ASYNC_SAFE),
84 PHPDBG_COMMAND_D(register, "register a function", 'R', NULL, "s", 0),
85 PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s", 0),
86 PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s", PHPDBG_ASYNC_SAFE),
87 PHPDBG_COMMAND_D(sh, "shell a command", 0 , NULL, "i", 0),
88 PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0, PHPDBG_ASYNC_SAFE),
89 PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss", 0),
90 PHPDBG_COMMAND_D(next, "step over next line", 'n', NULL, 0, PHPDBG_ASYNC_SAFE),
92}; /* }}} */
93
94static inline int phpdbg_call_register(phpdbg_param_t *stack) /* {{{ */
95{
97
98 if (stack->type == STACK_PARAM) {
99 char *lc_name;
100
101 name = stack->next;
102
103 if (!name || name->type != STR_PARAM) {
104 return FAILURE;
105 }
106
107 lc_name = zend_str_tolower_dup(name->str, name->len);
108
109 if (zend_hash_str_exists(&PHPDBG_G(registered), lc_name, name->len)) {
110 zval fretval;
111 zend_fcall_info fci;
112
113 memset(&fci, 0, sizeof(zend_fcall_info));
114
115 ZVAL_STRINGL(&fci.function_name, lc_name, name->len);
116 fci.size = sizeof(zend_fcall_info);
117 fci.object = NULL;
118 fci.retval = &fretval;
119 fci.param_count = 0;
120 fci.params = NULL;
121 fci.named_params = NULL;
122
123 zval params;
124 if (name->next) {
125 phpdbg_param_t *next = name->next;
126
127 array_init(&params);
128
129 while (next) {
130 char *buffered = NULL;
131
132 switch (next->type) {
133 case OP_PARAM:
134 case COND_PARAM:
135 case STR_PARAM:
136 add_next_index_stringl(&params, next->str, next->len);
137 break;
138
139 case NUMERIC_PARAM:
140 add_next_index_long(&params, next->num);
141 break;
142
143 case METHOD_PARAM:
144 spprintf(&buffered, 0, "%s::%s", next->method.class, next->method.name);
145 add_next_index_string(&params, buffered);
146 break;
147
149 spprintf(&buffered, 0, "%s::%s#"ZEND_LONG_FMT, next->method.class, next->method.name, next->num);
150 add_next_index_string(&params, buffered);
151 break;
152
154 spprintf(&buffered, 0, "%s#"ZEND_LONG_FMT, next->str, next->num);
155 add_next_index_string(&params, buffered);
156 break;
157
158 case FILE_PARAM:
159 spprintf(&buffered, 0, "%s:"ZEND_ULONG_FMT, next->file.name, next->file.line);
160 add_next_index_string(&params, buffered);
161 break;
162
164 spprintf(&buffered, 0, "%s:#"ZEND_ULONG_FMT, next->file.name, next->file.line);
165 add_next_index_string(&params, buffered);
166 break;
167
168 default: {
169 /* not yet */
170 }
171 }
172
173 next = next->next;
174 }
175 /* Add positional arguments */
176 fci.named_params = Z_ARRVAL(params);
177 }
178
181
182 phpdbg_debug("created %d params from arguments", fci.param_count);
183
184 if (zend_call_function(&fci, NULL) == SUCCESS) {
185 zend_print_zval_r(&fretval, 0);
186 phpdbg_out("\n");
187 zval_ptr_dtor(&fretval);
188 }
189
190 zval_ptr_dtor_str(&fci.function_name);
191 efree(lc_name);
192 if (fci.named_params) {
194 }
195
196 return SUCCESS;
197 }
198
199 efree(lc_name);
200 }
201
202 return FAILURE;
203} /* }}} */
204
206 int line;
208 char *code;
209 size_t code_len;
210 const char *init_file;
211};
212
213static void phpdbg_line_init(char *cmd, struct phpdbg_init_state *state) {
214 size_t cmd_len = strlen(cmd);
215
216 state->line++;
217
218 while (cmd_len > 0L && isspace(cmd[cmd_len-1])) {
219 cmd_len--;
220 }
221
222 cmd[cmd_len] = '\0';
223
224 if (*cmd && cmd_len > 0L && cmd[0] != '#') {
225 if (cmd_len == 2) {
226 if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
227 state->in_code = 1;
228 return;
229 } else {
230 if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
231 state->in_code = 0;
232 state->code[state->code_len] = '\0';
233 zend_eval_stringl(state->code, state->code_len, NULL, "phpdbginit code");
234 free(state->code);
235 state->code = NULL;
236 return;
237 }
238 }
239 }
240
241 if (state->in_code) {
242 if (state->code == NULL) {
243 state->code = malloc(cmd_len + 1);
244 } else {
245 state->code = realloc(state->code, state->code_len + cmd_len + 1);
246 }
247
248 if (state->code) {
249 memcpy(&state->code[state->code_len], cmd, cmd_len);
250 state->code_len += cmd_len;
251 }
252
253 return;
254 }
255
256 zend_try {
257 char *input = phpdbg_read_input(cmd);
258 phpdbg_param_t stack;
259
261
263
264 if (phpdbg_do_parse(&stack, input) <= 0) {
265 switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */)) {
266 case FAILURE:
268 if (phpdbg_call_register(&stack) == FAILURE) {
269 if (state->init_file) {
270 phpdbg_output_err_buf("Unrecognized command in %s:%d: %s, %s!", state->init_file, state->line, input, PHPDBG_G(err_buf).msg);
271 } else {
272 phpdbg_output_err_buf("Unrecognized command on line %d: %s, %s!", state->line, input, PHPDBG_G(err_buf).msg);
273 }
274 }
275 break;
276 }
277 }
278
281
282 phpdbg_stack_free(&stack);
283 phpdbg_destroy_input(&input);
284 } zend_catch {
287 zend_bailout();
288 }
289 } zend_end_try();
290 }
291
292}
293
295 struct phpdbg_init_state state = {0};
296 char *str = strtok(buffer, "\n");
297
298 while (str) {
299 phpdbg_line_init(str, &state);
300
301 str = strtok(NULL, "\n");
302 }
303
304 if (state.code) {
305 free(state.code);
306 }
307}
308
309void phpdbg_try_file_init(char *init_file, size_t init_file_len, bool free_init) /* {{{ */
310{
311 zend_stat_t sb = {0};
312
313 if (init_file && VCWD_STAT(init_file, &sb) != -1) {
314 FILE *fp = fopen(init_file, "r");
315 if (fp) {
316 char cmd[PHPDBG_MAX_CMD];
317 struct phpdbg_init_state state = {0};
318
319 state.init_file = init_file;
320
321 while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
322 phpdbg_line_init(cmd, &state);
323 }
324
325 if (state.code) {
326 free(state.code);
327 }
328
329 fclose(fp);
330 } else {
331 phpdbg_error("Failed to open %s for initialization", init_file);
332 }
333
334 if (free_init) {
335 free(init_file);
336 }
337 }
338} /* }}} */
339
340void phpdbg_init(char *init_file, size_t init_file_len, bool use_default) /* {{{ */
341{
342 if (init_file) {
343 phpdbg_try_file_init(init_file, init_file_len, 1);
344 } else if (use_default) {
345 char *scan_dir = getenv("PHP_INI_SCAN_DIR");
346 char *sys_ini;
347 int i;
348
349 size_t sys_ini_length = asprintf(&sys_ini, "%s/" PHPDBG_INIT_FILENAME, PHP_CONFIG_FILE_PATH);
350 phpdbg_try_file_init(sys_ini, sys_ini_length, 0);
351 free(sys_ini);
352
353 if (!scan_dir) {
354 scan_dir = PHP_CONFIG_FILE_SCAN_DIR;
355 }
356 while (*scan_dir != 0) {
357 i = 0;
358 while (scan_dir[i] != ':') {
359 if (scan_dir[i++] == 0) {
360 i = -1;
361 break;
362 }
363 }
364 if (i != -1) {
365 scan_dir[i] = 0;
366 }
367
369 phpdbg_try_file_init(init_file, init_file_len, 0);
370 free(init_file);
371 if (i == -1) {
372 break;
373 }
374 scan_dir += i + 1;
375 }
376
378 }
379}
380/* }}} */
381
382void phpdbg_clean(bool full, bool resubmit) /* {{{ */
383{
384 /* this is implicitly required */
385 if (PHPDBG_G(ops)) {
388 PHPDBG_G(ops) = NULL;
389 }
390
391 if (!resubmit && PHPDBG_G(cur_command)) {
392 free(PHPDBG_G(cur_command));
394 }
395
396 if (full) {
398 }
399} /* }}} */
400
401PHPDBG_COMMAND(exec) /* {{{ */
402{
403 zend_stat_t sb = {0};
404
405 if (VCWD_STAT(param->str, &sb) != FAILURE) {
406 if (sb.st_mode & (S_IFREG|S_IFLNK)) {
407 char *res = phpdbg_resolve_path(param->str);
408 size_t res_len = strlen(res);
409
410 if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) {
411 if (PHPDBG_G(in_execution)) {
412 if (phpdbg_ask_user_permission("Do you really want to stop execution to set a new execution context?") == FAILURE) {
413 free(res);
414 return FAILURE;
415 }
416 }
417
418 if (PHPDBG_G(exec)) {
419 phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec));
420 free(PHPDBG_G(exec));
421 PHPDBG_G(exec) = NULL;
422 PHPDBG_G(exec_len) = 0L;
423 }
424
425 if (PHPDBG_G(ops)) {
426 phpdbg_notice("Destroying compiled opcodes");
427 phpdbg_clean(0, 0);
428 }
429
430 PHPDBG_G(exec) = res;
431 PHPDBG_G(exec_len) = res_len;
432
434
435 *SG(request_info).argv = estrndup(PHPDBG_G(exec), PHPDBG_G(exec_len));
436 php_build_argv(NULL, &PG(http_globals)[TRACK_VARS_SERVER]);
437
438 phpdbg_notice("Set execution context: %s", PHPDBG_G(exec));
439
440 if (PHPDBG_G(in_execution)) {
441 phpdbg_clean(1, 0);
442 return SUCCESS;
443 }
444
446 } else {
447 free(res);
448 phpdbg_notice("Execution context not changed");
449 }
450 } else {
451 phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str);
452 }
453 } else {
454 phpdbg_error("Cannot stat %s, ensure the file exists", param->str);
455 }
456 return SUCCESS;
457} /* }}} */
458
460{
461 smart_str code = {0};
462 char *buf;
463 char *sep = param->str;
464 int seplen = param->len;
465 int bytes = 0;
466
467 smart_str_appends(&code, "?>");
468
469 do {
470 PHPDBG_G(input_buflen) += bytes;
471 if (PHPDBG_G(input_buflen) <= 0) {
472 continue;
473 }
474
475 if (sep && seplen) {
476 char *nl = buf = PHPDBG_G(input_buffer);
477 do {
478 if (buf == nl + seplen) {
479 if (!memcmp(sep, nl, seplen) && (*buf == '\n' || (*buf == '\r' && buf[1] == '\n'))) {
480 smart_str_appendl(&code, PHPDBG_G(input_buffer), nl - PHPDBG_G(input_buffer));
482 goto exec_code;
483 }
484 }
485 if (*buf == '\n') {
486 nl = buf + 1;
487 }
488 buf++;
489 } while (--PHPDBG_G(input_buflen));
490 if (buf != nl && buf <= nl + seplen) {
491 smart_str_appendl(&code, PHPDBG_G(input_buffer), nl - PHPDBG_G(input_buffer));
492 PHPDBG_G(input_buflen) = buf - nl;
494 } else {
496 smart_str_appendl(&code, PHPDBG_G(input_buffer), buf - PHPDBG_G(input_buffer));
497 }
498 } else {
499 smart_str_appendl(&code, PHPDBG_G(input_buffer), PHPDBG_G(input_buflen));
501 }
503
504 if (bytes < 0) {
506 zend_bailout();
507 }
508
509exec_code:
510 smart_str_0(&code);
511
514 zend_bailout();
515 }
516
517 return SUCCESS;
518} /* }}} */
519
522 zend_string_release(code);
523
524 if (EG(exception)) {
525 return FAILURE;
526 }
527
528 if (PHPDBG_G(exec)) {
529 free(PHPDBG_G(exec));
530 }
531 PHPDBG_G(exec) = strdup("Standard input code");
532 PHPDBG_G(exec_len) = sizeof("Standard input code") - 1;
533 { /* remove leading ?> from source */
534 int i;
535 /* remove trailing data after zero byte, used for avoiding conflicts in eval()'ed code snippets */
536 zend_string *source_path = strpprintf(0, "Standard input code%c%p", 0, PHPDBG_G(ops)->opcodes);
537 phpdbg_file_source *data = zend_hash_find_ptr(&PHPDBG_G(file_sources), source_path);
538 dtor_func_t dtor = PHPDBG_G(file_sources).pDestructor;
539 PHPDBG_G(file_sources).pDestructor = NULL;
540 zend_hash_del(&PHPDBG_G(file_sources), source_path);
541 PHPDBG_G(file_sources).pDestructor = dtor;
542 zend_hash_str_update_ptr(&PHPDBG_G(file_sources), "Standard input code", sizeof("Standard input code")-1, data);
543 zend_string_release(source_path);
544
545 for (i = 1; i <= data->lines; i++) {
546 data->line[i] -= 2;
547 }
548 data->len -= 2;
549 memmove(data->buf, data->buf + 2, data->len);
550 }
551
552 phpdbg_notice("Successful compilation of stdin input");
553
554 return SUCCESS;
555}
556
557int phpdbg_compile(void) /* {{{ */
558{
560 char *buf;
561 size_t len;
562
563 if (!PHPDBG_G(exec)) {
564 phpdbg_error("No execution context");
565 return FAILURE;
566 }
567
570 CG(skip_shebang) = 1;
573 if (EG(exception)) {
575 zend_bailout();
576 }
577
578 phpdbg_notice("Successful compilation of %s", PHPDBG_G(exec));
579
580 return SUCCESS;
581 } else {
582 phpdbg_error("Could not open file %s", PHPDBG_G(exec));
583 }
585 return FAILURE;
586} /* }}} */
587
588PHPDBG_COMMAND(step) /* {{{ */
589{
590 if (PHPDBG_G(in_execution)) {
592 }
593
594 return PHPDBG_NEXT;
595} /* }}} */
596
597PHPDBG_COMMAND(continue) /* {{{ */
598{
599 return PHPDBG_NEXT;
600} /* }}} */
601
602int phpdbg_skip_line_helper(void) /* {{{ */ {
603 zend_execute_data *ex = phpdbg_user_execute_data(EG(current_execute_data));
604 const zend_op_array *op_array = &ex->func->op_array;
605 const zend_op *opline = op_array->opcodes;
606
609 do {
610 if (opline->lineno != ex->opline->lineno
611 || opline->opcode == ZEND_RETURN
612 || opline->opcode == ZEND_FAST_RET
613 || opline->opcode == ZEND_GENERATOR_RETURN
614 || opline->opcode == ZEND_YIELD
615 || opline->opcode == ZEND_YIELD_FROM
616 ) {
617 zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
618 }
619 } while (++opline < op_array->opcodes + op_array->last);
620
621 return PHPDBG_UNTIL;
622}
623/* }}} */
624
625PHPDBG_COMMAND(until) /* {{{ */
626{
627 if (!PHPDBG_G(in_execution)) {
628 phpdbg_error("Not executing");
629 return SUCCESS;
630 }
631
633} /* }}} */
634
635PHPDBG_COMMAND(next) /* {{{ */
636{
637 if (!PHPDBG_G(in_execution)) {
638 phpdbg_error("Not executing");
639 return SUCCESS;
640 }
641
644} /* }}} */
645
646static void phpdbg_seek_to_end(void) /* {{{ */ {
647 zend_execute_data *ex = phpdbg_user_execute_data(EG(current_execute_data));
648 const zend_op_array *op_array = &ex->func->op_array;
649 const zend_op *opline = op_array->opcodes;
650
652 do {
653 switch (opline->opcode) {
654 case ZEND_RETURN:
655 case ZEND_FAST_RET:
657 case ZEND_YIELD:
658 case ZEND_YIELD_FROM:
659 zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
660 }
661 } while (++opline < op_array->opcodes + op_array->last);
662}
663/* }}} */
664
665PHPDBG_COMMAND(finish) /* {{{ */
666{
667 if (!PHPDBG_G(in_execution)) {
668 phpdbg_error("Not executing");
669 return SUCCESS;
670 }
671
672 phpdbg_seek_to_end();
673 if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) phpdbg_user_execute_data(EG(current_execute_data))->opline)) {
675 } else {
677 }
678
680} /* }}} */
681
682PHPDBG_COMMAND(leave) /* {{{ */
683{
684 if (!PHPDBG_G(in_execution)) {
685 phpdbg_error("Not executing");
686 return SUCCESS;
687 }
688
689 phpdbg_seek_to_end();
690 if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) phpdbg_user_execute_data(EG(current_execute_data))->opline)) {
692 phpdbg_notice("Already at the end of the function");
693 return SUCCESS;
694 } else {
697 }
698} /* }}} */
699
700PHPDBG_COMMAND(frame) /* {{{ */
701{
702 if (!param) {
703 phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num);
704 } else {
705 phpdbg_switch_frame(param->num);
706 }
707
708 return SUCCESS;
709} /* }}} */
710
711static inline void phpdbg_handle_exception(void) /* {{{ */
712{
716 zval rv, tmp;
717
718 EG(exception) = NULL;
719
720 zend_call_known_instance_method_with_0_params(ex->ce->__tostring, ex, &tmp);
721 file = zval_get_string(zend_read_property_ex(zend_get_exception_base(ex), ex, ZSTR_KNOWN(ZEND_STR_FILE), /* silent */ true, &rv));
722 line = zval_get_long(zend_read_property_ex(zend_get_exception_base(ex), ex, ZSTR_KNOWN(ZEND_STR_LINE), /* silent */ true, &rv));
723
724 if (EG(exception)) {
725 EG(exception) = NULL;
727 } else {
729 zval_ptr_dtor(&tmp);
730 msg = zval_get_string(zend_read_property_ex(zend_get_exception_base(ex), ex, ZSTR_KNOWN(ZEND_STR_STRING), /* silent */ true, &rv));
731 }
732
733 phpdbg_error("Uncaught %s in %s on line " ZEND_LONG_FMT, ZSTR_VAL(ex->ce->name), ZSTR_VAL(file), line);
734 zend_string_release(file);
736 zend_string_release(msg);
737
738 if (EG(prev_exception)) {
739 OBJ_RELEASE(EG(prev_exception));
740 EG(prev_exception) = 0;
741 }
743 EG(opline_before_exception) = NULL;
744
745 EG(exit_status) = 255;
746} /* }}} */
747
748PHPDBG_COMMAND(run) /* {{{ */
749{
750 if (PHPDBG_G(ops) || PHPDBG_G(exec)) {
751 zend_execute_data *ex = EG(current_execute_data);
752 bool restore = 1;
753
754 if (PHPDBG_G(in_execution)) {
755 if (phpdbg_ask_user_permission("Do you really want to restart execution?") == SUCCESS) {
757 phpdbg_clean(1, 1);
758 }
759 return SUCCESS;
760 }
761
762 if (!PHPDBG_G(ops)) {
763 if (phpdbg_compile() == FAILURE) {
764 phpdbg_error("Failed to compile %s, cannot run", PHPDBG_G(exec));
765 EG(exit_status) = FAILURE;
766 goto out;
767 }
768 }
769
770 if (param && param->type != EMPTY_PARAM && param->len != 0) {
771 char **argv = emalloc(5 * sizeof(char *));
772 char *end = param->str + param->len, *p = param->str;
773 char last_byte;
774 int argc = 0;
775 int i;
776
777 while (*end == '\r' || *end == '\n') *(end--) = 0;
778 last_byte = end[1];
779 end[1] = 0;
780
781 while (*p == ' ') p++;
782 while (*p) {
783 char sep = ' ';
784 char *buf = emalloc(end - p + 2), *q = buf;
785
786 if (*p == '<') {
787 /* use as STDIN */
788 do p++; while (*p == ' ');
789
790 if (*p == '\'' || *p == '"') {
791 sep = *(p++);
792 }
793 while (*p && *p != sep) {
794 if (*p == '\\' && (p[1] == sep || p[1] == '\\')) {
795 p++;
796 }
797 *(q++) = *(p++);
798 }
799 *(q++) = 0;
800 if (*p) {
801 do p++; while (*p == ' ');
802 }
803
804 if (*p) {
805 phpdbg_error("Invalid run command, cannot put further arguments after stdin");
806 goto free_cmd;
807 }
808
809 PHPDBG_G(stdin_file) = fopen(buf, "r");
810 if (PHPDBG_G(stdin_file) == NULL) {
811 phpdbg_error("Could not open '%s' for reading from stdin", buf);
812 goto free_cmd;
813 }
814 efree(buf);
816 break;
817 }
818
819 if (argc >= 4 && argc == (argc & -argc)) {
820 argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *));
821 }
822
823 if (*p == '\'' || *p == '"') {
824 sep = *(p++);
825 }
826 if (*p == '\\' && (p[1] == '<' || p[1] == '\'' || p[1] == '"')) {
827 p++;
828 }
829 while (*p && *p != sep) {
830 if (*p == '\\' && (p[1] == sep || p[1] == '\\' || (p[1] == '#' && sep == ' '))) {
831 p++;
832 }
833 *(q++) = *(p++);
834 }
835 if (!*p && sep != ' ') {
836 phpdbg_error("Invalid run command, unterminated escape sequence");
837free_cmd:
838 efree(buf);
839 for (i = 0; i < argc; i++) {
840 efree(argv[i]);
841 }
842 efree(argv);
843 end[1] = last_byte;
844 return SUCCESS;
845 }
846
847 *(q++) = 0;
848 argv[++argc] = erealloc(buf, q - buf);
849
850 if (*p) {
851 do p++; while (*p == ' ');
852 }
853 }
854 end[1] = last_byte;
855
856 argv[0] = SG(request_info).argv[0];
857 for (i = SG(request_info).argc; --i;) {
858 efree(SG(request_info).argv[i]);
859 }
860 efree(SG(request_info).argv);
861 SG(request_info).argv = erealloc(argv, ++argc * sizeof(char *));
862 SG(request_info).argc = argc;
863
864 php_build_argv(NULL, &PG(http_globals)[TRACK_VARS_SERVER]);
865 }
866
867 /* clean up from last execution */
869 zend_hash_clean(ex->symbol_table);
870 } else {
872 }
874
875 /* clean seek state */
878
879 /* reset hit counters */
881
882 zend_try {
887 } zend_catch {
889
891 restore = 0;
892 } else {
893 zend_bailout();
894 }
895 } zend_end_try();
896
897 if (restore) {
899 zend_try {
902 } zend_catch {
904
906 zend_bailout();
907 }
908 } zend_end_try();
909
911 phpdbg_handle_exception();
912 }
913 }
914
916
917 phpdbg_clean(1, 0);
918 } else {
919 phpdbg_error("Nothing to execute!");
920 }
921
922out:
923 PHPDBG_FRAME(num) = 0;
924 return SUCCESS;
925} /* }}} */
926
927int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv) /* {{{ */ {
928 phpdbg_notice("Printing variable %.*s", (int) len, name);
929
931
932 phpdbg_out("\n");
933
934 efree(name);
935 efree(keyname);
936
937 return SUCCESS;
938}
939/* }}} */
940
941PHPDBG_COMMAND(ev) /* {{{ */
942{
943 bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING) == PHPDBG_IS_STEPPING);
945
949
951
952 original_stack->top = EG(vm_stack_top);
953
956 phpdbg_parse_variable(param->str, param->len, &EG(symbol_table), 0, phpdbg_output_ev_variable, 0);
958 phpdbg_error("Could not fetch data, invalid data source");
960
962 return SUCCESS;
963 }
964
968
969 /* disable stepping while eval() in progress */
972 if (zend_eval_stringl(param->str, param->len, &retval, "eval()'d code") == SUCCESS) {
973 if (EG(exception)) {
974 ex = EG(exception);
976 } else {
978 phpdbg_out("\n");
980 }
981 }
982 } zend_catch {
984 if (ex) {
986 }
987 EG(current_execute_data) = original_execute_data;
988 EG(vm_stack_top) = original_stack->top;
989 EG(vm_stack_end) = original_stack->end;
990 EG(vm_stack) = original_stack;
991 EG(exit_status) = 0;
992 } zend_end_try();
993
995
996 /* switch stepping back on */
997 if (stepping && !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) {
999 }
1000
1001 CG(unclean_shutdown) = 0;
1002
1004
1005 return SUCCESS;
1006} /* }}} */
1007
1008PHPDBG_COMMAND(back) /* {{{ */
1009{
1010 if (!PHPDBG_G(in_execution)) {
1011 phpdbg_error("Not executing!");
1012 return SUCCESS;
1013 }
1014
1015 if (!param) {
1017 } else {
1018 phpdbg_dump_backtrace(param->num);
1019 }
1020
1021 return SUCCESS;
1022} /* }}} */
1023
1024PHPDBG_COMMAND(generator) /* {{{ */
1025{
1026 int i;
1027
1029 phpdbg_error("Not executing!");
1030 return SUCCESS;
1031 }
1032
1033 if (param) {
1034 i = param->num;
1035 zend_object **obj = EG(objects_store).object_buckets + i;
1036 if (i < EG(objects_store).top && *obj && IS_OBJ_VALID(*obj) && (*obj)->ce == zend_ce_generator) {
1037 zend_generator *gen = (zend_generator *) *obj;
1038 if (gen->execute_data) {
1039 if (zend_generator_get_current(gen)->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) {
1040 phpdbg_error("Generator currently running");
1041 } else {
1043 }
1044 } else {
1045 phpdbg_error("Generator already closed");
1046 }
1047 } else {
1048 phpdbg_error("Invalid object handle");
1049 }
1050 } else {
1051 for (i = 0; i < EG(objects_store).top; i++) {
1052 zend_object *obj = EG(objects_store).object_buckets[i];
1053 if (obj && IS_OBJ_VALID(obj) && obj->ce == zend_ce_generator) {
1054 zend_generator *gen = (zend_generator *) obj, *current = zend_generator_get_current(gen);
1055 if (gen->execute_data) {
1057 phpdbg_out("#%d: %.*s", i, (int) ZSTR_LEN(s), ZSTR_VAL(s));
1058 zend_string_release(s);
1059 if (gen != current) {
1060 if (gen->node.parent != current) {
1061 phpdbg_out(" with direct parent #%d and", gen->node.parent->std.handle);
1062 }
1063 phpdbg_out(" executing #%d currently", current->std.handle);
1064 }
1065 phpdbg_out("\n");
1066 }
1067 }
1068 }
1069 }
1070
1071 return SUCCESS;
1072} /* }}} */
1073
1074PHPDBG_COMMAND(print) /* {{{ */
1075{
1076 if (!param || param->type == EMPTY_PARAM) {
1077 return phpdbg_do_print_stack(param);
1078 } else switch (param->type) {
1079 case STR_PARAM:
1080 return phpdbg_do_print_func(param);
1081 case METHOD_PARAM:
1082 return phpdbg_do_print_method(param);
1083 default:
1084 phpdbg_error("Invalid arguments to print, expected nothing, function name or method name");
1085 return SUCCESS;
1086 }
1087} /* }}} */
1088
1089PHPDBG_COMMAND(info) /* {{{ */
1090{
1091 phpdbg_out("Execution Context Information\n\n");
1092#ifdef HAVE_PHPDBG_READLINE
1093# ifdef HAVE_LIBREADLINE
1094 phpdbg_writeln( "Readline yes");
1095# else
1096 phpdbg_writeln("Readline no");
1097# endif
1098# ifdef HAVE_LIBEDIT
1099 phpdbg_writeln("Libedit yes");
1100# else
1101 phpdbg_writeln("Libedit no");
1102# endif
1103#else
1104 phpdbg_writeln("Readline unavailable");
1105#endif
1106
1107 phpdbg_writeln("Exec %s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
1108 phpdbg_writeln("Compiled %s", PHPDBG_G(ops) ? "yes" : "no");
1109 phpdbg_writeln("Stepping %s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
1110 phpdbg_writeln("Quietness %s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off");
1111
1112 if (PHPDBG_G(ops)) {
1113 phpdbg_writeln("Opcodes %d", PHPDBG_G(ops)->last);
1114 phpdbg_writeln("Variables %d", PHPDBG_G(ops)->last_var ? PHPDBG_G(ops)->last_var - 1 : 0);
1115 }
1116
1117 phpdbg_writeln("Executing %s", PHPDBG_G(in_execution) ? "yes" : "no");
1118 if (PHPDBG_G(in_execution)) {
1119 phpdbg_writeln("VM Return %d", PHPDBG_G(vmret));
1120 }
1121
1122 phpdbg_writeln("Classes %d", zend_hash_num_elements(EG(class_table)));
1123 phpdbg_writeln("Functions %d", zend_hash_num_elements(EG(function_table)));
1124 phpdbg_writeln("Constants %d", zend_hash_num_elements(EG(zend_constants)));
1125 phpdbg_writeln("Included %d", zend_hash_num_elements(&EG(included_files)));
1126
1127 return SUCCESS;
1128} /* }}} */
1129
1130PHPDBG_COMMAND(set) /* {{{ */
1131{
1132 phpdbg_error("No set command selected!");
1133
1134 return SUCCESS;
1135} /* }}} */
1136
1137PHPDBG_COMMAND(break) /* {{{ */
1138{
1139 if (!param) {
1140 if (PHPDBG_G(exec)) {
1145 } else {
1146 phpdbg_error("Execution context not set!");
1147 }
1148 } else switch (param->type) {
1149 case ADDR_PARAM:
1150 phpdbg_set_breakpoint_opline(param->addr);
1151 break;
1152 case NUMERIC_PARAM:
1153 if (PHPDBG_G(exec)) {
1155 } else {
1156 phpdbg_error("Execution context not set!");
1157 }
1158 break;
1159 case METHOD_PARAM:
1160 phpdbg_set_breakpoint_method(param->method.class, param->method.name);
1161 break;
1163 phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num);
1164 break;
1166 phpdbg_set_breakpoint_function_opline(param->str, param->num);
1167 break;
1168 case FILE_PARAM:
1169 phpdbg_set_breakpoint_file(param->file.name, 0, param->file.line);
1170 break;
1171 case NUMERIC_FILE_PARAM:
1172 phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line);
1173 break;
1174 case COND_PARAM:
1175 phpdbg_set_breakpoint_expression(param->str, param->len);
1176 break;
1177 case STR_PARAM:
1178 phpdbg_set_breakpoint_symbol(param->str, param->len);
1179 break;
1180 case OP_PARAM:
1181 phpdbg_set_breakpoint_opcode(param->str, param->len);
1182 break;
1183
1185 }
1186
1187 return SUCCESS;
1188} /* }}} */
1189
1190PHPDBG_COMMAND(sh) /* {{{ */
1191{
1192 FILE *fd = NULL;
1193 if ((fd=VCWD_POPEN((char*)param->str, "w"))) {
1194 /* TODO: do something perhaps ?? do we want input ?? */
1195 pclose(fd);
1196 } else {
1197 phpdbg_error("Failed to execute %s", param->str);
1198 }
1199
1200 return SUCCESS;
1201} /* }}} */
1202
1203static int add_module_info(zend_module_entry *module) /* {{{ */ {
1204 phpdbg_write("%s\n", module->name);
1205 return 0;
1206}
1207/* }}} */
1208
1209static void add_zendext_info(zend_extension *ext) /* {{{ */ {
1210 phpdbg_write("%s\n", ext->name);
1211}
1212/* }}} */
1213
1214#ifdef HAVE_LIBDL
1215PHPDBG_API const char *phpdbg_load_module_or_extension(char **path, const char **name) /* {{{ */ {
1217 char *extension_dir;
1218
1219 extension_dir = INI_STR("extension_dir");
1220
1221 if (strchr(*path, '/') != NULL || strchr(*path, DEFAULT_SLASH) != NULL) {
1222 /* path is fine */
1223 } else if (extension_dir && extension_dir[0]) {
1224 char *libpath;
1225 int extension_dir_len = strlen(extension_dir);
1226 if (IS_SLASH(extension_dir[extension_dir_len-1])) {
1227 spprintf(&libpath, 0, "%s%s", extension_dir, *path); /* SAFE */
1228 } else {
1229 spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, *path); /* SAFE */
1230 }
1231 efree(*path);
1232 *path = libpath;
1233 } else {
1234 phpdbg_error("Not a full path given or extension_dir ini setting is not set");
1235
1236 return NULL;
1237 }
1238
1239 handle = DL_LOAD(*path);
1240
1241 if (!handle) {
1242#ifdef PHP_WIN32
1243 char *err = GET_DL_ERROR();
1244 if (err && err[0]) {
1245 phpdbg_error("%s", err);
1247 } else {
1248 phpdbg_error("Unknown reason");
1249 }
1250#else
1251 phpdbg_error("%s", GET_DL_ERROR());
1252#endif
1253 return NULL;
1254 }
1255
1256#if ZEND_EXTENSIONS_SUPPORT
1257 do {
1258 zend_extension *new_extension;
1259
1260 const zend_extension_version_info *extension_version_info = (const zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
1261 if (!extension_version_info) {
1262 extension_version_info = (const zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "_extension_version_info");
1263 }
1264 new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
1265 if (!new_extension) {
1266 new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "_zend_extension_entry");
1267 }
1268 if (!extension_version_info || !new_extension) {
1269 break;
1270 }
1271 if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
1272 phpdbg_error("%s requires Zend Engine API version %d, which does not match the installed Zend Engine API version %d", new_extension->name, extension_version_info->zend_extension_api_no, ZEND_EXTENSION_API_NO);
1273
1274 goto quit;
1275 } else if (strcmp(ZEND_EXTENSION_BUILD_ID, extension_version_info->build_id) && (!new_extension->build_id_check || new_extension->build_id_check(ZEND_EXTENSION_BUILD_ID) != SUCCESS)) {
1276 phpdbg_error("%s was built with configuration %s, whereas running engine is %s", new_extension->name, extension_version_info->build_id, ZEND_EXTENSION_BUILD_ID);
1277
1278 goto quit;
1279 }
1280
1281 *name = new_extension->name;
1282
1283 zend_register_extension(new_extension, handle);
1284
1285 if (new_extension->startup) {
1286 if (new_extension->startup(new_extension) != SUCCESS) {
1287 phpdbg_error("Unable to startup Zend extension %s", new_extension->name);
1288
1289 goto quit;
1290 }
1291 zend_append_version_info(new_extension);
1292 }
1293
1294 return "Zend extension";
1295 } while (0);
1296#endif
1297
1298 do {
1299 zend_module_entry *module_entry;
1300 zend_module_entry *(*get_module)(void);
1301
1302 get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module");
1303 if (!get_module) {
1304 get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module");
1305 }
1306
1307 if (!get_module) {
1308 break;
1309 }
1310
1311 module_entry = get_module();
1312 *name = module_entry->name;
1313
1314 if (strcmp(ZEND_EXTENSION_BUILD_ID, module_entry->build_id)) {
1315 phpdbg_error("%s was built with configuration %s, whereas running engine is %s", module_entry->name, module_entry->build_id, ZEND_EXTENSION_BUILD_ID);
1316
1317 goto quit;
1318 }
1319
1320 if ((module_entry = zend_register_module_ex(module_entry, MODULE_PERSISTENT)) == NULL) {
1321 phpdbg_error("Unable to register module %s", *name);
1322
1323 goto quit;
1324 }
1325
1326 module_entry->handle = handle;
1327
1328 if (zend_startup_module_ex(module_entry) == FAILURE) {
1329 phpdbg_error("Unable to startup module %s", module_entry->name);
1330
1331 goto quit;
1332 }
1333
1334 if (module_entry->request_startup_func) {
1335 if (module_entry->request_startup_func(MODULE_PERSISTENT, module_entry->module_number) == FAILURE) {
1336 phpdbg_error("Unable to initialize module %s", module_entry->name);
1337
1338 goto quit;
1339 }
1340 }
1341
1342 return "module";
1343 } while (0);
1344
1345 phpdbg_error("This shared object is nor a Zend extension nor a module");
1346
1347quit:
1348 DL_UNLOAD(handle);
1349 return NULL;
1350}
1351/* }}} */
1352#endif
1353
1354PHPDBG_COMMAND(dl) /* {{{ */
1355{
1356 const char *type, *name;
1357 char *path;
1358
1359 if (!param || param->type == EMPTY_PARAM) {
1360 phpdbg_notice("Zend extensions");
1362 phpdbg_out("\n");
1363 phpdbg_notice("Modules");
1364 zend_hash_apply(&module_registry, (apply_func_t) add_module_info);
1365 } else switch (param->type) {
1366 case STR_PARAM:
1367#ifdef HAVE_LIBDL
1368 path = estrndup(param->str, param->len);
1369
1371 if ((type = phpdbg_load_module_or_extension(&path, &name)) == NULL) {
1372 phpdbg_error("Could not load %s, not found or invalid zend extension / module: %s", path, PHPDBG_G(err_buf).msg);
1373 } else {
1374 phpdbg_notice("Successfully loaded the %s %s at path %s", type, name, path);
1375 }
1378 efree(path);
1379#else
1380 phpdbg_error("Cannot dynamically load %.*s - dynamic modules are not supported", (int) param->len, param->str);
1381#endif
1382 break;
1383
1385 }
1386
1387 return SUCCESS;
1388} /* }}} */
1389
1390PHPDBG_COMMAND(source) /* {{{ */
1391{
1392 zend_stat_t sb = {0};
1393
1394 if (VCWD_STAT(param->str, &sb) != -1) {
1395 phpdbg_try_file_init(param->str, param->len, 0);
1396 } else {
1397 phpdbg_error("Failed to stat %s, file does not exist", param->str);
1398 }
1399
1400 return SUCCESS;
1401} /* }}} */
1402
1403PHPDBG_COMMAND(export) /* {{{ */
1404{
1405 FILE *handle = VCWD_FOPEN(param->str, "w+");
1406
1407 if (handle) {
1409 fclose(handle);
1410 } else {
1411 phpdbg_error("Failed to open or create %s, check path and permissions", param->str);
1412 }
1413
1414 return SUCCESS;
1415} /* }}} */
1416
1417PHPDBG_COMMAND(register) /* {{{ */
1418{
1420 char *lcname = zend_str_tolower_dup(param->str, param->len);
1421 size_t lcname_len = param->len;
1422
1423 if (!zend_hash_str_exists(&PHPDBG_G(registered), lcname, lcname_len)) {
1424 if ((function = zend_hash_str_find_ptr(EG(function_table), lcname, lcname_len))) {
1425 zend_hash_str_update_ptr(&PHPDBG_G(registered), lcname, lcname_len, function);
1426
1427 phpdbg_notice("Registered %s", lcname);
1428 } else {
1429 phpdbg_error("The requested function (%s) could not be found", param->str);
1430 }
1431 } else {
1432 phpdbg_error("The requested name (%s) is already in use", lcname);
1433 }
1434
1435 efree(lcname);
1436 return SUCCESS;
1437} /* }}} */
1438
1439PHPDBG_COMMAND(quit) /* {{{ */
1440{
1443
1444 return SUCCESS;
1445} /* }}} */
1446
1447PHPDBG_COMMAND(clean) /* {{{ */
1448{
1449 if (PHPDBG_G(in_execution)) {
1450 if (phpdbg_ask_user_permission("Do you really want to clean your current environment?") == FAILURE) {
1451 return SUCCESS;
1452 }
1453 }
1454
1455 phpdbg_out("Cleaning Execution Environment\n");
1456
1457 phpdbg_writeln("Classes %d", zend_hash_num_elements(EG(class_table)));
1458 phpdbg_writeln("Functions %d", zend_hash_num_elements(EG(function_table)));
1459 phpdbg_writeln("Constants %d", zend_hash_num_elements(EG(zend_constants)));
1460 phpdbg_writeln("Includes %d", zend_hash_num_elements(&EG(included_files)));
1461
1462 phpdbg_clean(1, 0);
1463
1464 return SUCCESS;
1465} /* }}} */
1466
1467PHPDBG_COMMAND(clear) /* {{{ */
1468{
1469 phpdbg_out("Clearing Breakpoints\n");
1470
1471 phpdbg_writeln("File %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]));
1472 phpdbg_writeln("Functions %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]));
1473 phpdbg_writeln("Methods %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]));
1474 phpdbg_writeln("Oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]));
1475 phpdbg_writeln("File oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]));
1476 phpdbg_writeln("Function oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]));
1477 phpdbg_writeln("Method oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]));
1478 phpdbg_writeln("Conditionals %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]));
1479
1481
1482 return SUCCESS;
1483} /* }}} */
1484
1485PHPDBG_COMMAND(list) /* {{{ */
1486{
1487 if (!param) {
1489 } else switch (param->type) {
1490 case NUMERIC_PARAM:
1492
1493 case FILE_PARAM:
1495
1496 case STR_PARAM:
1497 phpdbg_list_function_byname(param->str, param->len);
1498 break;
1499
1500 case METHOD_PARAM:
1502
1504 }
1505
1506 return SUCCESS;
1507} /* }}} */
1508
1509PHPDBG_COMMAND(watch) /* {{{ */
1510{
1511 if (!param || param->type == EMPTY_PARAM) {
1513 } else switch (param->type) {
1514 case STR_PARAM:
1515 phpdbg_create_var_watchpoint(param->str, param->len);
1516 break;
1517
1519 }
1520
1521 return SUCCESS;
1522} /* }}} */
1523
1524int phpdbg_interactive(bool allow_async_unsafe, char *input) /* {{{ */
1525{
1526 int ret = SUCCESS;
1527 phpdbg_param_t stack;
1528
1530
1531 while (ret == SUCCESS || ret == FAILURE) {
1533 zend_bailout();
1534 }
1535
1536 if (!input && !(input = phpdbg_read_input(NULL))) {
1537 break;
1538 }
1539
1540
1542
1543 if (phpdbg_do_parse(&stack, input) <= 0) {
1545
1546 zend_try {
1547 ret = phpdbg_stack_execute(&stack, allow_async_unsafe);
1548 } zend_catch {
1549 phpdbg_stack_free(&stack);
1550 phpdbg_destroy_input(&input);
1551 /* TODO: should use proper unwinding instead of bailing out */
1552 zend_bailout();
1553 } zend_end_try();
1554
1555 switch (ret) {
1556 case FAILURE:
1557 if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
1558 if (!allow_async_unsafe || phpdbg_call_register(&stack) == FAILURE) {
1559 if (PHPDBG_G(err_buf).active) {
1561 }
1562 }
1563 }
1564 break;
1565
1566 case PHPDBG_LEAVE:
1567 case PHPDBG_FINISH:
1568 case PHPDBG_UNTIL:
1569 case PHPDBG_NEXT: {
1573 phpdbg_error("Not running");
1574 }
1575 break;
1576 }
1577 }
1578
1581 }
1582
1583 phpdbg_stack_free(&stack);
1584 phpdbg_destroy_input(&input);
1585 PHPDBG_G(req_id) = 0;
1586 input = NULL;
1587 }
1588
1589 if (input) {
1590 phpdbg_stack_free(&stack);
1591 phpdbg_destroy_input(&input);
1592 PHPDBG_G(req_id) = 0;
1593 }
1594
1595 if (PHPDBG_G(in_execution)) {
1597 }
1598
1600
1602
1603 return ret;
1604} /* }}} */
1605
1606static inline void list_code(void) {
1607 if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) {
1608 const char *file_char = zend_get_executed_filename();
1609 zend_string *file = zend_string_init(file_char, strlen(file_char), 0);
1611 efree(file);
1612 }
1613}
1614
1615/* code may behave weirdly if EG(exception) is set; thus backup it */
1616#define DO_INTERACTIVE(allow_async_unsafe) do { \
1617 if (exception) { \
1618 const zend_op *before_ex = EG(opline_before_exception); \
1619 const zend_op *backup_opline = NULL; \
1620 if (EG(current_execute_data) && EG(current_execute_data)->func && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) { \
1621 backup_opline = EG(current_execute_data)->opline; \
1622 } \
1623 GC_ADDREF(exception); \
1624 zend_clear_exception(); \
1625 list_code(); \
1626 switch (phpdbg_interactive(allow_async_unsafe, NULL)) { \
1627 case PHPDBG_LEAVE: \
1628 case PHPDBG_FINISH: \
1629 case PHPDBG_UNTIL: \
1630 case PHPDBG_NEXT: \
1631 if (backup_opline \
1632 && (backup_opline->opcode == ZEND_HANDLE_EXCEPTION || backup_opline->opcode == ZEND_CATCH)) { \
1633 EG(current_execute_data)->opline = backup_opline; \
1634 EG(exception) = exception; \
1635 } else { \
1636 zend_throw_exception_internal(exception); \
1637 } \
1638 EG(opline_before_exception) = before_ex; \
1639 } \
1640 } else { \
1641 list_code(); \
1642 phpdbg_interactive(allow_async_unsafe, NULL); \
1643 } \
1644 goto next; \
1645} while (0)
1646
1648{
1649 bool original_in_execution = PHPDBG_G(in_execution);
1650
1652 zend_bailout();
1653 }
1654
1656
1657#ifdef ZEND_CHECK_STACK_LIMIT
1658 if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) {
1660 /* No opline was executed before exception */
1661 EG(opline_before_exception) = NULL;
1662 /* Fall through to handle exception below. */
1663 }
1664#endif /* ZEND_CHECK_STACK_LIMIT */
1665
1666 while (1) {
1668
1670 /* resolve nth opline breakpoints */
1672 }
1673
1674#ifdef ZEND_WIN32
1675 if (zend_atomic_bool_load_ex(&EG(timed_out))) {
1676 zend_timeout();
1677 }
1678#endif
1679
1681 /* Restore bailout based exit. */
1682 zend_bailout();
1683 }
1684
1687 goto next;
1688 }
1689
1690 /* check for uncaught exceptions */
1693
1694 do {
1695 prev_ex = zend_generator_check_placeholder_frame(prev_ex);
1696 /* assuming that no internal functions will silently swallow exceptions ... */
1697 if (!prev_ex->func || !ZEND_USER_CODE(prev_ex->func->common.type)) {
1698 continue;
1699 }
1700
1701 if (phpdbg_check_caught_ex(prev_ex, exception)) {
1702 goto ex_is_caught;
1703 }
1704 } while ((prev_ex = prev_ex->prev_execute_data));
1705
1707
1708 zval rv;
1709 zend_string *file = zval_get_string(zend_read_property_ex(zend_get_exception_base(exception), exception, ZSTR_KNOWN(ZEND_STR_FILE), /* silent */ true, &rv));
1710 zend_long line = zval_get_long(zend_read_property_ex(zend_get_exception_base(exception), exception, ZSTR_KNOWN(ZEND_STR_LINE), /* silent */ true, &rv));
1711 zend_string *msg = zval_get_string(zend_read_property_ex(zend_get_exception_base(exception), exception, ZSTR_KNOWN(ZEND_STR_MESSAGE), /* silent */ true, &rv));
1712
1713 phpdbg_error("Uncaught %s in %s on line " ZEND_LONG_FMT ": %.*s",
1714 ZSTR_VAL(exception->ce->name), ZSTR_VAL(file), line,
1715 ZSTR_LEN(msg) < 80 ? (int) ZSTR_LEN(msg) : 80, ZSTR_VAL(msg));
1716 zend_string_release(msg);
1717 zend_string_release(file);
1718
1719 DO_INTERACTIVE(1);
1720 }
1721ex_is_caught:
1722
1723 /* allow conditional breakpoints and initialization to access the vm uninterrupted */
1725 /* skip possible breakpoints */
1726 goto next;
1727 }
1728
1729 /* not while in conditionals */
1731
1732 /* perform seek operation */
1734 /* current address */
1735 zend_ulong address = (zend_ulong) execute_data->opline;
1736
1737 if (PHPDBG_G(seek_ex) != execute_data) {
1739 goto stepping;
1740 }
1741 goto next;
1742 }
1743
1744#define INDEX_EXISTS_CHECK (zend_hash_index_exists(&PHPDBG_G(seek), address) || (exception && phpdbg_check_caught_ex(execute_data, exception) == 0))
1745
1746 /* run to next line */
1748 if (INDEX_EXISTS_CHECK) {
1751 } else {
1752 /* skip possible breakpoints */
1753 goto next;
1754 }
1755 }
1756
1757 /* run to finish */
1759 if (INDEX_EXISTS_CHECK) {
1762 }
1763 /* skip possible breakpoints */
1764 goto next;
1765 }
1766
1767 /* break for leave */
1769 if (INDEX_EXISTS_CHECK) {
1772 phpdbg_notice("Breaking for leave at %s:%u",
1775 );
1776 DO_INTERACTIVE(1);
1777 } else {
1778 /* skip possible breakpoints */
1779 goto next;
1780 }
1781 }
1782 }
1783
1785stepping:
1787 DO_INTERACTIVE(1);
1788 }
1789
1790 /* check if some watchpoint was hit */
1791 {
1793 DO_INTERACTIVE(1);
1794 }
1795 }
1796
1797 /* search for breakpoints */
1798 {
1799 phpdbg_breakbase_t *brake;
1800
1803 && (brake->type != PHPDBG_BREAK_FILE || execute_data->opline->lineno != PHPDBG_G(last_line))) {
1804 phpdbg_hit_breakpoint(brake, 1);
1805 DO_INTERACTIVE(1);
1806 }
1807 }
1808
1811
1812 phpdbg_out("\n");
1813 phpdbg_notice("Program received signal SIGINT");
1814 DO_INTERACTIVE(1);
1815 }
1816
1817next:
1818
1819 PHPDBG_G(last_line) = execute_data->opline->lineno;
1820
1821 /* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */
1822 if ((execute_data->opline->opcode == ZEND_DO_FCALL ||
1823 execute_data->opline->opcode == ZEND_DO_UCALL ||
1824 execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME) &&
1825 execute_data->call->func->type == ZEND_USER_FUNCTION) {
1827 }
1830
1831 if (PHPDBG_G(vmret) != 0) {
1832 if (PHPDBG_G(vmret) < 0) {
1833 PHPDBG_G(in_execution) = original_in_execution;
1834 return;
1835 } else {
1836 execute_data = EG(current_execute_data);
1837 }
1838 }
1839 }
1840 zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
1841} /* }}} */
1842
1843/* only if *not* interactive and while executing */
1844void phpdbg_force_interruption(void) /* {{{ */ {
1846 zend_execute_data *data = EG(current_execute_data); /* should be always readable if not NULL */
1847
1849
1850 if (data) {
1851 if (data->func) {
1852 if (ZEND_USER_CODE(data->func->type)) {
1853 phpdbg_notice("Current opline: %p (op #%u) in %s:%u",
1854 data->opline,
1855 (uint32_t) (data->opline - data->func->op_array.opcodes),
1856 data->func->op_array.filename->val,
1857 data->opline->lineno);
1858 } else if (data->func->internal_function.function_name) {
1859 phpdbg_notice("Current opline: in internal function %s",
1860 data->func->internal_function.function_name->val);
1861 } else {
1862 phpdbg_notice("Current opline: executing internal code");
1863 }
1864 } else {
1865 phpdbg_notice("Current opline: %p (op_array information unavailable)",
1866 data->opline);
1867 }
1868 } else {
1869 phpdbg_notice("No information available about executing context");
1870 }
1871
1872 DO_INTERACTIVE(0);
1873
1874next:
1876
1878 zend_bailout();
1879 }
1880}
1881/* }}} */
#define SG(v)
Definition SAPI.h:160
size_t len
Definition apprentice.c:174
file_private const char ext[]
bool exception
Definition assert.c:30
getenv(?string $name=null, bool $local_only=false)
file(string $filename, int $flags=0, $context=null)
strtok(string $string, ?string $token=null)
pclose($handle)
fclose($stream)
fopen(string $filename, string $mode, bool $use_include_path=false, $context=null)
fgets($stream, ?int $length=null)
strchr(string $haystack, string $needle, bool $before_needle=false)
char s[4]
Definition cdf.c:77
Definition test.php:8
print
dl(string $extension_filename)
Definition dl.stub.php:3
zend_ffi_type * type
Definition ffi.c:3812
zval * zv
Definition ffi.c:3975
DL_HANDLE handle
Definition ffi.c:3028
zend_string * res
Definition ffi.c:4692
memcpy(ptr1, ptr2, size)
char * err
Definition ffi.c:3029
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
const php_stream_filter_ops * ops
Definition filters.c:1899
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
PHPAPI zend_result php_stream_open_for_zend_ex(zend_file_handle *handle, int mode)
Definition main.c:1620
const PHP_CONFIG_FILE_SCAN_DIR
const PHP_CONFIG_FILE_PATH
#define next(ls)
Definition minilua.c:2661
#define memmove(a, b, c)
int line
Definition php_ffi.h:54
unsigned const char * end
Definition php_ffi.h:51
#define TRACK_VARS_SERVER
Definition php_globals.h:43
#define PG(v)
Definition php_globals.h:31
php_output_handler * active
Definition php_output.h:140
char * extension_dir
Definition php_sqlite3.h:26
#define STREAM_OPEN_FOR_INCLUDE
#define USE_PATH
PHPAPI void php_build_argv(const char *s, zval *track_vars_array)
void phpdbg_register_file_handles(void)
Definition phpdbg.c:882
int phpdbg_startup_run
Definition phpdbg.c:46
HashTable seek
Definition phpdbg.h:233
HashTable bp[PHPDBG_BREAK_TABLES]
Definition phpdbg.h:231
#define PHPDBG_IN_UNTIL
Definition phpdbg.h:152
struct @010122165316201240231237266310115370127155020222 err_buf
struct @234323133100145062121301312242002332057146367313 io[PHPDBG_IO_FDS]
int phpdbg_do_parse(phpdbg_param_t *stack, char *input)
#define PHPDBG_STDIN
Definition phpdbg.h:189
#define PHPDBG_IS_STEPONEVAL
Definition phpdbg.h:157
FILE * stdin_file
Definition phpdbg.h:299
char * msg
Definition phpdbg.h:289
#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_API
Definition phpdbg.h:27
zend_ulong req_id
Definition phpdbg.h:292
#define PHPDBG_IS_INITIALIZING
Definition phpdbg.h:158
#define phpdbg_try_access
Definition phpdbg.h:194
uint32_t last_line
Definition phpdbg.h:237
zend_object * handled_exception
Definition phpdbg.h:235
#define phpdbg_catch_access
Definition phpdbg.h:201
#define PHPDBG_BP_MASK
Definition phpdbg.h:170
#define PHPDBG_IS_QUIET
Definition phpdbg.h:146
#define PHPDBG_STEP_OPCODE
Definition phpdbg.h:145
#define PHPDBG_LEAVE
Definition phpdbg.h:119
char input_buffer[PHPDBG_MAX_CMD]
Definition phpdbg.h:302
#define PHPDBG_IS_STEPPING
Definition phpdbg.h:144
int fd
Definition phpdbg.h:282
#define PHPDBG_IN_EVAL
Definition phpdbg.h:142
zend_execute_data * seek_ex
Definition phpdbg.h:234
#define PHPDBG_BP_RESOLVE_MASK
Definition phpdbg.h:169
#define PHPDBG_INIT_FILENAME
Definition phpdbg.h:95
bool in_execution
Definition phpdbg.h:269
size_t exec_len
Definition phpdbg.h:264
#define phpdbg_end_try_access()
Definition phpdbg.h:204
#define PHPDBG_IN_SIGNAL_HANDLER
Definition phpdbg.h:164
HashTable file_sources
Definition phpdbg.h:275
zend_ulong lines
Definition phpdbg.h:311
#define PHPDBG_IN_COND_BP
Definition phpdbg.h:141
HashTable registered
Definition phpdbg.h:232
bool unclean_eval
Definition phpdbg.h:270
#define PHPDBG_FINISH
Definition phpdbg.h:118
#define PHPDBG_IN_FINISH
Definition phpdbg.h:153
#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
int vmret
Definition phpdbg.h:268
#define PHPDBG_IS_QUITTING
Definition phpdbg.h:147
#define PHPDBG_IN_LEAVE
Definition phpdbg.h:154
#define PHPDBG_IS_STOPPING
Definition phpdbg.h:171
#define PHPDBG_IS_CLEANING
Definition phpdbg.h:149
#define PHPDBG_SEEK_MASK
Definition phpdbg.h:168
phpdbg_frame_t frame
Definition phpdbg.h:236
char * cur_command
Definition phpdbg.h:239
PHPDBG_API phpdbg_breakbase_t * phpdbg_find_breakpoint(zend_execute_data *execute_data)
Definition phpdbg_bp.c:1142
PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline)
Definition phpdbg_bp.c:692
PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array)
Definition phpdbg_bp.c:536
PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline)
Definition phpdbg_bp.c:479
PHPDBG_API void phpdbg_clear_breakpoints(void)
Definition phpdbg_bp.c:1254
PHPDBG_API void phpdbg_hit_breakpoint(phpdbg_breakbase_t *brake, bool output)
Definition phpdbg_bp.c:1273
PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len)
Definition phpdbg_bp.c:784
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_export_breakpoints(FILE *handle)
Definition phpdbg_bp.c:109
PHPDBG_API void phpdbg_reset_breakpoints(void)
Definition phpdbg_bp.c:96
PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const char *method, zend_ulong opline)
Definition phpdbg_bp.c:639
PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_len)
Definition phpdbg_bp.c:902
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_file_opline(const char *file, zend_ulong opline)
Definition phpdbg_bp.c:738
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_METHOD
Definition phpdbg_bp.h:27
#define PHPDBG_BREAK_METHOD_OPLINE
Definition phpdbg_bp.h:31
#define PHPDBG_BREAK_FILE
Definition phpdbg_bp.h:23
struct _phpdbg_breakbase_t phpdbg_breakbase_t
const phpdbg_command_t phpdbg_break_commands[]
PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, bool allow_async_unsafe)
Definition phpdbg_cmd.c:720
PHPDBG_API char * phpdbg_read_input(const char *buffered)
Definition phpdbg_cmd.c:745
PHPDBG_API void phpdbg_destroy_input(char **input)
Definition phpdbg_cmd.c:811
PHPDBG_API int phpdbg_ask_user_permission(const char *question)
Definition phpdbg_cmd.c:816
PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack)
Definition phpdbg_cmd.c:377
struct _phpdbg_param phpdbg_param_t
Definition phpdbg_cmd.h:51
#define PHPDBG_COMMAND(name)
Definition phpdbg_cmd.h:167
@ NUMERIC_FILE_PARAM
Definition phpdbg_cmd.h:36
@ EMPTY_PARAM
Definition phpdbg_cmd.h:33
@ ADDR_PARAM
Definition phpdbg_cmd.h:34
@ OP_PARAM
Definition phpdbg_cmd.h:46
@ NUMERIC_METHOD_PARAM
Definition phpdbg_cmd.h:41
@ STACK_PARAM
Definition phpdbg_cmd.h:42
@ STR_PARAM
Definition phpdbg_cmd.h:38
@ COND_PARAM
Definition phpdbg_cmd.h:45
@ METHOD_PARAM
Definition phpdbg_cmd.h:37
@ FILE_PARAM
Definition phpdbg_cmd.h:35
@ NUMERIC_PARAM
Definition phpdbg_cmd.h:39
@ NUMERIC_FUNCTION_PARAM
Definition phpdbg_cmd.h:40
#define PHPDBG_END_COMMAND
Definition phpdbg_cmd.h:171
#define phpdbg_init_param(v, t)
Definition phpdbg_cmd.h:70
#define phpdbg_default_switch_case()
Definition phpdbg_cmd.h:176
#define PHPDBG_COMMAND_ARGS
Definition phpdbg_cmd.h:169
#define PHPDBG_MAX_CMD
Definition phpdbg_cmd.h:105
struct _phpdbg_command_t phpdbg_command_t
Definition phpdbg_cmd.h:88
#define PHPDBG_STRL(s)
Definition phpdbg_cmd.h:104
#define PHPDBG_COMMAND_D(name, tip, alias, children, args, flags)
Definition phpdbg_cmd.h:164
#define PHPDBG_FRAME(v)
Definition phpdbg_cmd.h:106
#define PHPDBG_ASYNC_SAFE
Definition phpdbg_cmd.h:84
void phpdbg_open_generator_frame(zend_generator *gen)
zend_string * phpdbg_compile_stackframe(zend_execute_data *ex)
void phpdbg_dump_backtrace(size_t num)
void phpdbg_switch_frame(int frame)
void phpdbg_restore_frame(void)
const phpdbg_command_t phpdbg_help_commands[]
Definition phpdbg_help.c:31
zend_constant * data
const phpdbg_command_t phpdbg_info_commands[]
Definition phpdbg_info.c:31
PHPDBG_API int phpdbg_mixed_read(int fd, char *ptr, int len, int tmo)
Definition phpdbg_io.c:73
void phpdbg_list_function_byname(const char *str, size_t len)
const phpdbg_command_t phpdbg_list_commands[]
Definition phpdbg_list.c:39
void phpdbg_list_file(zend_string *filename, uint32_t count, int offset, uint32_t highlight)
#define PHPDBG_LIST_HANDLER(name)
Definition phpdbg_list.h:26
PHPDBG_API void phpdbg_free_err_buf(void)
Definition phpdbg_out.c:159
PHPDBG_API void phpdbg_activate_err_buf(bool active)
Definition phpdbg_out.c:169
PHPDBG_API int phpdbg_output_err_buf(const char *strfmt,...)
Definition phpdbg_out.c:173
#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_notice(strfmt,...)
Definition phpdbg_out.h:44
#define phpdbg_debug(strfmt,...)
Definition phpdbg_out.h:59
#define phpdbg_writeln(strfmt,...)
Definition phpdbg_out.h:45
const phpdbg_command_t phpdbg_print_commands[]
void phpdbg_print_opline(zend_execute_data *execute_data, bool ignore_flags)
zend_string * lcname
void phpdbg_init(char *init_file, size_t init_file_len, bool use_default)
#define INDEX_EXISTS_CHECK
void phpdbg_string_init(char *buffer)
zend_object * ex
const phpdbg_command_t phpdbg_prompt_commands[]
int phpdbg_skip_line_helper(void)
PHPDBG_OUTPUT_BACKUP()
void phpdbg_try_file_init(char *init_file, size_t init_file_len, bool free_init)
int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv)
PHPDBG_OUTPUT_BACKUP_RESTORE()
int phpdbg_compile_stdin(zend_string *code)
zend_execute_data * original_execute_data
#define DO_INTERACTIVE(allow_async_unsafe)
void phpdbg_clean(bool full, bool resubmit)
int phpdbg_compile(void)
original_stack top
zend_vm_stack original_stack
void phpdbg_force_interruption(void)
void phpdbg_execute_ex(zend_execute_data *execute_data)
int phpdbg_interactive(bool allow_async_unsafe, char *input)
const phpdbg_command_t phpdbg_set_commands[]
Definition phpdbg_set.c:31
PHPDBG_API char * phpdbg_resolve_path(const char *path)
PHPDBG_API bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zend_object *exception)
PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, bool silent)
PHPDBG_API const char * phpdbg_current_file(void)
int phpdbg_print_changed_zvals(void)
int phpdbg_create_var_watchpoint(char *input, size_t len)
void phpdbg_list_watchpoints(void)
const phpdbg_command_t phpdbg_watch_commands[]
zval * current
Definition session.c:1024
zval rv
Definition session.c:1024
p
Definition session.c:1105
#define asprintf
Definition snprintf.h:111
#define strpprintf
Definition spprintf.h:30
#define spprintf
Definition spprintf.h:29
phpdbg_param_type type
Definition phpdbg_cmd.h:53
phpdbg_param_t * next
Definition phpdbg_cmd.h:66
zend_execute_data * prev_execute_data
zend_function * func
int(* build_id_check)(const char *build_id)
const char * name
int(* api_no_check)(int api_no)
startup_func_t startup
HashTable * named_params
Definition zend_API.h:56
uint32_t param_count
Definition zend_API.h:51
zend_object * object
Definition zend_API.h:50
zend_generator * parent
zend_generator_node node
zend_execute_data * execute_data
const char * name
int module_number
const char * build_id
void * handle
zend_result(* request_startup_func)(INIT_FUNC_ARGS)
zend_class_entry * ce
Definition zend_types.h:560
uint32_t handle
Definition zend_types.h:558
zend_op * opcodes
uint8_t opcode
uint32_t lineno
Definition file.h:177
const char * init_file
struct _zend_function::@236135173067030250234125302313220025134003177336 common
PHP_WINUTIL_API void php_win32_error_msg_free(char *msg)
Definition winutil.c:50
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format,...)
Definition zend.c:1703
ZEND_API void zend_print_zval_r(zval *expr, int indent)
Definition zend.c:625
ZEND_API void zend_append_version_info(const zend_extension *extension)
Definition zend.c:1284
#define zend_catch
Definition zend.h:277
#define zend_try
Definition zend.h:270
#define zend_end_try()
Definition zend.h:280
#define zend_bailout()
Definition zend.h:268
ZEND_API zval * zend_read_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv)
Definition zend_API.c:5187
ZEND_API zend_module_entry * zend_register_module_ex(zend_module_entry *module, int module_type)
Definition zend_API.c:2587
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
Definition zend_API.c:2195
ZEND_API HashTable module_registry
Definition zend_API.c:41
ZEND_API zend_result add_next_index_long(zval *arg, zend_long n)
Definition zend_API.c:2132
ZEND_API void zend_update_property_string(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value)
Definition zend_API.c:5066
ZEND_API zend_result zend_startup_module_ex(zend_module_entry *module)
Definition zend_API.c:2388
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
Definition zend_API.c:2186
struct _zend_fcall_info zend_fcall_info
#define ZEND_EXTERN_MODULE_GLOBALS(module_name)
Definition zend_API.h:270
ZEND_API zend_array * zend_rebuild_symbol_table(void)
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
ZEND_API zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
#define array_init(arg)
Definition zend_API.h:537
#define estrndup(s, length)
Definition zend_alloc.h:165
#define efree(ptr)
Definition zend_alloc.h:155
#define erealloc(ptr, size)
Definition zend_alloc.h:159
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
strcmp(string $string1, string $string2)
ZEND_API zend_op_array *(* zend_compile_file)(zend_file_handle *file_handle, int type)
ZEND_API zend_op_array *(* zend_compile_string)(zend_string *source_string, const char *filename, zend_compile_position position)
#define zend_try_exception_handler()
struct _zend_op zend_op
#define ZEND_USER_CODE(type)
ZEND_API void destroy_op_array(zend_op_array *op_array)
#define ZEND_USER_FUNCTION
#define ZEND_CALL_HAS_SYMBOL_TABLE
struct _zend_op_array zend_op_array
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle)
#define ZEND_CALL_INFO(call)
@ ZEND_COMPILE_POSITION_AFTER_OPEN_TAG
#define ZEND_INCLUDE
#define E_ERROR
Definition zend_errors.h:23
void zend_exception_restore(void)
ZEND_API bool zend_is_unwind_exit(const zend_object *ex)
ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *ex, int severity)
ZEND_API zend_class_entry * zend_get_exception_base(zend_object *object)
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 void zend_execute(zend_op_array *op_array, zval *return_value)
ZEND_API void execute_ex(zend_execute_data *execute_data)
ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_error(void)
ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void)
ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *retval_ptr, const char *string_name)
void zend_register_extension(zend_extension *new_extension, DL_HANDLE handle)
ZEND_API zend_llist zend_extensions
struct _zend_extension_version_info zend_extension_version_info
#define ZEND_EXTENSION_BUILD_ID
struct _zend_extension zend_extension
#define ZEND_EXTENSION_API_NO
union _zend_function zend_function
ZEND_API zend_execute_data * zend_generator_check_placeholder_frame(zend_execute_data *ptr)
ZEND_API zend_class_entry * zend_ce_generator
struct _zend_generator zend_generator
struct _zend_vm_stack * zend_vm_stack
#define CG(v)
#define EG(v)
ZEND_API void ZEND_FASTCALL zend_hash_apply(HashTable *ht, apply_func_t apply_func)
Definition zend_hash.c:2059
ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
Definition zend_hash.c:1869
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
Definition zend_hash.c:1808
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
Definition zend_hash.c:1534
int(* apply_func_t)(zval *pDest)
Definition zend_hash.h:150
#define INI_STR(name)
Definition zend_ini.h:195
struct _zend_file_handle zend_file_handle
ZEND_API void zend_llist_apply(zend_llist *l, llist_apply_func_t func)
Definition zend_llist.c:179
void(* llist_apply_func_t)(void *)
Definition zend_llist.h:35
#define ZEND_ULONG_FMT
Definition zend_long.h:88
int32_t zend_long
Definition zend_long.h:42
uint32_t zend_ulong
Definition zend_long.h:43
#define ZEND_LONG_FMT
Definition zend_long.h:87
struct _zend_string zend_string
struct _zend_module_entry zend_module_entry
#define MODULE_PERSISTENT
#define OBJ_RELEASE(obj)
#define IS_OBJ_VALID(o)
ZEND_API char *ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t length)
int last
#define ZEND_IGNORE_VALUE(x)
#define DL_HANDLE
#define ZEND_STRL(str)
#define UNEXPECTED(condition)
struct _zend_object zend_object
ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len)
ZEND_API void zend_stream_init_filename(zend_file_handle *handle, const char *filename)
Definition zend_stream.c:70
struct stat zend_stat_t
Definition zend_stream.h:94
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_KNOWN(idx)
#define ZSTR_EMPTY_ALLOC()
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
struct _zend_array HashTable
Definition zend_types.h:386
void(* dtor_func_t)(zval *pDest)
Definition zend_types.h:107
#define Z_STRVAL(zval)
Definition zend_types.h:974
@ FAILURE
Definition zend_types.h:61
#define Z_ARRVAL(zval)
Definition zend_types.h:986
struct _zend_execute_data zend_execute_data
Definition zend_types.h:91
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define IS_SLASH(c)
#define DEFAULT_SLASH
#define VCWD_FOPEN(path, mode)
#define VCWD_POPEN(command, type)
#define VCWD_CHDIR_FILE(path)
#define VCWD_STAT(path, buff)
#define S_IFLNK
ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data *ex)
zval retval
zend_generator * generator
zend_string * name
function(EX_VAR(opline->result.var))
execute_data
zval * ret
out($f, $s)
#define ZEND_YIELD
#define ZEND_RETURN
#define ZEND_DO_UCALL
#define ZEND_DO_FCALL
#define ZEND_YIELD_FROM
#define ZEND_GENERATOR_RETURN
#define ZEND_DO_FCALL_BY_NAME
#define ZEND_FAST_RET