php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
phpdbg_list.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 <sys/stat.h>
22#ifndef _WIN32
23# include <sys/mman.h>
24# include <unistd.h>
25#endif
26#include <fcntl.h>
27#include "phpdbg.h"
28#include "phpdbg_list.h"
29#include "phpdbg_utils.h"
30#include "phpdbg_prompt.h"
31#include "php_streams.h"
32#include "zend_exceptions.h"
33
35
36#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s, flags) \
37 PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[12], flags)
38
40 PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l", PHPDBG_ASYNC_SAFE),
41 PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s", PHPDBG_ASYNC_SAFE),
42 PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m", PHPDBG_ASYNC_SAFE),
43 PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s", PHPDBG_ASYNC_SAFE),
45};
46
47PHPDBG_LIST(lines) /* {{{ */
48{
49 if (!PHPDBG_G(exec) && !zend_is_executing()) {
50 phpdbg_error("Not executing, and execution context not set");
51 return SUCCESS;
52 }
53
54 switch (param->type) {
55 case NUMERIC_PARAM: {
56 const char *char_file = phpdbg_current_file();
57 zend_string *file = zend_string_init(char_file, strlen(char_file), 0);
58 phpdbg_list_file(file, param->num < 0 ? 1 - param->num : param->num, (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(), 0);
59 efree(file);
60 } break;
61
62 case FILE_PARAM: {
64 char resolved_path_buf[MAXPATHLEN];
65 const char *abspath = param->file.name;
66 if (VCWD_REALPATH(abspath, resolved_path_buf)) {
67 abspath = resolved_path_buf;
68 }
69 file = zend_string_init(abspath, strlen(abspath), 0);
70 phpdbg_list_file(file, param->file.line, 0, 0);
71 zend_string_release(file);
72 } break;
73
75 }
76
77 return SUCCESS;
78} /* }}} */
79
80PHPDBG_LIST(func) /* {{{ */
81{
82 phpdbg_list_function_byname(param->str, param->len);
83
84 return SUCCESS;
85} /* }}} */
86
87PHPDBG_LIST(method) /* {{{ */
88{
90
91 if (phpdbg_safe_class_lookup(param->method.class, strlen(param->method.class), &ce) == SUCCESS) {
93 char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name));
94
95 if ((function = zend_hash_str_find_ptr(&ce->function_table, lcname, strlen(lcname)))) {
97 } else {
98 phpdbg_error("Could not find %s::%s", param->method.class, param->method.name);
99 }
100
101 efree(lcname);
102 } else {
103 phpdbg_error("Could not find the class %s", param->method.class);
104 }
105
106 return SUCCESS;
107} /* }}} */
108
109PHPDBG_LIST(class) /* {{{ */
110{
112
113 if (phpdbg_safe_class_lookup(param->str, param->len, &ce) == SUCCESS) {
114 if (ce->type == ZEND_USER_CLASS) {
115 if (ce->info.user.filename) {
117 } else {
118 phpdbg_error("The source of the requested class (%s) cannot be found", ZSTR_VAL(ce->name));
119 }
120 } else {
121 phpdbg_error("The class requested (%s) is not user defined", ZSTR_VAL(ce->name));
122 }
123 } else {
124 phpdbg_error("The requested class (%s) could not be found", param->str);
125 }
126
127 return SUCCESS;
128} /* }}} */
129
130void phpdbg_list_file(zend_string *filename, uint32_t count, int offset, uint32_t highlight) /* {{{ */
131{
132 uint32_t line, lastline;
134
135 if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) {
136 phpdbg_error("Could not find information about included file...");
137 return;
138 }
139
140 if (offset < 0) {
141 count += offset;
142 offset = 0;
143 }
144
145 lastline = offset + count;
146
147 if (lastline > data->lines) {
148 lastline = data->lines;
149 }
150
151 for (line = offset; line < lastline;) {
152 uint32_t linestart = data->line[line++];
153 uint32_t linelen = data->line[line] - linestart;
154 char *buffer = data->buf + linestart;
155
156 if (!highlight) {
157 phpdbg_write(" %05u: %.*s", line, linelen, buffer);
158 } else {
159 if (highlight != line) {
160 phpdbg_write(" %05u: %.*s", line, linelen, buffer);
161 } else {
162 phpdbg_write(">%05u: %.*s", line, linelen, buffer);
163 }
164 }
165
166 if (*(buffer + linelen - 1) != '\n' || !linelen) {
167 phpdbg_out("\n");
168 }
169 }
170} /* }}} */
171
173{
174 const zend_op_array *ops;
175
176 if (fbc->type != ZEND_USER_FUNCTION) {
177 phpdbg_error("The function requested (%s) is not user defined", ZSTR_VAL(fbc->common.function_name));
178 return;
179 }
180
181 ops = (zend_op_array *) fbc;
182
183 phpdbg_list_file(ops->filename, ops->line_end - ops->line_start + 1, ops->line_start, 0);
184} /* }}} */
185
186void phpdbg_list_function_byname(const char *str, size_t len) /* {{{ */
187{
188 HashTable *func_table = EG(function_table);
190 char *func_name = (char*) str;
191 size_t func_name_len = len;
192
193 /* search active scope if begins with period */
194 if (func_name[0] == '.') {
196 if (scope) {
197 func_name++;
199
200 func_table = &scope->function_table;
201 } else {
202 phpdbg_error("No active class");
203 return;
204 }
205 } else if (!EG(function_table)) {
206 phpdbg_error("No function table loaded");
207 return;
208 } else {
209 func_table = EG(function_table);
210 }
211
212 /* use lowercase names, case insensitive */
214
216 if ((fbc = zend_hash_str_find_ptr(func_table, func_name, func_name_len))) {
218 } else {
219 phpdbg_error("Function %s not found", func_name);
220 }
222 phpdbg_error("Could not list function %s, invalid data source", func_name);
224
226} /* }}} */
227
228/* Note: do not free the original file handler, let original compile_file() or caller do that. Caller may rely on its value to check success */
230 phpdbg_file_source data, *dataptr;
232 uint32_t line;
233 char *bufptr, *endptr;
234 size_t len;
235
236 /* Copy file contents before calling original compile_file,
237 * as it may invalidate the file handle. */
238 if (zend_stream_fixup(file, &bufptr, &len) == FAILURE) {
239 if (type == ZEND_REQUIRE) {
241 } else {
243 }
244 return NULL;
245 }
246
247 data.buf = estrndup(bufptr, len);
248 data.len = len;
249
251 if (ret == NULL) {
252 efree(data.buf);
253 return ret;
254 }
255
256 data.buf[data.len] = '\0';
257 data.line[0] = 0;
258 *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint32_t) * data.len)) = data;
259
260 for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
261 if (*bufptr == '\n') {
262 dataptr->line[++line] = (uint32_t)(bufptr - data.buf) + 1;
263 }
264 }
265
266 dataptr->lines = ++line;
267 dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint32_t) * line);
268 dataptr->line[line] = endptr - data.buf;
269
271 zend_hash_add_ptr(&PHPDBG_G(file_sources), ret->filename, dataptr);
273
274 return ret;
275}
276
278 zend_string *filename = file->opened_path ? file->opened_path : file->filename;
279 char resolved_path_buf[MAXPATHLEN];
280 zend_op_array *op_array;
281 phpdbg_file_source *dataptr;
282
283 if (VCWD_REALPATH(ZSTR_VAL(filename), resolved_path_buf)) {
284 filename = zend_string_init(resolved_path_buf, strlen(resolved_path_buf), 0);
285
286 if (file->opened_path) {
287 zend_string_release(file->opened_path);
288 file->opened_path = filename;
289 } else {
290 zend_string_release(file->filename);
291 file->filename = filename;
292 }
293 }
294
295 op_array = PHPDBG_G(init_compile_file)(file, type);
296
297 if (op_array == NULL) {
298 return NULL;
299 }
300
301 dataptr = zend_hash_find_ptr(&PHPDBG_G(file_sources), op_array->filename);
302 ZEND_ASSERT(dataptr != NULL);
303
304 dataptr->op_array = *op_array;
305 if (dataptr->op_array.refcount) {
306 ++*dataptr->op_array.refcount;
307 }
308
309 return op_array;
310}
311
312zend_op_array *phpdbg_compile_string(zend_string *source_string, const char *filename, zend_compile_position position) {
313 zend_string *fake_name;
314 zend_op_array *op_array;
315 phpdbg_file_source *dataptr;
316 uint32_t line;
317 char *bufptr, *endptr;
318
320 return PHPDBG_G(compile_string)(source_string, filename, position);
321 }
322
323 dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint32_t) * ZSTR_LEN(source_string));
324 dataptr->buf = estrndup(ZSTR_VAL(source_string), ZSTR_LEN(source_string));
325 dataptr->len = ZSTR_LEN(source_string);
326 dataptr->line[0] = 0;
327 for (line = 0, bufptr = dataptr->buf - 1, endptr = dataptr->buf + dataptr->len; ++bufptr < endptr;) {
328 if (*bufptr == '\n') {
329 dataptr->line[++line] = (uint32_t)(bufptr - dataptr->buf) + 1;
330 }
331 }
332 dataptr->lines = ++line;
333 dataptr->line[line] = endptr - dataptr->buf;
334
335 op_array = PHPDBG_G(compile_string)(source_string, filename, position);
336
337 if (op_array == NULL) {
338 efree(dataptr->buf);
339 efree(dataptr);
340 return NULL;
341 }
342
343 fake_name = strpprintf(0, "%s%c%p", filename, 0, op_array->opcodes);
344
345 dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint32_t) * line);
346 zend_hash_add_ptr(&PHPDBG_G(file_sources), fake_name, dataptr);
347
348 zend_string_release(fake_name);
349
350 dataptr->op_array = *op_array;
351 if (dataptr->op_array.refcount) {
352 ++*dataptr->op_array.refcount;
353 }
354
355 return op_array;
356}
357
364
size_t len
Definition apprentice.c:174
file(string $filename, int $flags=0, $context=null)
count(Countable|array $value, int $mode=COUNT_NORMAL)
Definition test.php:8
zend_ffi_type * type
Definition ffi.c:3812
const php_stream_filter_ops * ops
Definition filters.c:1899
zend_long offset
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
int line
Definition php_ffi.h:54
char * exec
Definition phpdbg.h:263
#define PHPDBG_G(v)
Definition phpdbg.h:102
#define phpdbg_try_access
Definition phpdbg.h:194
#define phpdbg_catch_access
Definition phpdbg.h:201
#define PHPDBG_IN_EVAL
Definition phpdbg.h:142
zend_op_array *(* init_compile_file)(zend_file_handle *file_handle, int type)
Definition phpdbg.h:273
#define phpdbg_end_try_access()
Definition phpdbg.h:204
HashTable file_sources
Definition phpdbg.h:275
zend_ulong lines
Definition phpdbg.h:311
zend_op_array *(* compile_string)(zend_string *source_string, const char *filename, zend_compile_position position)
Definition phpdbg.h:274
zend_op_array *(* compile_file)(zend_file_handle *file_handle, int type)
Definition phpdbg.h:272
PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file)
Definition phpdbg_bp.c:389
@ FILE_PARAM
Definition phpdbg_cmd.h:35
@ NUMERIC_PARAM
Definition phpdbg_cmd.h:39
#define PHPDBG_END_COMMAND
Definition phpdbg_cmd.h:171
#define phpdbg_default_switch_case()
Definition phpdbg_cmd.h:176
struct _phpdbg_command_t phpdbg_command_t
Definition phpdbg_cmd.h:88
#define PHPDBG_ASYNC_SAFE
Definition phpdbg_cmd.h:84
zend_constant * data
void phpdbg_list_function(const zend_function *fbc)
void phpdbg_list_function_byname(const char *str, size_t len)
#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s, flags)
Definition phpdbg_list.c:36
zend_op_array * phpdbg_init_compile_file(zend_file_handle *file, int type)
void phpdbg_init_list(void)
const phpdbg_command_t phpdbg_list_commands[]
Definition phpdbg_list.c:39
void phpdbg_list_update(void)
zend_op_array * phpdbg_compile_file(zend_file_handle *file, int type)
zend_op_array * phpdbg_compile_string(zend_string *source_string, const char *filename, zend_compile_position position)
void phpdbg_list_file(zend_string *filename, uint32_t count, int offset, uint32_t highlight)
#define PHPDBG_LIST(name)
Definition phpdbg_list.h:25
#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
const char * func_name
zend_string * lcname
size_t func_name_len
int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry **ce)
PHPDBG_API const char * phpdbg_current_file(void)
const char * endptr
Definition session.c:1021
#define strpprintf
Definition spprintf.h:30
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
uint32_t line_end
Definition zend.h:230
char type
Definition zend.h:148
uint32_t line_start
Definition zend.h:229
HashTable function_table
Definition zend.h:163
uint32_t * refcount
zend_string * filename
zend_op * opcodes
Definition file.h:177
uint32_t line[1]
Definition phpdbg_list.h:47
zend_op_array op_array
Definition phpdbg_list.h:45
ZEND_API void zend_message_dispatcher(zend_long message, const void *data)
Definition zend.c:1393
#define ZMSG_FAILED_REQUIRE_FOPEN
Definition zend.h:424
#define ZMSG_FAILED_INCLUDE_FOPEN
Definition zend.h:423
#define ZEND_EXTERN_MODULE_GLOBALS(module_name)
Definition zend_API.h:270
#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
strlen(string $string)
execute_data func
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)
enum _zend_compile_position zend_compile_position
#define ZEND_USER_FUNCTION
#define ZEND_REQUIRE
struct _zend_op_array zend_op_array
#define ZEND_USER_CLASS
ZEND_API uint32_t zend_get_executed_lineno(void)
ZEND_API zend_class_entry * zend_get_executed_scope(void)
ZEND_API bool zend_is_executing(void)
union _zend_function zend_function
#define EG(v)
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
Definition zend_hash.c:1534
struct _zend_file_handle zend_file_handle
struct _zend_string zend_string
ZEND_API char *ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t length)
#define ZEND_ASSERT(c)
struct _zend_class_entry zend_class_entry
ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len)
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
struct _zend_array HashTable
Definition zend_types.h:386
@ FAILURE
Definition zend_types.h:61
#define MAXPATHLEN
#define VCWD_REALPATH(path, real_path)
zend_function * fbc
function(EX_VAR(opline->result.var))
zval * ret
new_op_array scope