8000 [Debug] Symfony debug extension · symfony/symfony@eec5c92 · GitHub
[go: up one dir, main page]

Skip to content

Commit eec5c92

Browse files
Julien Paulinicolas-grekas
Julien Pauli
authored andcommitted
[Debug] Symfony debug extension
1 parent aa59445 commit eec5c92

File tree

5 files changed

+503
-0
lines changed

5 files changed

+503
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
dnl $Id$
2+
dnl config.m4 for extension symfony_debug
3+
4+
dnl Comments in this file start with the string 'dnl'.
5+
dnl Remove where necessary. This file will not work
6+
dnl without editing.
7+
8+
dnl If your extension references something external, use with:
9+
10+
dnl PHP_ARG_WITH(symfony_debug, for symfony_debug support,
11+
dnl Make sure that the comment is aligned:
12+
dnl [ --with-symfony_debug Include symfony_debug support])
13+
14+
dnl Otherwise use enable:
15+
16+
PHP_ARG_ENABLE(symfony_debug, whether to enable symfony_debug support,
17+
dnl Make sure that the comment is aligned:
18+
[ --enable-symfony_debug Enable symfony_debug support])
19+
20+
if test "$PHP_SYMFONY_DEBUG" != "no"; then
21+
dnl Write more examples of tests here...
22+
23+
dnl # --with-symfony_debug -> check with-path
24+
dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
25+
dnl SEARCH_FOR="/include/symfony_debug.h" # you most likely want to change this
26+
dnl if test -r $PHP_SYMFONY_DEBUG/$SEARCH_FOR; then # path given as parameter
27+
dnl SYMFONY_DEBUG_DIR=$PHP_SYMFONY_DEBUG
28+
dnl else # search default path list
29+
dnl AC_MSG_CHECKING([for symfony_debug files in default path])
30+
dnl for i in $SEARCH_PATH ; do
31+
dnl if test -r $i/$SEARCH_FOR; then
32+
dnl SYMFONY_DEBUG_DIR=$i
33+
dnl AC_MSG_RESULT(found in $i)
34+
dnl fi
35+
dnl done
36+
dnl fi
37+
dnl
38+
dnl if test -z "$SYMFONY_DEBUG_DIR"; then
39+
dnl AC_MSG_RESULT([not found])
40+
dnl AC_MSG_ERROR([Please reinstall the symfony_debug distribution])
41+
dnl fi
42+
43+
dnl # --with-symfony_debug -> add include path
44+
dnl PHP_ADD_INCLUDE($SYMFONY_DEBUG_DIR/include)
45+
46+
dnl # --with-symfony_debug -> check for lib and symbol presence
47+
dnl LIBNAME=symfony_debug # you may want to change this
48+
dnl LIBSYMBOL=symfony_debug # you most likely want to change this
49+
50+
dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
51+
dnl [
52+
dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $SYMFONY_DEBUG_DIR/lib, SYMFONY_DEBUG_SHARED_LIBADD)
53+
dnl AC_DEFINE(HAVE_SYMFONY_DEBUGLIB,1,[ ])
54+
dnl ],[
55+
dnl AC_MSG_ERROR([wrong symfony_debug lib version or lib not found])
56+
dnl ],[
57+
dnl -L$SYMFONY_DEBUG_DIR/lib -lm
58+
dnl ])
59+
dnl
60+
dnl PHP_SUBST(SYMFONY_DEBUG_SHARED_LIBADD)
61+
62+
PHP_NEW_EXTENSION(symfony_debug, symfony_debug.c, $ext_shared)
63+
fi
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// $Id$
2+
// vim:ft=javascript
3+
4+
// If your extension references something external, use ARG_WITH
5+
// ARG_WITH("symfony_debug", "for symfony_debug support", "no");
6+
7+
// Otherwise, use ARG_ENABLE
8+
// ARG_ENABLE("symfony_debug", "enable symfony_debug support", "no");
9+
10+
if (PHP_SYMFONY_DEBUG != "no") {
11+
EXTENSION("symfony_debug", "symfony_debug.c");
12+
}
13+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* This file is part of the Symfony package.
3+
*
4+
* (c) Fabien Potencier <fabien@symfony.com>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
#ifndef PHP_SYMFONY_DEBUG_H
11+
#define PHP_SYMFONY_DEBUG_H
12+
13+
extern zend_module_entry symfony_debug_module_entry;
14+
#define phpext_symfony_debug_ptr &symfony_debug_module_entry
15+
16+
#define PHP_SYMFONY_DEBUG_VERSION "1.0"
17+
18+
#ifdef PHP_WIN32
19+
# define PHP_SYMFONY_DEBUG_API __declspec(dllexport)
20+
#elif defined(__GNUC__) && __GNUC__ >= 4
21+
# define PHP_SYMFONY_DEBUG_API __attribute__ ((visibility("default")))
22+
#else
23+
# define PHP_SYMFONY_DEBUG_API
24+
#endif
25+
26+
#ifdef ZTS
27+
#include "TSRM.h"
28+
#endif
29+
30+
ZEND_BEGIN_MODULE_GLOBALS(symfony_debug)
31+
intptr_t req_rand_init;
32+
ZEND_END_MODULE_GLOBALS(symfony_debug)
33+
34+
PHP_MINIT_FUNCTION(symfony_debug);
35+
PHP_MSHUTDOWN_FUNCTION(symfony_debug);
36+
PHP_RINIT_FUNCTION(symfony_debug);
37+
PHP_RSHUTDOWN_FUNCTION(symfony_debug);
38+
PHP_MINFO_FUNCTION(symfony_debug);
39+
PHP_GINIT_FUNCTION(symfony_debug);
40+
PHP_GSHUTDOWN_FUNCTION(symfony_debug);
41+
42+
PHP_FUNCTION(symfony_zval_info);
43+
44+
static char *_symfony_debug_memory_address_hash(void *);
45+
static const char *_symfony_debug_zval_type(zval *);
46+
static const char* _symfony_debug_get_resource_type(long);
47+
static int _symfony_debug_get_resource_refcount(long);
48+
49+
#ifdef ZTS
50+
#define SYMFONY_DEBUG_G(v) TSRMG(symfony_debug_globals_id, zend_symfony_debug_globals *, v)
51+
#else
52+
#define SYMFONY_DEBUG_G(v) (symfony_debug_globals.v)
53+
#endif
54+
55+
#endif /* PHP_SYMFONY_DEBUG_H */
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/*
2+
* This file is part of the Symfony package.
3+
*
4+
* (c) Fabien Potencier <fabien@symfony.com>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
#ifdef HAVE_CONFIG_H
11+
#include "config.h"
12+
#endif
13+
14+
#include "php.h"
15+
#include "php_ini.h"
16+
#include "ext/standard/info.h"
17+
#include "php_symfony_debug.h"
18+
#include "ext/standard/php_rand.h"
19+
#include "ext/standard/php_lcg.h"
20+
#include "ext/spl/php_spl.h"
21+
#include "Zend/zend_gc.h"
22+
23+
ZEND_DECLARE_MODULE_GLOBALS(symfony_debug)
24+
25+
ZEND_BEGIN_ARG_INFO_EX(symfony_zval_arginfo, 0, 0, 2)
26+
ZEND_ARG_INFO(0, key)
27+
ZEND_ARG_ARRAY_INFO(0, array, 0)
28+
ZEND_ARG_INFO(0, options)
29+
ZEND_END_ARG_INFO()
30+
31+
const zend_function_entry symfony_debug_functions[] = {
32+
PHP_FE(symfony_zval_info, symfony_zval_arginfo)
33+
PHP_FE_END
34+
};
35+
36+
PHP_FUNCTION(symfony_zval_info)
37+
{
38+
zval *key = NULL, *arg = NULL;
39+
zval **data = NULL;
40+
HashTable *array = NULL;
41+
long options = 0;
42+
43+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zh|l", &key, &array, &options) == FAILURE) {
44+
return;
45+
}
46+
47+
switch (Z_TYPE_P(key)) {
48+
case IS_STRING:
49+
if (zend_symtable_find(array, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&data) == FAILURE) {
50+
return;
51+
}
52+
break;
53+
case IS_LONG:
54+
if (zend_hash_index_find(array, Z_LVAL_P(key), (void **)&data)) {
55+
return;
56+
}
57+
break;
58+
}
59+
60+
arg = *data;
61+
62+
array_init(return_value);
63+
64+
add_assoc_string(return_value, "type", (char *)_symfony_debug_zval_type(arg), 1);
65+
add_assoc_stringl(return_value, "zval_hash", _symfony_debug_memory_address_hash((void *)arg), 16, 1);
66+
add_assoc_long(return_value, "zval_refcount", Z_REFCOUNT_P(arg));
67+
add_assoc_bool(return_value, "zval_isref", (zend_bool)Z_ISREF_P(arg));
68+
69+
if (Z_TYPE_P(arg) == IS_OBJECT) {
70+
static char hash[33] = {0};
71+
php_spl_object_hash(arg, (char *)hash);
72+
add_assoc_stringl(return_value, "object_class", (char *)Z_OBJCE_P(arg)->name, Z_OBJCE_P(arg)->name_length, 1);
73+
add_assoc_long(return_value, "object_refcount", EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(arg)].bucket.obj.refcount);
74+
add_assoc_string(return_value, "object_hash", hash, 1);
75+
} else if (Z_TYPE_P(arg) == IS_ARRAY) {
76+
add_assoc_long(return_value, "array_count", zend_hash_num_elements(Z_ARRVAL_P(arg)));
77+
} else if(Z_TYPE_P(arg) == IS_RESOURCE) {
78+
add_assoc_long(return_value, "resource_id", Z_LVAL_P(arg));
79+
add_assoc_string(return_value, "resource_type", (char *)_symfony_debug_get_resource_type(Z_LVAL_P(arg)), 1);
80+
add_assoc_long(return_value, "resource_refcount", _symfony_debug_get_resource_refcount(Z_LVAL_P(arg)));
81+
} else if (Z_TYPE_P(arg) == IS_STRING) {
82+
add_assoc_long(return_value, "strlen", Z_STRLEN_P(arg));
83+
}
84+
}
85+
86+
static const char* _symfony_debug_get_resource_type(long rsid)
87+
{
88+
const char *res_type;
89+
res_type = zend_rsrc_list_get_rsrc_type(rsid);
90+
91+
if (!res_type) {
92+
return "Unknown";
93+
}
94+
95+
return res_type;
96+
}
97+
98+
static int _symfony_debug_get_resource_refcount(long rsid)
99+
{
100+
zend_rsrc_list_entry *le;
101+
102+
if (zend_hash_index_find(&EG(regular_list), rsid, (void **) &le)==SUCCESS) {
103+
return le->refcount;
104+
}
105+
106+
return 0;
107+
}
108+
109+
static char *_symfony_debug_memory_address_hash(void *address)
110+
{
111+
static char result[17] = {0};
112+
intptr_t address_rand;
113+
114+
if (!SYMFONY_DEBUG_G(req_rand_init)) {
115+
if (!BG(mt_rand_is_seeded)) {
116+
php_mt_srand(GENERATE_SEED() TSRMLS_CC);
117+
}
118+
SYMFONY_DEBUG_G(req_rand_init) = (intptr_t)php_mt_rand();
119+
}
120+
121+
address_rand = (intptr_t)address ^ SYMFONY_DEBUG_G(req_rand_init);
122+
123+
snprintf(result, 17, "%016zx", address_rand);
124+
125+
return result;
126+
}
127+
128+
static const char *_symfony_debug_zval_type(zval *zv)
129+
{
130+
switch (Z_TYPE_P(zv)) {
131+
case IS_NULL:
132+
return "NULL";
133+
break;
134+
135+
case IS_BOOL:
136+
return "boolean";
137+
break;
138+
139+
case IS_LONG:
140+
return "integer";
141+
break;
142+
143+
case IS_DOUBLE:
144+
return "double";
145+
break;
146+
147+
case IS_STRING:
148+
return "string";
149+
break;
150+
151+
case IS_ARRAY:
152+
return "array";
153+
break;
154+
155+
case IS_OBJECT:
156+
return "object";
157+
158+
case IS_RESOURCE:
159+
return "resource";
160+
161+
default:
162+
return "unknown type";
163+
}
164+
}
165+
166+
zend_module_entry symfony_debug_module_entry = {
167+
STANDARD_MODULE_HEADER,
168+
"symfony_debug",
169+
symfony_debug_functions,
170+
PHP_MINIT(symfony_debug),
171+
PHP_MSHUTDOWN(symfony_debug),
172+
PHP_RINIT(symfony_debug),
173+
PHP_RSHUTDOWN(symfony_debug),
174+
PHP_MINFO(symfony_debug),
175+
PHP_SYMFONY_DEBUG_VERSION,
176+
PHP_MODULE_GLOBALS(symfony_debug),
177+
PHP_GINIT(symfony_debug),
178+
PHP_GSHUTDOWN(symfony_debug),
179+
NULL,
180+
STANDARD_MODULE_PROPERTIES_EX
181+
};
182+
183+
#ifdef COMPILE_DL_SYMFONY_DEBUG
184+
ZEND_GET_MODULE(symfony_debug)
185+
#endif
186+
187+
PHP_GINIT_FUNCTION(symfony_debug)
188+
{
189+
symfony_debug_globals->req_rand_init = 0;
190+
}
191+
192+
PHP_GSHUTDOWN_FUNCTION(symfony_debug)
193+
{
194+
195+
}
196+
197+
PHP_MINIT_FUNCTION(symfony_debug)
198+
{
199+
return SUCCESS;
200+
}
201+
202+
PHP_MSHUTDOWN_FUNCTION(symfony_debug)
203+
{
204+
return SUCCESS;
205+
}
206+
207+
PHP_RINIT_FUNCTION(symfony_debug)
208+
{
209+
return SUCCESS;
210+
}
211+
212+
PHP_RSHUTDOWN_FUNCTION(symfony_debug)
213+
{
214+
return SUCCESS;
215+
}
216+
217+
PHP_MINFO_FUNCTION(symfony_debug)
218+
{
219+
php_info_print_table_start();
220+
php_info_print_table_header(2, "Symfony Debug support", "enabled");
221+
php_info_print_table_header(2, "Symfony Debug version", PHP_SYMFONY_DEBUG_VERSION);
222+
php_info_print_table_end();
223+
}

0 commit comments

Comments
 (0)
0