PageRenderTime 37ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/xdebug_trace_computerized.c

http://github.com/derickr/xdebug
C | 252 lines | 184 code | 47 blank | 21 comment | 16 complexity | f1c71d96d48563a68e137fbc4fe413b3 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 "xdebug_trace_computerized.h"
  19. #include "xdebug_var.h"
  20. #include "ext/standard/php_string.h"
  21. extern ZEND_DECLARE_MODULE_GLOBALS(xdebug);
  22. void *xdebug_trace_computerized_init(char *fname, long options TSRMLS_DC)
  23. {
  24. xdebug_trace_computerized_context *tmp_computerized_context;
  25. char *used_fname;
  26. tmp_computerized_context = xdmalloc(sizeof(xdebug_trace_computerized_context));
  27. tmp_computerized_context->trace_file = xdebug_trace_open_file(fname, options, (char**) &used_fname TSRMLS_CC);
  28. tmp_computerized_context->trace_filename = used_fname;
  29. return tmp_computerized_context->trace_file ? tmp_computerized_context : NULL;
  30. }
  31. void xdebug_trace_computerized_deinit(void *ctxt TSRMLS_DC)
  32. {
  33. xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt;
  34. fclose(context->trace_file);
  35. context->trace_file = NULL;
  36. xdfree(context->trace_filename);
  37. xdfree(context);
  38. }
  39. void xdebug_trace_computerized_write_header(void *ctxt TSRMLS_DC)
  40. {
  41. xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt;
  42. char *str_time;
  43. fprintf(context->trace_file, "Version: %s\n", XDEBUG_VERSION);
  44. fprintf(context->trace_file, "File format: 4\n");
  45. str_time = xdebug_get_time();
  46. fprintf(context->trace_file, "TRACE START [%s]\n", str_time);
  47. fflush(context->trace_file);
  48. xdfree(str_time);
  49. }
  50. void xdebug_trace_computerized_write_footer(void *ctxt TSRMLS_DC)
  51. {
  52. xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt;
  53. char *str_time;
  54. double u_time;
  55. char *tmp;
  56. u_time = xdebug_get_utime();
  57. tmp = xdebug_sprintf("\t\t\t%F\t", u_time - XG(start_time));
  58. fprintf(context->trace_file, "%s", tmp);
  59. xdfree(tmp);
  60. #if WIN32|WINNT
  61. fprintf(context->trace_file, "%Iu", zend_memory_usage(0 TSRMLS_CC));
  62. #else
  63. fprintf(context->trace_file, "%zu", zend_memory_usage(0 TSRMLS_CC));
  64. #endif
  65. fprintf(context->trace_file, "\n");
  66. str_time = xdebug_get_time();
  67. fprintf(context->trace_file, "TRACE END [%s]\n\n", str_time);
  68. fflush(context->trace_file);
  69. xdfree(str_time);
  70. }
  71. char *xdebug_trace_computerized_get_filename(void *ctxt TSRMLS_DC)
  72. {
  73. xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt;
  74. return context->trace_filename;
  75. }
  76. static char *render_variable(zval *var, int type TSRMLS_DC)
  77. {
  78. char *tmp_value = NULL;
  79. switch (XG(collect_params)) {
  80. case 1: /* synopsis */
  81. case 2:
  82. tmp_value = xdebug_get_zval_synopsis(var, 0, NULL);
  83. break;
  84. case 3: /* full */
  85. case 4: /* full (with var) */
  86. default:
  87. tmp_value = xdebug_get_zval_value(var, 0, NULL);
  88. break;
  89. case 5: /* serialized */
  90. tmp_value = xdebug_get_zval_value_serialized(var, 0, NULL TSRMLS_CC);
  91. break;
  92. }
  93. return tmp_value;
  94. }
  95. void xdebug_trace_computerized_function_entry(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC)
  96. {
  97. xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt;
  98. char *tmp_name;
  99. xdebug_str str = XDEBUG_STR_INITIALIZER;
  100. xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->level), 1);
  101. xdebug_str_add(&str, xdebug_sprintf("%d\t", function_nr), 1);
  102. tmp_name = xdebug_show_fname(fse->function, 0, 0 TSRMLS_CC);
  103. xdebug_str_add(&str, "0\t", 0);
  104. xdebug_str_add(&str, xdebug_sprintf("%F\t", fse->time - XG(start_time)), 1);
  105. xdebug_str_add(&str, xdebug_sprintf("%lu\t", fse->memory), 1);
  106. xdebug_str_add(&str, xdebug_sprintf("%s\t", tmp_name), 1);
  107. xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->user_defined == XDEBUG_EXTERNAL ? 1 : 0), 1);
  108. xdfree(tmp_name);
  109. if (fse->include_filename) {
  110. if (fse->function.type == XFUNC_EVAL) {
  111. #if PHP_VERSION_ID >= 70000
  112. zend_string *i_filename = zend_string_init(fse->include_filename, strlen(fse->include_filename), 0);
  113. zend_string *escaped;
  114. escaped = php_addcslashes(i_filename, 0, "'\\\0..\37", 6);
  115. xdebug_str_add(&str, xdebug_sprintf("'%s'", escaped->val), 1);
  116. zend_string_release(escaped);
  117. zend_string_release(i_filename);
  118. #else
  119. int tmp_len;
  120. char *escaped;
  121. escaped = php_addcslashes(fse->include_filename, strlen(fse->include_filename), &tmp_len, 0, "'\\\0..\37", 6 TSRMLS_CC);
  122. xdebug_str_add(&str, xdebug_sprintf("'%s'", escaped), 1);
  123. efree(escaped);
  124. #endif
  125. } else {
  126. xdebug_str_add(&str, fse->include_filename, 0);
  127. }
  128. }
  129. /* Filename and Lineno (9, 10) */
  130. xdebug_str_add(&str, xdebug_sprintf("\t%s\t%d", fse->filename, fse->lineno), 1);
  131. if (XG(collect_params) > 0) {
  132. unsigned int j = 0; /* Counter */
  133. /* Nr of arguments (11) */
  134. xdebug_str_add(&str, xdebug_sprintf("\t%d", fse->varc), 1);
  135. /* Arguments (12-...) */
  136. for (j = 0; j < fse->varc; j++) {
  137. char *tmp_value;
  138. xdebug_str_addl(&str, "\t", 1, 0);
  139. if (fse->var[j].is_variadic) {
  140. xdebug_str_addl(&str, "...\t", 4, 0);
  141. }
  142. if (fse->var[j].name && XG(collect_params) == 4) {
  143. xdebug_str_add(&str, xdebug_sprintf("$%s = ", fse->var[j].name), 1);
  144. }
  145. tmp_value = render_variable(fse->var[j].addr, XG(collect_params) TSRMLS_CC);
  146. if (tmp_value) {
  147. xdebug_str_add(&str, tmp_value, 1);
  148. } else {
  149. xdebug_str_add(&str, "???", 0);
  150. }
  151. }
  152. }
  153. /* Trailing \n */
  154. xdebug_str_add(&str, "\n", 0);
  155. fprintf(context->trace_file, "%s", str.d);
  156. fflush(context->trace_file);
  157. xdfree(str.d);
  158. }
  159. void xdebug_trace_computerized_function_exit(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC)
  160. {
  161. xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt;
  162. xdebug_str str = XDEBUG_STR_INITIALIZER;
  163. xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->level), 1);
  164. xdebug_str_add(&str, xdebug_sprintf("%d\t", function_nr), 1);
  165. xdebug_str_add(&str, "1\t", 0);
  166. xdebug_str_add(&str, xdebug_sprintf("%F\t", xdebug_get_utime() - XG(start_time)), 1);
  167. xdebug_str_add(&str, xdebug_sprintf("%lu\n", zend_memory_usage(0 TSRMLS_CC)), 1);
  168. fprintf(context->trace_file, "%s", str.d);
  169. fflush(context->trace_file);
  170. xdfree(str.d);
  171. }
  172. void xdebug_trace_computerized_function_return_value(void *ctxt, function_stack_entry *fse, int function_nr, zval *return_value TSRMLS_DC)
  173. {
  174. xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt;
  175. xdebug_str str = XDEBUG_STR_INITIALIZER;
  176. char *tmp_value = NULL;
  177. xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->level), 1);
  178. xdebug_str_add(&str, xdebug_sprintf("%d\t", function_nr), 1);
  179. xdebug_str_add(&str, "R\t\t\t", 0);
  180. tmp_value = render_variable(return_value, XG(collect_params) TSRMLS_CC);
  181. if (tmp_value) {
  182. xdebug_str_add(&str, tmp_value, 1);
  183. } else {
  184. xdebug_str_add(&str, "???", 0);
  185. }
  186. xdebug_str_addl(&str, "\n", 2, 0);
  187. fprintf(context->trace_file, "%s", str.d);
  188. fflush(context->trace_file);
  189. xdfree(str.d);
  190. }
  191. xdebug_trace_handler_t xdebug_trace_handler_computerized =
  192. {
  193. xdebug_trace_computerized_init,
  194. xdebug_trace_computerized_deinit,
  195. xdebug_trace_computerized_write_header,
  196. xdebug_trace_computerized_write_footer,
  197. xdebug_trace_computerized_get_filename,
  198. xdebug_trace_computerized_function_entry,
  199. xdebug_trace_computerized_function_exit,
  200. xdebug_trace_computerized_function_return_value,
  201. #if PHP_VERSION_ID >= 50500
  202. NULL /* xdebug_trace_computerized_generator_return_value */,
  203. #endif
  204. NULL /* xdebug_trace_computerized_assignment */
  205. };