root/sapi/fpm/fpm/fpm_php_trace.c

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

DEFINITIONS

This source file includes following definitions.
  1. fpm_php_trace_dump
  2. fpm_php_trace

   1 
   2         /* $Id: fpm_php_trace.c,v 1.27.2.1 2008/11/15 00:57:24 anight Exp $ */
   3         /* (c) 2007,2008 Andrei Nigmatulin */
   4 
   5 #include "fpm_config.h"
   6 
   7 #if HAVE_FPM_TRACE
   8 
   9 #include "php.h"
  10 #include "php_main.h"
  11 
  12 #include <stdio.h>
  13 #include <stddef.h>
  14 #if HAVE_INTTYPES_H
  15 # include <inttypes.h>
  16 #else
  17 # include <stdint.h>
  18 #endif
  19 #include <unistd.h>
  20 #include <sys/time.h>
  21 #include <sys/types.h>
  22 #include <errno.h>
  23 
  24 #include "fpm_trace.h"
  25 #include "fpm_php_trace.h"
  26 #include "fpm_children.h"
  27 #include "fpm_worker_pool.h"
  28 #include "fpm_process_ctl.h"
  29 #include "fpm_scoreboard.h"
  30 
  31 #include "zlog.h"
  32 
  33 
  34 #define valid_ptr(p) ((p) && 0 == ((p) & (sizeof(long) - 1)))
  35 
  36 #if SIZEOF_LONG == 4
  37 #define PTR_FMT "08"
  38 #elif SIZEOF_LONG == 8
  39 #define PTR_FMT "016"
  40 #endif
  41 
  42 
  43 static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog TSRMLS_DC) /* {{{ */
  44 {
  45         int callers_limit = 20;
  46         pid_t pid = child->pid;
  47         struct timeval tv;
  48         static const int buf_size = 1024;
  49         char buf[buf_size];
  50         long execute_data;
  51         long l;
  52 
  53         gettimeofday(&tv, 0);
  54 
  55         zlog_print_time(&tv, buf, buf_size);
  56 
  57         fprintf(slowlog, "\n%s [pool %s] pid %d\n", buf, child->wp->config->name, (int) pid);
  58 
  59         if (0 > fpm_trace_get_strz(buf, buf_size, (long) &SG(request_info).path_translated)) {
  60                 return -1;
  61         }
  62 
  63         fprintf(slowlog, "script_filename = %s\n", buf);
  64 
  65         if (0 > fpm_trace_get_long((long) &EG(current_execute_data), &l)) {
  66                 return -1;
  67         }
  68 
  69         execute_data = l;
  70 
  71         while (execute_data) {
  72                 long function;
  73                 uint lineno = 0;
  74 
  75                 fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data);
  76 
  77                 if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, function_state.function), &l)) {
  78                         return -1;
  79                 }
  80 
  81                 function = l;
  82 
  83                 if (valid_ptr(function)) {
  84                         if (0 > fpm_trace_get_strz(buf, buf_size, function + offsetof(zend_function, common.function_name))) {
  85                                 return -1;
  86                         }
  87 
  88                         fprintf(slowlog, "%s()", buf);
  89                 } else {
  90                         fprintf(slowlog, "???");
  91                 }
  92 
  93                 if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, op_array), &l)) {
  94                         return -1;
  95                 }
  96 
  97                 *buf = '\0';
  98 
  99                 if (valid_ptr(l)) {
 100                         long op_array = l;
 101 
 102                         if (0 > fpm_trace_get_strz(buf, buf_size, op_array + offsetof(zend_op_array, filename))) {
 103                                 return -1;
 104                         }
 105                 }
 106 
 107                 if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, opline), &l)) {
 108                         return -1;
 109                 }
 110 
 111                 if (valid_ptr(l)) {
 112                         long opline = l;
 113                         uint *lu = (uint *) &l;
 114 
 115                         if (0 > fpm_trace_get_long(opline + offsetof(struct _zend_op, lineno), &l)) {
 116                                 return -1;
 117                         }
 118 
 119                         lineno = *lu;
 120                 }
 121 
 122                 fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno);
 123 
 124                 if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) {
 125                         return -1;
 126                 }
 127 
 128                 execute_data = l;
 129 
 130                 if (0 == --callers_limit) {
 131                         break;
 132                 }
 133         }
 134         return 0;
 135 }
 136 /* }}} */
 137 
 138 void fpm_php_trace(struct fpm_child_s *child) /* {{{ */
 139 {
 140         TSRMLS_FETCH();
 141         fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, child->wp->scoreboard);
 142         FILE *slowlog;
 143 
 144         zlog(ZLOG_NOTICE, "about to trace %d", (int) child->pid);
 145 
 146         slowlog = fopen(child->wp->config->slowlog, "a+");
 147 
 148         if (!slowlog) {
 149                 zlog(ZLOG_SYSERROR, "unable to open slowlog (%s)", child->wp->config->slowlog);
 150                 goto done0;
 151         }
 152 
 153         if (0 > fpm_trace_ready(child->pid)) {
 154                 goto done1;
 155         }
 156 
 157         if (0 > fpm_php_trace_dump(child, slowlog TSRMLS_CC)) {
 158                 fprintf(slowlog, "+++ dump failed\n");
 159         }
 160 
 161         if (0 > fpm_trace_close(child->pid)) {
 162                 goto done1;
 163         }
 164 
 165 done1:
 166         fclose(slowlog);
 167 
 168 done0:
 169         fpm_pctl_kill(child->pid, FPM_PCTL_CONT);
 170         child->tracer = 0;
 171 
 172         zlog(ZLOG_NOTICE, "finished trace of %d", (int) child->pid);
 173 }
 174 /* }}} */
 175 
 176 #endif
 177 

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