PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/xdebug_monitor.c

http://github.com/derickr/xdebug
C | 154 lines | 104 code | 30 blank | 20 comment | 18 complexity | 9b7556c01cfb1dd4c37542ff9b5dbb14 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Xdebug |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2002-2016 Derick Rethans |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 1.0 of the Xdebug license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available at through the world-wide-web at |
  10. | http://xdebug.derickrethans.nl/license.php |
  11. | If you did not receive a copy of the Xdebug license and are unable |
  12. | to obtain it through the world-wide-web, please send a note to |
  13. | xdebug@derickrethans.nl so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Derick Rethans <derick@xdebug.org> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #include "php_xdebug.h"
  19. #include "xdebug_compat.h"
  20. #include "xdebug_hash.h"
  21. #include "xdebug_monitor.h"
  22. ZEND_EXTERN_MODULE_GLOBALS(xdebug)
  23. #if PHP_VERSION_ID >= 70000
  24. static void init_function_monitor_hash(xdebug_hash *internal, HashTable *functions_to_monitor)
  25. {
  26. zval *val;
  27. ZEND_HASH_FOREACH_VAL(functions_to_monitor, val) {
  28. if (Z_TYPE_P(val) == IS_STRING) {
  29. xdebug_hash_add(internal, Z_STRVAL_P(val), Z_STRLEN_P(val), xdstrdup(Z_STRVAL_P(val)));
  30. }
  31. } ZEND_HASH_FOREACH_END();
  32. }
  33. #else
  34. static void init_function_monitor_hash(xdebug_hash *internal, HashTable *functions_to_monitor)
  35. {
  36. HashPosition pos;
  37. zval **val;
  38. zend_hash_internal_pointer_reset_ex(functions_to_monitor, &pos);
  39. while (zend_hash_get_current_data_ex(functions_to_monitor, (void **) &val, &pos) != FAILURE) {
  40. if (Z_TYPE_PP(val) == IS_STRING) {
  41. xdebug_hash_add(internal, Z_STRVAL_PP(val), Z_STRLEN_PP(val), xdstrdup(Z_STRVAL_PP(val)));
  42. }
  43. zend_hash_move_forward_ex(functions_to_monitor, &pos);
  44. }
  45. }
  46. #endif
  47. static void xdebug_hash_function_monitor_dtor(char *function)
  48. {
  49. xdfree(function);
  50. }
  51. static xdebug_monitored_function_entry *xdebug_monitored_function_init(char *func_name, char *filename, int lineno)
  52. {
  53. xdebug_monitored_function_entry *tmp = xdmalloc(sizeof(xdebug_monitored_function_entry));
  54. tmp->func_name = xdstrdup(func_name);
  55. tmp->filename = xdstrdup(filename);
  56. tmp->lineno = lineno;
  57. return tmp;
  58. }
  59. void xdebug_monitored_function_dtor(void *dummy, void *elem)
  60. {
  61. xdebug_monitored_function_entry *mfe = (xdebug_monitored_function_entry*) elem;
  62. xdfree(mfe->func_name);
  63. xdfree(mfe->filename);
  64. xdfree(mfe);
  65. }
  66. void xdebug_function_monitor_record(char *func_name, char *filename, int lineno TSRMLS_DC)
  67. {
  68. xdebug_monitored_function_entry *record;
  69. record = xdebug_monitored_function_init(func_name, filename, lineno);
  70. xdebug_llist_insert_next(XG(monitored_functions_found), XDEBUG_LLIST_TAIL(XG(monitored_functions_found)), record);
  71. }
  72. PHP_FUNCTION(xdebug_start_function_monitor)
  73. {
  74. HashTable *functions_to_monitor;
  75. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &functions_to_monitor) == FAILURE) {
  76. return;
  77. }
  78. if (XG(do_monitor_functions) == 1) {
  79. php_error(E_NOTICE, "Function monitoring was already started");
  80. }
  81. /* Clean and store list of functions to monitor */
  82. if (XG(functions_to_monitor)) {
  83. xdebug_hash_destroy(XG(functions_to_monitor));
  84. }
  85. /* We add "1" here so that we don't alloc a 0-slot hash table */
  86. XG(functions_to_monitor) = xdebug_hash_alloc(zend_hash_num_elements(functions_to_monitor) + 1, (xdebug_hash_dtor) xdebug_hash_function_monitor_dtor);
  87. init_function_monitor_hash(XG(functions_to_monitor), functions_to_monitor);
  88. XG(do_monitor_functions) = 1;
  89. }
  90. PHP_FUNCTION(xdebug_stop_function_monitor)
  91. {
  92. if (XG(do_monitor_functions) == 0) {
  93. php_error(E_NOTICE, "Function monitoring was not started");
  94. }
  95. XG(do_monitor_functions) = 0;
  96. }
  97. PHP_FUNCTION(xdebug_get_monitored_functions)
  98. {
  99. xdebug_llist_element *le;
  100. zend_bool clear = 0;
  101. xdebug_monitored_function_entry *mfe;
  102. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clear) == FAILURE) {
  103. return;
  104. }
  105. array_init(return_value);
  106. for (le = XDEBUG_LLIST_HEAD(XG(monitored_functions_found)); le != NULL; le = XDEBUG_LLIST_NEXT(le)) {
  107. zval *entry;
  108. mfe = XDEBUG_LLIST_VALP(le);
  109. XDEBUG_MAKE_STD_ZVAL(entry);
  110. array_init(entry);
  111. add_assoc_string_ex(entry, "function", HASH_KEY_SIZEOF("function"), mfe->func_name ADD_STRING_COPY);
  112. add_assoc_string_ex(entry, "filename", HASH_KEY_SIZEOF("filename"), mfe->filename ADD_STRING_COPY);
  113. add_assoc_long(entry, "lineno", mfe->lineno);
  114. add_next_index_zval(return_value, entry);
  115. #if PHP_VERSION_ID >= 70000
  116. efree(entry);
  117. #endif
  118. }
  119. if (clear) {
  120. xdebug_llist_destroy(XG(monitored_functions_found), NULL);
  121. XG(monitored_functions_found) = xdebug_llist_alloc(xdebug_monitored_function_dtor);
  122. }
  123. }
  124. /* }}} */