9
9
#include "ext/standard/php_string.h"
10
10
11
11
#include "zend_extensions.h"
12
- #include "zend_exceptions.h"
13
12
#include "Zend/zend_compile.h"
14
13
14
+ #if PHP_VERSION_ID >= 80100
15
+ #include "zend_fibers.h"
16
+ #endif
17
+
15
18
#include "zend.h"
16
19
#include "SAPI.h"
17
20
#include "zend_API.h"
@@ -32,6 +35,8 @@ const zend_function_entry meminfo_functions[] = {
32
35
};
33
36
#endif
34
37
38
+ static void meminfo_visit_exec_frame (php_stream * stream , HashTable * visited_items , zend_execute_data * current_execute_data , int * first_element );
39
+
35
40
zend_module_entry meminfo_module_entry = {
36
41
STANDARD_MODULE_HEADER ,
37
42
"meminfo" ,
@@ -88,38 +93,51 @@ PHP_FUNCTION(meminfo_dump)
88
93
/**
89
94
* Go through all exec frames to gather declared variables and follow them to record items in memory
90
95
*/
91
- void meminfo_browse_exec_frames (php_stream * stream , HashTable * visited_items , int * first_element )
92
- {
93
- zend_execute_data * exec_frame , * prev_frame ;
94
- zend_array * p_symbol_table ;
96
+ void meminfo_browse_exec_frames (php_stream * stream , HashTable * visited_items , int * first_element ) {
97
+ zend_execute_data * exec_frame ;
95
98
96
99
exec_frame = EG (current_execute_data );
97
100
98
- char frame_label [500 ];
101
+ // exec_frame->prev_execute_data Skipping the frame of the meminfo_dump() function call
102
+ meminfo_visit_exec_frame (stream , visited_items , exec_frame -> prev_execute_data , first_element );
99
103
100
- // Skipping the frame of the meminfo_dump() function call
101
- exec_frame = exec_frame -> prev_execute_data ;
104
+ EG (current_execute_data ) = exec_frame ;
105
+ }
106
+
107
+ static void meminfo_visit_exec_frame (php_stream * stream , HashTable * visited_items , zend_execute_data * current_execute_data , int * first_element )
108
+ {
109
+ zend_execute_data * exec_frame ;
110
+ zend_array * p_symbol_table ;
111
+
112
+ char frame_label [500 ];
113
+ char ptr_identifier [17 ];
114
+ exec_frame = current_execute_data ;
102
115
103
116
while (exec_frame ) {
117
+ sprintf (ptr_identifier , "%p" , exec_frame );
118
+ if (meminfo_visit_item (ptr_identifier , visited_items )) {
119
+ goto handle_next ;
120
+ }
121
+
104
122
// Switch the active frame to the current browsed one and rebuild the symbol table
105
123
// to get it right
106
124
EG (current_execute_data ) = exec_frame ;
107
125
108
126
// copy variables from ex->func->op_array.vars into the symbol table for the last called *user* function
109
- // therefore it does necessary returns the symbol table of the current frame
127
+ // therefore it does necessary returns the symbol table of the current frame
110
128
p_symbol_table = zend_rebuild_symbol_table ();
111
129
112
130
if (p_symbol_table != NULL ) {
113
-
114
131
if (exec_frame -> prev_execute_data ) {
115
132
meminfo_build_frame_label (frame_label , sizeof (frame_label ), exec_frame );
116
133
} else {
117
134
snprintf (frame_label , sizeof (frame_label ), "<GLOBAL>" );
118
135
}
119
136
120
137
meminfo_browse_zvals_from_symbol_table (stream , frame_label , p_symbol_table , visited_items , first_element );
121
-
122
138
}
139
+
140
+ handle_next :
123
141
exec_frame = exec_frame -> prev_execute_data ;
124
142
}
125
143
}
@@ -360,11 +378,13 @@ void meminfo_zval_dump(php_stream * stream, char * frame_label, zend_string * sy
360
378
361
379
if (Z_TYPE_P (zv ) == IS_OBJECT ) {
362
380
HashTable * properties ;
363
- zend_string * escaped_class_name ;
381
+ zend_string * escaped_class_name ;
382
+ zend_string * class_name ;
364
383
365
384
properties = NULL ;
385
+ class_name = Z_OBJCE_P (zv )-> name ;
366
386
367
- escaped_class_name = meminfo_escape_for_json (ZSTR_VAL (Z_OBJCE_P ( zv ) -> name ));
387
+ escaped_class_name = meminfo_escape_for_json (ZSTR_VAL (class_name ));
368
388
369
389
php_stream_printf (stream , ",\n" );
370
390
php_stream_printf (stream , " \"class\" : \"%s\",\n" , ZSTR_VAL (escaped_class_name ));
@@ -392,6 +412,16 @@ void meminfo_zval_dump(php_stream * stream, char * frame_label, zend_string * sy
392
412
}
393
413
#endif
394
414
}
415
+
416
+ #if PHP_VERSION_ID >= 80100
417
+ if (strcmp (ZSTR_VAL (class_name ), "Fiber" ) == 0 ) {
418
+ zend_object * object = Z_OBJ_P (zv );
419
+ zend_fiber * fiber = (zend_fiber * ) object ;
420
+ if (fiber -> execute_data ) {
421
+ meminfo_visit_exec_frame (stream , visited_items , fiber -> execute_data , first_element );
422
+ }
423
+ }
424
+ #endif
395
425
} else if (Z_TYPE_P (zv ) == IS_ARRAY ) {
396
426
php_stream_printf (stream , ",\n" );
397
427
meminfo_hash_dump (stream , Z_ARRVAL_P (zv ), 0 , visited_items , first_element );
0 commit comments