root/sapi/phpdbg/phpdbg_info.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHPDBG_INFO
  2. PHPDBG_INFO
  3. PHPDBG_INFO
  4. PHPDBG_INFO
  5. PHPDBG_INFO
  6. PHPDBG_INFO
  7. phpdbg_print_class_name
  8. PHPDBG_INFO
  9. PHPDBG_INFO

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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 #include "php.h"
  22 #include "phpdbg.h"
  23 #include "phpdbg_utils.h"
  24 #include "phpdbg_info.h"
  25 #include "phpdbg_bp.h"
  26 #include "phpdbg_prompt.h"
  27 
  28 ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
  29 
  30 #define PHPDBG_INFO_COMMAND_D(f, h, a, m, l, s) \
  31         PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14])
  32 
  33 const phpdbg_command_t phpdbg_info_commands[] = {
  34         PHPDBG_INFO_COMMAND_D(break,    "show breakpoints",              'b', info_break,   NULL, 0),
  35         PHPDBG_INFO_COMMAND_D(files,    "show included files",           'F', info_files,   NULL, 0),
  36         PHPDBG_INFO_COMMAND_D(classes,  "show loaded classes",           'c', info_classes, NULL, 0),
  37         PHPDBG_INFO_COMMAND_D(funcs,    "show loaded classes",           'f', info_funcs,   NULL, 0),
  38         PHPDBG_INFO_COMMAND_D(error,    "show last error",               'e', info_error,   NULL, 0),
  39         PHPDBG_INFO_COMMAND_D(vars,     "show active variables",         'v', info_vars,    NULL, 0),
  40         PHPDBG_INFO_COMMAND_D(literal,  "show active literal constants", 'l', info_literal, NULL, 0),
  41         PHPDBG_INFO_COMMAND_D(memory,   "show memory manager stats",     'm', info_memory,  NULL, 0),
  42         PHPDBG_END_COMMAND
  43 };
  44 
  45 PHPDBG_INFO(break) /* {{{ */
  46 {
  47         phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC);
  48         phpdbg_print_breakpoints(PHPDBG_BREAK_SYM TSRMLS_CC);
  49         phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD TSRMLS_CC);
  50         phpdbg_print_breakpoints(PHPDBG_BREAK_OPLINE TSRMLS_CC);
  51         phpdbg_print_breakpoints(PHPDBG_BREAK_FILE_OPLINE TSRMLS_CC);
  52         phpdbg_print_breakpoints(PHPDBG_BREAK_FUNCTION_OPLINE TSRMLS_CC);
  53         phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD_OPLINE TSRMLS_CC);
  54         phpdbg_print_breakpoints(PHPDBG_BREAK_COND TSRMLS_CC);
  55         phpdbg_print_breakpoints(PHPDBG_BREAK_OPCODE TSRMLS_CC);
  56 
  57         return SUCCESS;
  58 } /* }}} */
  59 
  60 PHPDBG_INFO(files) /* {{{ */
  61 {
  62         HashPosition pos;
  63         char *fname;
  64 
  65         phpdbg_notice("Included files: %d",
  66                 zend_hash_num_elements(&EG(included_files)));
  67 
  68         zend_hash_internal_pointer_reset_ex(&EG(included_files), &pos);
  69         while (zend_hash_get_current_key_ex(&EG(included_files), &fname,
  70                 NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) {
  71                 phpdbg_writeln("File: %s", fname);
  72                 zend_hash_move_forward_ex(&EG(included_files), &pos);
  73         }
  74 
  75         return SUCCESS;
  76 } /* }}} */
  77 
  78 PHPDBG_INFO(error) /* {{{ */
  79 {
  80         if (PG(last_error_message)) {
  81                 phpdbg_writeln("Last error: %s at %s line %d",
  82                         PG(last_error_message), PG(last_error_file), PG(last_error_lineno));
  83         } else {
  84                 phpdbg_notice("No error found!");
  85         }
  86         return SUCCESS;
  87 } /* }}} */
  88 
  89 PHPDBG_INFO(vars) /* {{{ */
  90 {
  91         HashTable vars;
  92         HashPosition pos;
  93         char *var;
  94         zval **data;
  95 
  96         if (!EG(active_op_array)) {
  97                 phpdbg_error("No active op array!");
  98                 return SUCCESS;
  99         }
 100 
 101         if (!EG(active_symbol_table)) {
 102                 zend_rebuild_symbol_table(TSRMLS_C);
 103 
 104                 if (!EG(active_symbol_table)) {
 105                         phpdbg_error("No active symbol table!");
 106                         return SUCCESS;
 107                 }
 108         }
 109 
 110         zend_hash_init(&vars, 8, NULL, NULL, 0);
 111 
 112         zend_hash_internal_pointer_reset_ex(EG(active_symbol_table), &pos);
 113         while (zend_hash_get_current_key_ex(EG(active_symbol_table), &var,
 114                 NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) {
 115                 zend_hash_get_current_data_ex(EG(active_symbol_table), (void **)&data, &pos);
 116                 if (*var != '_') {
 117                         zend_hash_update(
 118                                 &vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL);
 119                 }
 120                 zend_hash_move_forward_ex(EG(active_symbol_table), &pos);
 121         }
 122 
 123         {
 124                 zend_op_array *ops = EG(active_op_array);
 125                 
 126                 if (ops->function_name) {
 127                         if (ops->scope) {
 128                                 phpdbg_notice(
 129                                 "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars));
 130                         } else {
 131                                 phpdbg_notice(
 132                                         "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars));
 133                         }
 134                 } else {
 135                         if (ops->filename) {
 136                                 phpdbg_notice(
 137                                 "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars));
 138                         } else {
 139                                 phpdbg_notice(
 140                                         "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars));
 141                         }
 142                 }
 143         }
 144 
 145         if (zend_hash_num_elements(&vars)) {
 146                 phpdbg_writeln("Address\t\tRefs\tType\t\tVariable");
 147                 for (zend_hash_internal_pointer_reset_ex(&vars, &pos);
 148                         zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS;
 149                         zend_hash_move_forward_ex(&vars, &pos)) {
 150                         char *var;
 151 
 152                         zend_hash_get_current_key_ex(&vars, &var, NULL, NULL, 0, &pos);
 153 
 154                         if (*data) {
 155                                 phpdbg_write(
 156                                 "%p\t%d\t",
 157                                         *data,
 158                                         Z_REFCOUNT_PP(data));
 159 
 160                                 switch (Z_TYPE_PP(data)) {
 161                                         case IS_STRING:         phpdbg_write("(string)\t");     break;
 162                                         case IS_LONG:           phpdbg_write("(integer)\t");    break;
 163                                         case IS_DOUBLE:         phpdbg_write("(float)\t");              break;
 164                                         case IS_RESOURCE:       phpdbg_write("(resource)\t");   break;
 165                                         case IS_ARRAY:          phpdbg_write("(array)\t");              break;
 166                                         case IS_OBJECT:         phpdbg_write("(object)\t");     break;
 167                                         case IS_NULL:           phpdbg_write("(null)\t");               break;
 168                                 }
 169 
 170                                 if (Z_TYPE_PP(data) == IS_RESOURCE) {
 171                                         int type;
 172 
 173                                         phpdbg_writeln(
 174                                                 "%s$%s", Z_ISREF_PP(data) ? "&": "", var);
 175                                         if (zend_list_find(Z_RESVAL_PP(data), &type)) {
 176                                                 phpdbg_write(
 177                                                         "|-------(typeof)------> (%s)",
 178                                                         zend_rsrc_list_get_rsrc_type(type TSRMLS_CC));
 179                                         } else {
 180                                                 phpdbg_write(
 181                                                         "|-------(typeof)------> (unknown)");
 182                                         }
 183                                         phpdbg_writeln(EMPTY);
 184                                 } else if (Z_TYPE_PP(data) == IS_OBJECT) {
 185                                         phpdbg_writeln(
 186                                                 "%s$%s", Z_ISREF_PP(data) ? "&": "", var);
 187                                         phpdbg_write(
 188                                                 "|-----(instanceof)----> (%s)", Z_OBJCE_PP(data)->name);
 189                                         phpdbg_writeln(EMPTY);
 190                                 } else {
 191                                         phpdbg_write(
 192                                                 "%s$%s", Z_ISREF_PP(data) ? "&": "", var);
 193                                 }
 194                         } else {
 195                                 phpdbg_write(
 196                                         "n/a\tn/a\tn/a\t$%s", var);
 197                         }
 198                         phpdbg_writeln(EMPTY);
 199                 }
 200         }
 201 
 202         zend_hash_destroy(&vars);
 203 
 204         return SUCCESS;
 205 } /* }}} */
 206 
 207 PHPDBG_INFO(literal) /* {{{ */
 208 {
 209         if ((EG(in_execution) && EG(active_op_array)) || PHPDBG_G(ops)) {
 210                 zend_op_array *ops = EG(active_op_array) ? EG(active_op_array) : PHPDBG_G(ops);
 211                 int literal = 0, count = ops->last_literal-1;
 212 
 213                 if (ops->function_name) {
 214                         if (ops->scope) {
 215                                 phpdbg_notice(
 216                                 "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count);
 217                         } else {
 218                                 phpdbg_notice(
 219                                         "Literal Constants in %s() (%d)", ops->function_name, count);
 220                         }
 221                 } else {
 222                         if (ops->filename) {
 223                                 phpdbg_notice(
 224                                 "Literal Constants in %s (%d)", ops->filename, count);
 225                         } else {
 226                                 phpdbg_notice(
 227                                         "Literal Constants @ %p (%d)", ops, count);
 228                         }
 229                 }
 230 
 231                 while (literal < ops->last_literal) {
 232                         if (Z_TYPE(ops->literals[literal].constant) != IS_NULL) {
 233                                 phpdbg_write("|-------- C%u -------> [", literal);
 234                                 zend_print_zval(
 235                                         &ops->literals[literal].constant, 0);
 236                                 phpdbg_write("]");
 237                                 phpdbg_writeln(EMPTY);
 238                         }
 239                         literal++;
 240                 }
 241         } else {
 242                 phpdbg_error("Not executing!");
 243         }
 244 
 245         return SUCCESS;
 246 } /* }}} */
 247 
 248 PHPDBG_INFO(memory) /* {{{ */
 249 {
 250         if (is_zend_mm(TSRMLS_C)) {
 251                 phpdbg_notice("Memory Manager Information");
 252                 phpdbg_notice("Current");
 253                 phpdbg_writeln("|-------> Used:\t%.3f kB", 
 254                         (float) (zend_memory_usage(0 TSRMLS_CC)/1024));
 255                 phpdbg_writeln("|-------> Real:\t%.3f kB", 
 256                         (float) (zend_memory_usage(1 TSRMLS_CC)/1024));
 257                 phpdbg_notice("Peak");
 258                 phpdbg_writeln("|-------> Used:\t%.3f kB", 
 259                         (float) (zend_memory_peak_usage(0 TSRMLS_CC)/1024));
 260                 phpdbg_writeln("|-------> Real:\t%.3f kB", 
 261                         (float) (zend_memory_peak_usage(1 TSRMLS_CC)/1024));
 262         } else {
 263                 phpdbg_error("Memory Manager Disabled!");
 264         }
 265         return SUCCESS;
 266 } /* }}} */
 267 
 268 static inline void phpdbg_print_class_name(zend_class_entry **ce TSRMLS_DC) /* {{{ */
 269 {
 270         phpdbg_write(
 271                 "%s %s %s (%d)",
 272                 ((*ce)->type == ZEND_USER_CLASS) ?
 273                         "User" : "Internal",
 274                 ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
 275                         "Interface" :
 276                         ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
 277                                 "Abstract Class" :
 278                                         "Class",
 279                 (*ce)->name, zend_hash_num_elements(&(*ce)->function_table));
 280 } /* }}} */
 281 
 282 PHPDBG_INFO(classes) /* {{{ */
 283 {
 284         HashPosition position;
 285         zend_class_entry **ce;
 286         HashTable classes;
 287 
 288         zend_hash_init(&classes, 8, NULL, NULL, 0);
 289 
 290         for (zend_hash_internal_pointer_reset_ex(EG(class_table), &position);
 291                 zend_hash_get_current_data_ex(EG(class_table), (void**)&ce, &position) == SUCCESS;
 292                 zend_hash_move_forward_ex(EG(class_table), &position)) {
 293 
 294                 if ((*ce)->type == ZEND_USER_CLASS) {
 295                         zend_hash_next_index_insert(
 296                                 &classes, ce, sizeof(ce), NULL);
 297                 }
 298         }
 299 
 300         phpdbg_notice("User Classes (%d)",
 301                 zend_hash_num_elements(&classes));
 302 
 303         for (zend_hash_internal_pointer_reset_ex(&classes, &position);
 304                 zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS;
 305                 zend_hash_move_forward_ex(&classes, &position)) {
 306 
 307                 phpdbg_print_class_name(ce TSRMLS_CC);
 308                 phpdbg_writeln(EMPTY);
 309 
 310                 if ((*ce)->parent) {
 311                         zend_class_entry *pce = (*ce)->parent;
 312                         do {
 313                                 phpdbg_write("|-------- ");
 314                                 phpdbg_print_class_name(&pce TSRMLS_CC);
 315                                 phpdbg_writeln(EMPTY);
 316                         } while ((pce = pce->parent));
 317                 }
 318 
 319                 if ((*ce)->info.user.filename) {
 320                         phpdbg_writeln(
 321                                 "|---- in %s on line %u",
 322                                 (*ce)->info.user.filename,
 323                                 (*ce)->info.user.line_start);
 324                 } else {
 325                         phpdbg_writeln("|---- no source code");
 326                 }
 327                 phpdbg_writeln(EMPTY);
 328         }
 329 
 330         zend_hash_destroy(&classes);
 331 
 332         return SUCCESS;
 333 } /* }}} */
 334 
 335 PHPDBG_INFO(funcs) /* {{{ */
 336 {
 337         HashPosition position;
 338         zend_function *zf, **pzf;
 339         HashTable functions;
 340 
 341         zend_hash_init(&functions, 8, NULL, NULL, 0);
 342 
 343         for (zend_hash_internal_pointer_reset_ex(EG(function_table), &position);
 344                 zend_hash_get_current_data_ex(EG(function_table), (void**)&zf, &position) == SUCCESS;
 345                 zend_hash_move_forward_ex(EG(function_table), &position)) {
 346 
 347                 if (zf->type == ZEND_USER_FUNCTION) {
 348                         zend_hash_next_index_insert(
 349                                 &functions, (void**) &zf, sizeof(zend_function), NULL);
 350                 }
 351         }
 352 
 353         phpdbg_notice("User Functions (%d)",
 354                 zend_hash_num_elements(&functions));
 355 
 356         for (zend_hash_internal_pointer_reset_ex(&functions, &position);
 357                 zend_hash_get_current_data_ex(&functions, (void**)&pzf, &position) == SUCCESS;
 358                 zend_hash_move_forward_ex(&functions, &position)) {
 359                 zend_op_array *op_array = &((*pzf)->op_array);
 360 
 361                 phpdbg_writeln(
 362                         "|-------- %s in %s on line %d",
 363                         op_array->function_name ? op_array->function_name : "{main}",
 364                         op_array->filename ? op_array->filename : "(no source code)",
 365                         op_array->line_start);
 366         }
 367 
 368         zend_hash_destroy(&functions);
 369 
 370         return SUCCESS;
 371 } /* }}} */

/* [<][>][^][v][top][bottom][index][help] */