PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/fpm/fpm_php_trace.c

http://github.com/dreamcat4/php-fpm
C | 176 lines | 123 code | 51 blank | 2 comment | 24 complexity | 2ea1ad0826696a8a4f73784591b84315 MD5 | raw file
  1. /* $Id: fpm_php_trace.c,v 1.27.2.1 2008/11/15 00:57:24 anight Exp $ */
  2. /* (c) 2007,2008 Andrei Nigmatulin */
  3. #include "fpm_config.h"
  4. #if HAVE_FPM_TRACE
  5. #include "php.h"
  6. #include "php_main.h"
  7. #include <stdio.h>
  8. #include <stddef.h>
  9. #if HAVE_INTTYPES_H
  10. #include <inttypes.h>
  11. #else
  12. #include <stdint.h>
  13. #endif
  14. #include <unistd.h>
  15. #include <sys/time.h>
  16. #include <sys/types.h>
  17. #include <errno.h>
  18. #include "fpm_trace.h"
  19. #include "fpm_php_trace.h"
  20. #include "fpm_children.h"
  21. #include "fpm_worker_pool.h"
  22. #include "fpm_process_ctl.h"
  23. #include "zlog.h"
  24. #define valid_ptr(p) ((p) && 0 == ((p) & (sizeof(long) - 1)))
  25. #if SIZEOF_LONG == 4
  26. #define PTR_FMT "08"
  27. #elif SIZEOF_LONG == 8
  28. #define PTR_FMT "016"
  29. #endif
  30. static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog TSRMLS_DC)
  31. {
  32. int callers_limit = 20;
  33. pid_t pid = child->pid;
  34. struct timeval tv;
  35. static const int buf_size = 1024;
  36. char buf[buf_size];
  37. long execute_data;
  38. long l;
  39. gettimeofday(&tv, 0);
  40. zlog_print_time(&tv, buf, buf_size);
  41. fprintf(slowlog, "\n%s pid %d (pool %s)\n", buf, (int) pid, child->wp->config->name);
  42. if (0 > fpm_trace_get_strz(buf, buf_size, (long) &SG(request_info).path_translated)) {
  43. return -1;
  44. }
  45. fprintf(slowlog, "script_filename = %s\n", buf);
  46. if (0 > fpm_trace_get_long((long) &EG(current_execute_data), &l)) {
  47. return -1;
  48. }
  49. execute_data = l;
  50. while (execute_data) {
  51. long function;
  52. uint lineno = 0;
  53. fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data);
  54. if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, function_state.function), &l)) {
  55. return -1;
  56. }
  57. function = l;
  58. if (valid_ptr(function)) {
  59. if (0 > fpm_trace_get_strz(buf, buf_size, function + offsetof(zend_function, common.function_name))) {
  60. return -1;
  61. }
  62. fprintf(slowlog, "%s()", buf);
  63. }
  64. else {
  65. fprintf(slowlog, "???");
  66. }
  67. if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, op_array), &l)) {
  68. return -1;
  69. }
  70. *buf = '\0';
  71. if (valid_ptr(l)) {
  72. long op_array = l;
  73. if (0 > fpm_trace_get_strz(buf, buf_size, op_array + offsetof(zend_op_array, filename))) {
  74. return -1;
  75. }
  76. }
  77. if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, opline), &l)) {
  78. return -1;
  79. }
  80. if (valid_ptr(l)) {
  81. long opline = l;
  82. uint *lu = (uint *) &l;
  83. if (0 > fpm_trace_get_long(opline + offsetof(struct _zend_op, lineno), &l)) {
  84. return -1;
  85. }
  86. lineno = *lu;
  87. }
  88. fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno);
  89. if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) {
  90. return -1;
  91. }
  92. execute_data = l;
  93. if (0 == --callers_limit) {
  94. break;
  95. }
  96. }
  97. return 0;
  98. }
  99. void fpm_php_trace(struct fpm_child_s *child)
  100. {
  101. TSRMLS_FETCH();
  102. FILE *slowlog;
  103. zlog(ZLOG_STUFF, ZLOG_NOTICE, "about to trace %d", (int) child->pid);
  104. slowlog = fopen(child->wp->config->slowlog, "a+");
  105. if (!slowlog) {
  106. zlog(ZLOG_STUFF, ZLOG_SYSERROR, "fopen(%s) failed", child->wp->config->slowlog);
  107. goto done0;
  108. }
  109. if (0 > fpm_trace_ready(child->pid)) {
  110. goto done1;
  111. }
  112. if (0 > fpm_php_trace_dump(child, slowlog TSRMLS_CC)) {
  113. fprintf(slowlog, "+++ dump failed\n");
  114. }
  115. if (0 > fpm_trace_close(child->pid)) {
  116. goto done1;
  117. }
  118. done1:
  119. fclose(slowlog);
  120. done0:
  121. fpm_pctl_kill(child->pid, FPM_PCTL_CONT);
  122. child->tracer = 0;
  123. zlog(ZLOG_STUFF, ZLOG_NOTICE, "finished trace of %d", (int) child->pid);
  124. }
  125. #endif