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

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit eec5c92

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

File tree

5 files chang 8000 ed

+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