1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: David Soria Parra <david.soriaparra@sun.com> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id: $ */
20
21 #include "zend.h"
22 #include "zend_API.h"
23 #include "zend_dtrace.h"
24
25 #ifdef HAVE_DTRACE
26
27 ZEND_API zend_op_array *(*zend_dtrace_compile_file)(zend_file_handle *file_handle, int type);
28 ZEND_API void (*zend_dtrace_execute)(zend_op_array *op_array);
29 ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data, zval *return_value);
30
31 /* PHP DTrace probes {{{ */
dtrace_get_executed_filename(void)32 static inline const char *dtrace_get_executed_filename(void)
33 {
34 zend_execute_data *ex = EG(current_execute_data);
35
36 while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
37 ex = ex->prev_execute_data;
38 }
39 if (ex) {
40 return ZSTR_VAL(ex->func->op_array.filename);
41 } else {
42 return zend_get_executed_filename();
43 }
44 }
45
dtrace_compile_file(zend_file_handle * file_handle,int type)46 ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type)
47 {
48 zend_op_array *res;
49 DTRACE_COMPILE_FILE_ENTRY(ZSTR_VAL(file_handle->opened_path), (char *)file_handle->filename);
50 res = compile_file(file_handle, type);
51 DTRACE_COMPILE_FILE_RETURN(ZSTR_VAL(file_handle->opened_path), (char *)file_handle->filename);
52
53 return res;
54 }
55
56 /* We wrap the execute function to have fire the execute-entry/return and function-entry/return probes */
dtrace_execute_ex(zend_execute_data * execute_data)57 ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data)
58 {
59 int lineno;
60 const char *scope, *filename, *funcname, *classname;
61 scope = filename = funcname = classname = NULL;
62
63 /* we need filename and lineno for both execute and function probes */
64 if (DTRACE_EXECUTE_ENTRY_ENABLED() || DTRACE_EXECUTE_RETURN_ENABLED()
65 || DTRACE_FUNCTION_ENTRY_ENABLED() || DTRACE_FUNCTION_RETURN_ENABLED()) {
66 filename = dtrace_get_executed_filename();
67 lineno = zend_get_executed_lineno();
68 }
69
70 if (DTRACE_FUNCTION_ENTRY_ENABLED() || DTRACE_FUNCTION_RETURN_ENABLED()) {
71 classname = get_active_class_name(&scope);
72 funcname = get_active_function_name();
73 }
74
75 if (DTRACE_EXECUTE_ENTRY_ENABLED()) {
76 DTRACE_EXECUTE_ENTRY((char *)filename, lineno);
77 }
78
79 if (DTRACE_FUNCTION_ENTRY_ENABLED() && funcname != NULL) {
80 DTRACE_FUNCTION_ENTRY((char *)funcname, (char *)filename, lineno, (char *)classname, (char *)scope);
81 }
82
83 execute_ex(execute_data);
84
85 if (DTRACE_FUNCTION_RETURN_ENABLED() && funcname != NULL) {
86 DTRACE_FUNCTION_RETURN((char *)funcname, (char *)filename, lineno, (char *)classname, (char *)scope);
87 }
88
89 if (DTRACE_EXECUTE_RETURN_ENABLED()) {
90 DTRACE_EXECUTE_RETURN((char *)filename, lineno);
91 }
92 }
93
dtrace_execute_internal(zend_execute_data * execute_data,zval * return_value)94 ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value)
95 {
96 int lineno;
97 const char *filename;
98 if (DTRACE_EXECUTE_ENTRY_ENABLED() || DTRACE_EXECUTE_RETURN_ENABLED()) {
99 filename = dtrace_get_executed_filename();
100 lineno = zend_get_executed_lineno();
101 }
102
103 if (DTRACE_EXECUTE_ENTRY_ENABLED()) {
104 DTRACE_EXECUTE_ENTRY((char *)filename, lineno);
105 }
106
107 execute_internal(execute_data, return_value);
108
109 if (DTRACE_EXECUTE_RETURN_ENABLED()) {
110 DTRACE_EXECUTE_RETURN((char *)filename, lineno);
111 }
112 }
113
114 /* }}} */
115
116 #endif /* HAVE_DTRACE */
117