]> granicus.if.org Git - php/commitdiff
Implemented fpm_trace for PHP7
authorXinchen Hui <laruence@gmail.com>
Mon, 11 May 2015 03:22:38 +0000 (11:22 +0800)
committerXinchen Hui <laruence@gmail.com>
Mon, 11 May 2015 03:22:38 +0000 (11:22 +0800)
sapi/fpm/fpm/fpm_php_trace.c
sapi/fpm/fpm/fpm_trace.c

index 91394a0b47c4b8ef8525b56ae3917b811f20bd89..f6506fcb942c7269b1f978f99148c808d1396e1d 100644 (file)
 
 static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ */
 {
-// TODO: fpm_php_trace_dump() has to be reimplemented ???
-#if 0
        int callers_limit = 20;
        pid_t pid = child->pid;
        struct timeval tv;
        static const int buf_size = 1024;
        char buf[buf_size];
        long execute_data;
+       long path_translated;
        long l;
 
        gettimeofday(&tv, 0);
@@ -58,7 +57,13 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ *
 
        fprintf(slowlog, "\n%s [pool %s] pid %d\n", buf, child->wp->config->name, (int) pid);
 
-       if (0 > fpm_trace_get_strz(buf, buf_size, (long) &SG(request_info).path_translated)) {
+       if (0 > fpm_trace_get_long((long) &SG(request_info).path_translated, &l)) {
+               return -1;
+       }
+
+       path_translated = l;
+
+       if (0 > fpm_trace_get_strz(buf, buf_size, path_translated)) {
                return -1;
        }
 
@@ -72,68 +77,118 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ *
 
        while (execute_data) {
                long function;
+               long function_name;
+               long file_name;
+               long prev;
                uint lineno = 0;
 
-               fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data);
-
-               if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, function_state.function), &l)) {
+               if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, func), &l)) {
                        return -1;
                }
 
                function = l;
 
                if (valid_ptr(function)) {
-                       if (0 > fpm_trace_get_strz(buf, buf_size, function + offsetof(zend_function, common.function_name))) {
+                       if (0 > fpm_trace_get_long(function + offsetof(zend_function, common.function_name), &l)) {
                                return -1;
                        }
 
-                       fprintf(slowlog, "%s()", buf);
+                       function_name = l;
+
+                       if (function_name == 0) {
+                               uint32_t *call_info = (uint32_t *)&l;
+                               if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, This.u1.type_info), &l)) {
+                                       return -1;
+                               }
+
+                               if (ZEND_CALL_KIND_EX((*call_info) >> 24) == ZEND_CALL_TOP_CODE) {
+                                       return 0;
+                               } else if (ZEND_CALL_KIND_EX(*(call_info) >> 24) == ZEND_CALL_NESTED_CODE) {
+                                       memcpy(buf, "[INCLUDE_OR_EVAL]", sizeof("[INCLUDE_OR_EVAL]"));
+                               } else {
+                                       ZEND_ASSERT(0);
+                               }
+                       } else {
+                               if (0 > fpm_trace_get_strz(buf, buf_size, function_name + offsetof(zend_string, val))) {
+                                       return -1;
+                               }
+
+                       }
                } else {
-                       fprintf(slowlog, "???");
+                       memcpy(buf, "???", sizeof("???"));
                }
+               
+               fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data);
 
-               if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, op_array), &l)) {
+               fprintf(slowlog, "%s()", buf);
+
+               *buf = '\0';
+
+               if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) {
                        return -1;
                }
 
-               *buf = '\0';
+               execute_data = prev = l;
 
-               if (valid_ptr(l)) {
-                       long op_array = l;
+               while (prev) {
 
-                       if (0 > fpm_trace_get_strz(buf, buf_size, op_array + offsetof(zend_op_array, filename))) {
+                       if (0 > fpm_trace_get_long(prev + offsetof(zend_execute_data, func), &l)) {
                                return -1;
                        }
-               }
 
-               if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, opline), &l)) {
-                       return -1;
-               }
+                       function = l;
 
-               if (valid_ptr(l)) {
-                       long opline = l;
-                       uint *lu = (uint *) &l;
+                       if (!valid_ptr(function)) {
+                               break;
+                       }
 
-                       if (0 > fpm_trace_get_long(opline + offsetof(struct _zend_op, lineno), &l)) {
+                       if (0 > fpm_trace_get_long(function + offsetof(zend_function, type), &l)) {
                                return -1;
                        }
 
-                       lineno = *lu;
-               }
+                       /* zend_uchar? */
+                       if (ZEND_USER_CODE(l)) {
+                               if (0 > fpm_trace_get_long(function + offsetof(zend_op_array, filename), &l)) {
+                                       return -1;
+                               }
 
-               fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno);
+                               file_name = l;
 
-               if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) {
-                       return -1;
+                               if (0 > fpm_trace_get_strz(buf, buf_size, file_name + offsetof(zend_string, val))) {
+                                       return -1;
+                               }
+
+                               if (0 > fpm_trace_get_long(prev + offsetof(zend_execute_data, opline), &l)) {
+                                       return -1;
+                               }
+
+                               if (valid_ptr(l)) {
+                                       long opline = l;
+                                       uint32_t *lu = (uint32_t *) &l;
+
+                                       if (0 > fpm_trace_get_long(opline + offsetof(struct _zend_op, lineno), &l)) {
+                                               return -1;
+                                       }
+
+                                       lineno = *lu;
+                               }
+                               break;
+                       } 
+
+                       if (0 > fpm_trace_get_long(prev + offsetof(zend_execute_data, prev_execute_data), &l)) {
+                               return -1;
+                       }
+
+                       prev = l;
                }
 
-               execute_data = l;
+               fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno);
 
                if (0 == --callers_limit) {
                        break;
                }
        }
-#endif
+
        return 0;
 }
 /* }}} */
index 366af5a3fe38489adf4eae929315939616fc97d5..eae7fe9bbfc88ff24c2a2953787737339d8fd544 100644 (file)
 int fpm_trace_get_strz(char *buf, size_t sz, long addr) /* {{{ */
 {
        int i;
-       long l;
+       long l = addr;
        char *lc = (char *) &l;
 
-       if (0 > fpm_trace_get_long(addr, &l)) {
-               return -1;
-       }
-
        i = l % SIZEOF_LONG;
        l -= i;
        for (addr = l; ; addr += SIZEOF_LONG) {