xref: /PHP-7.2/sapi/phpdbg/phpdbg.h (revision 7af270eb)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Felipe Pena <felipe@php.net>                                |
16    | Authors: Joe Watkins <joe.watkins@live.co.uk>                        |
17    | Authors: Bob Weinand <bwoebi@php.net>                                |
18    +----------------------------------------------------------------------+
19 */
20 
21 #ifndef PHPDBG_H
22 #define PHPDBG_H
23 
24 #ifdef PHP_WIN32
25 # define PHPDBG_API __declspec(dllexport)
26 #elif defined(__GNUC__) && __GNUC__ >= 4
27 # define PHPDBG_API __attribute__ ((visibility("default")))
28 #else
29 # define PHPDBG_API
30 #endif
31 
32 #ifndef PHP_WIN32
33 #	include <stdint.h>
34 #	include <stddef.h>
35 #else
36 #	include "main/php_stdint.h"
37 #endif
38 #include "php.h"
39 #include "php_globals.h"
40 #include "php_variables.h"
41 #include "php_getopt.h"
42 #include "zend_builtin_functions.h"
43 #include "zend_extensions.h"
44 #include "zend_modules.h"
45 #include "zend_globals.h"
46 #include "zend_ini_scanner.h"
47 #include "zend_stream.h"
48 #include "zend_signal.h"
49 #if !defined(_WIN32) && !defined(ZEND_SIGNALS) && defined(HAVE_SIGNAL_H)
50 #	include <signal.h>
51 #elif defined(PHP_WIN32)
52 #	include "win32/signal.h"
53 #endif
54 #include "SAPI.h"
55 #include <fcntl.h>
56 #include <sys/types.h>
57 #if defined(_WIN32) && !defined(__MINGW32__)
58 #	include <windows.h>
59 #	include "config.w32.h"
60 #	undef  strcasecmp
61 #	undef  strncasecmp
62 #	define strcasecmp _stricmp
63 #	define strncasecmp _strnicmp
64 #else
65 #	include "php_config.h"
66 #endif
67 #ifndef O_BINARY
68 #	define O_BINARY 0
69 #endif
70 #include "php_main.h"
71 
72 #ifdef ZTS
73 # include "TSRM.h"
74 #endif
75 
76 #undef zend_hash_str_add
77 #ifdef PHP_WIN32
78 #define zend_hash_str_add(...) \
79 	_zend_hash_str_add(__VA_ARGS__ ZEND_FILE_LINE_CC)
80 #else
81 #define zend_hash_str_add_tmp(ht, key, len, pData) \
82 	_zend_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC)
83 #define zend_hash_str_add(...) zend_hash_str_add_tmp(__VA_ARGS__)
84 #endif
85 
86 #ifdef HAVE_PHPDBG_READLINE
87 # ifdef HAVE_LIBREADLINE
88 #	 include <readline/readline.h>
89 #	 include <readline/history.h>
90 # endif
91 # ifdef HAVE_LIBEDIT
92 #	 include <editline/readline.h>
93 # endif
94 #endif
95 
96 /* {{{ remote console headers */
97 #ifndef _WIN32
98 #	include <sys/socket.h>
99 #	include <sys/un.h>
100 #	include <sys/select.h>
101 #	include <sys/types.h>
102 #	include <netdb.h>
103 #endif /* }}} */
104 
105 /* {{{ strings */
106 #define PHPDBG_NAME "phpdbg"
107 #define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */
108 #define PHPDBG_ISSUES "http://bugs.php.net/report.php"
109 #define PHPDBG_VERSION "0.5.0"
110 #define PHPDBG_INIT_FILENAME ".phpdbginit"
111 #define PHPDBG_DEFAULT_PROMPT "prompt>"
112 /* }}} */
113 
114 /* Hey, apple. One shouldn't define *functions* from the standard C library as marcos. */
115 #ifdef memcpy
116 #define memcpy_tmp(...) memcpy(__VA_ARGS__)
117 #undef memcpy
118 #define memcpy(...) memcpy_tmp(__VA_ARGS__)
119 #endif
120 
121 #if !defined(PHPDBG_WEBDATA_TRANSFER_H) && !defined(PHPDBG_WEBHELPER_H)
122 
123 #ifdef ZTS
124 # define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v)
125 #else
126 # define PHPDBG_G(v) (phpdbg_globals.v)
127 #endif
128 
129 #include "phpdbg_sigsafe.h"
130 #include "phpdbg_out.h"
131 #include "phpdbg_lexer.h"
132 #include "phpdbg_cmd.h"
133 #include "phpdbg_utils.h"
134 #include "phpdbg_btree.h"
135 #include "phpdbg_watch.h"
136 #include "phpdbg_bp.h"
137 #include "phpdbg_opcode.h"
138 #ifdef PHP_WIN32
139 # include "phpdbg_sigio_win32.h"
140 #endif
141 
142 int phpdbg_do_parse(phpdbg_param_t *stack, char *input);
143 
144 #define PHPDBG_NEXT   2
145 #define PHPDBG_UNTIL  3
146 #define PHPDBG_FINISH 4
147 #define PHPDBG_LEAVE  5
148 
149 /*
150  BEGIN: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE
151 */
152 
153 /* {{{ flags */
154 #define PHPDBG_HAS_FILE_BP            (1ULL<<1)
155 #define PHPDBG_HAS_PENDING_FILE_BP    (1ULL<<2)
156 #define PHPDBG_HAS_SYM_BP             (1ULL<<3)
157 #define PHPDBG_HAS_OPLINE_BP          (1ULL<<4)
158 #define PHPDBG_HAS_METHOD_BP          (1ULL<<5)
159 #define PHPDBG_HAS_COND_BP            (1ULL<<6)
160 #define PHPDBG_HAS_OPCODE_BP          (1ULL<<7)
161 #define PHPDBG_HAS_FUNCTION_OPLINE_BP (1ULL<<8)
162 #define PHPDBG_HAS_METHOD_OPLINE_BP   (1ULL<<9)
163 #define PHPDBG_HAS_FILE_OPLINE_BP     (1ULL<<10) /* }}} */
164 
165 /*
166  END: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE
167 */
168 
169 #define PHPDBG_IN_COND_BP             (1ULL<<11)
170 #define PHPDBG_IN_EVAL                (1ULL<<12)
171 
172 #define PHPDBG_IS_STEPPING            (1ULL<<13)
173 #define PHPDBG_STEP_OPCODE            (1ULL<<14)
174 #define PHPDBG_IS_QUIET               (1ULL<<15)
175 #define PHPDBG_IS_QUITTING            (1ULL<<16)
176 #define PHPDBG_IS_COLOURED            (1ULL<<17)
177 #define PHPDBG_IS_CLEANING            (1ULL<<18)
178 #define PHPDBG_IS_RUNNING             (1ULL<<19)
179 
180 #define PHPDBG_IN_UNTIL               (1ULL<<20)
181 #define PHPDBG_IN_FINISH              (1ULL<<21)
182 #define PHPDBG_IN_LEAVE               (1ULL<<22)
183 
184 #define PHPDBG_IS_REGISTERED          (1ULL<<23)
185 #define PHPDBG_IS_STEPONEVAL          (1ULL<<24)
186 #define PHPDBG_IS_INITIALIZING        (1ULL<<25)
187 #define PHPDBG_IS_SIGNALED            (1ULL<<26)
188 #define PHPDBG_IS_INTERACTIVE         (1ULL<<27)
189 #define PHPDBG_PREVENT_INTERACTIVE    (1ULL<<28)
190 #define PHPDBG_IS_BP_ENABLED          (1ULL<<29)
191 #define PHPDBG_IS_REMOTE              (1ULL<<30)
192 #define PHPDBG_IS_DISCONNECTED        (1ULL<<31)
193 #define PHPDBG_WRITE_XML              (1ULL<<32)
194 
195 #define PHPDBG_SHOW_REFCOUNTS         (1ULL<<33)
196 
197 #define PHPDBG_IN_SIGNAL_HANDLER      (1ULL<<34)
198 
199 #define PHPDBG_DISCARD_OUTPUT         (1ULL<<35)
200 
201 #define PHPDBG_HAS_PAGINATION         (1ULL<<36)
202 
203 #define PHPDBG_SEEK_MASK              (PHPDBG_IN_UNTIL | PHPDBG_IN_FINISH | PHPDBG_IN_LEAVE)
204 #define PHPDBG_BP_RESOLVE_MASK	      (PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP)
205 #define PHPDBG_BP_MASK                (PHPDBG_HAS_FILE_BP | PHPDBG_HAS_SYM_BP | PHPDBG_HAS_METHOD_BP | PHPDBG_HAS_OPLINE_BP | PHPDBG_HAS_COND_BP | PHPDBG_HAS_OPCODE_BP | PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP)
206 #define PHPDBG_IS_STOPPING            (PHPDBG_IS_QUITTING | PHPDBG_IS_CLEANING)
207 
208 #define PHPDBG_PRESERVE_FLAGS_MASK    (PHPDBG_SHOW_REFCOUNTS | PHPDBG_IS_STEPONEVAL | PHPDBG_IS_BP_ENABLED | PHPDBG_STEP_OPCODE | PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_REMOTE | PHPDBG_WRITE_XML | PHPDBG_IS_DISCONNECTED | PHPDBG_HAS_PAGINATION)
209 
210 #ifndef _WIN32
211 #	define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_BP_ENABLED | PHPDBG_HAS_PAGINATION)
212 #else
213 #	define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_BP_ENABLED | PHPDBG_HAS_PAGINATION)
214 #endif /* }}} */
215 
216 /* {{{ output descriptors */
217 #define PHPDBG_STDIN 			0
218 #define PHPDBG_STDOUT			1
219 #define PHPDBG_STDERR			2
220 #define PHPDBG_IO_FDS 			3 /* }}} */
221 
222 #define phpdbg_try_access \
223 	{                                                            \
224 		JMP_BUF *__orig_bailout = PHPDBG_G(sigsegv_bailout); \
225 		JMP_BUF __bailout;                                   \
226                                                                      \
227 		PHPDBG_G(sigsegv_bailout) = &__bailout;              \
228 		if (SETJMP(__bailout) == 0) {
229 #define phpdbg_catch_access \
230 		} else {                                             \
231 			PHPDBG_G(sigsegv_bailout) = __orig_bailout;
232 #define phpdbg_end_try_access() \
233 		}                                                    \
234 			PHPDBG_G(sigsegv_bailout) = __orig_bailout;  \
235 	}
236 
237 
238 void phpdbg_register_file_handles(void);
239 
240 /* {{{ structs */
241 ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
242 	HashTable bp[PHPDBG_BREAK_TABLES];           /* break points */
243 	HashTable registered;                        /* registered */
244 	HashTable seek;                              /* seek oplines */
245 	zend_execute_data *seek_ex;                  /* call frame of oplines to seek to */
246 	zend_object *handled_exception;              /* last handled exception (prevent multiple handling of same exception) */
247 	phpdbg_frame_t frame;                        /* frame */
248 	uint32_t last_line;                          /* last executed line */
249 
250 	char *cur_command;                           /* current command */
251 	phpdbg_lexer_data lexer;                     /* lexer data */
252 	phpdbg_param_t *parser_stack;                /* param stack during lexer / parser phase */
253 
254 #ifndef _WIN32
255 	struct sigaction old_sigsegv_signal;         /* segv signal handler */
256 #endif
257 	phpdbg_btree watchpoint_tree;                /* tree with watchpoints */
258 	phpdbg_btree watch_HashTables;               /* tree with original dtors of watchpoints */
259 	HashTable watch_elements;                    /* user defined watch elements */
260 	HashTable watch_collisions;                  /* collision table to check if multiple watches share the same recursive watchpoint */
261 	HashTable watch_recreation;                  /* watch elements pending recreation of their respective watchpoints */
262 	HashTable watch_free;                        /* pointers to watch for being freed */
263 	HashTable *watchlist_mem;                    /* triggered watchpoints */
264 	HashTable *watchlist_mem_backup;             /* triggered watchpoints backup table while iterating over it */
265 	zend_bool watchpoint_hit;                    /* a watchpoint was hit */
266 	void (*original_free_function)(void *);      /* the original AG(mm_heap)->_free function */
267 	phpdbg_watch_element *watch_tmp;             /* temporary pointer for a watch element */
268 
269 	char *exec;                                  /* file to execute */
270 	size_t exec_len;                             /* size of exec */
271 	zend_op_array *ops;                 	     /* op_array */
272 	zval retval;                                 /* return value */
273 	int bp_count;                                /* breakpoint count */
274 	int vmret;                                   /* return from last opcode handler execution */
275 	zend_bool in_execution;                      /* in execution? */
276 	zend_bool unclean_eval;                      /* do not check for memory leaks when we needed to bail out during eval */
277 
278 	zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type);
279 	zend_op_array *(*init_compile_file)(zend_file_handle *file_handle, int type);
280 	zend_op_array *(*compile_string)(zval *source_string, char *filename);
281 	HashTable file_sources;
282 
283 	FILE *oplog;                                 /* opline log */
284 	zend_arena *oplog_arena;                     /* arena for storing oplog */
285 	phpdbg_oplog_list *oplog_list;               /* list of oplog starts */
286 	phpdbg_oplog_entry *oplog_cur;               /* current oplog entry */
287 
288 	struct {
289 		FILE *ptr;
290 		int fd;
291 	} io[PHPDBG_IO_FDS];                         /* io */
292 	int eol;                                     /* type of line ending to use */
293 	size_t (*php_stdiop_write)(php_stream *, const char *, size_t);
294 	int in_script_xml;                           /* in <stream> output mode */
295 	struct {
296 		zend_bool active;
297 		int type;
298 		int fd;
299 		char *tag;
300 		char *msg;
301 		int msglen;
302 		char *xml;
303 		int xmllen;
304 	} err_buf;                                   /* error buffer */
305 	zend_ulong req_id;                           /* "request id" to keep track of commands */
306 
307 	char *prompt[2];                             /* prompt */
308 	const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */
309 	char *buffer;                                /* buffer */
310 	zend_bool last_was_newline;                  /* check if we don't need to output a newline upon next phpdbg_error or phpdbg_notice */
311 
312 	FILE *stdin_file;                            /* FILE pointer to stdin source file */
313 	php_stream *(*orig_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);
314 
315 	char input_buffer[PHPDBG_MAX_CMD];           /* stdin input buffer */
316 	int input_buflen;                            /* length of stdin input buffer */
317 	phpdbg_signal_safe_mem sigsafe_mem;          /* memory to use in async safe environment (only once!) */
318 
319 	JMP_BUF *sigsegv_bailout;                    /* bailout address for accesibility probing */
320 
321 	uint64_t flags;                              /* phpdbg flags */
322 
323 	char *socket_path;                           /* phpdbg.path ini setting */
324 	char *sapi_name_ptr;                         /* store sapi name to free it if necessary to not leak memory */
325 	int socket_fd;                               /* file descriptor to socket (wait command) (-1 if unused) */
326 	int socket_server_fd;                        /* file descriptor to master socket (wait command) (-1 if unused) */
327 #ifdef PHP_WIN32
328 	HANDLE sigio_watcher_thread;                 /* sigio watcher thread handle */
329 	struct win32_sigio_watcher_data swd;
330 #endif
331 	long lines;                                  /* max number of lines to display */
332 ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */
333 
334 #endif
335 
336 #endif /* PHPDBG_H */
337