99#include "ext/standard/php_string.h"
1010
1111#include "zend_extensions.h"
12- #include "zend_exceptions.h"
1312#include "Zend/zend_compile.h"
1413
14+ #if PHP_VERSION_ID >= 80100
15+ #include "zend_fibers.h"
16+ #endif
17+
1518#include "zend.h"
1619#include "SAPI.h"
1720#include "zend_API.h"
@@ -32,6 +35,8 @@ const zend_function_entry meminfo_functions[] = {
3235};
3336#endif
3437
38+ static void meminfo_visit_exec_frame (php_stream * stream , HashTable * visited_items , zend_execute_data * current_execute_data , int * first_element );
39+
3540zend_module_entry meminfo_module_entry = {
3641 STANDARD_MODULE_HEADER ,
3742 "meminfo" ,
@@ -88,38 +93,51 @@ PHP_FUNCTION(meminfo_dump)
8893/**
8994 * Go through all exec frames to gather declared variables and follow them to record items in memory
9095 */
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 ;
9598
9699 exec_frame = EG (current_execute_data );
97100
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 );
99103
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 ;
102115
103116 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+
104122 // Switch the active frame to the current browsed one and rebuild the symbol table
105123 // to get it right
106124 EG (current_execute_data ) = exec_frame ;
107125
108126 // 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
110128 p_symbol_table = zend_rebuild_symbol_table ();
111129
112130 if (p_symbol_table != NULL ) {
113-
114131 if (exec_frame -> prev_execute_data ) {
115132 meminfo_build_frame_label (frame_label , sizeof (frame_label ), exec_frame );
116133 } else {
117134 snprintf (frame_label , sizeof (frame_label ), "<GLOBAL>" );
118135 }
119136
120137 meminfo_browse_zvals_from_symbol_table (stream , frame_label , p_symbol_table , visited_items , first_element );
121-
122138 }
139+
140+ handle_next :
123141 exec_frame = exec_frame -> prev_execute_data ;
124142 }
125143}
@@ -360,11 +378,13 @@ void meminfo_zval_dump(php_stream * stream, char * frame_label, zend_string * sy
360378
361379 if (Z_TYPE_P (zv ) == IS_OBJECT ) {
362380 HashTable * properties ;
363- zend_string * escaped_class_name ;
381+ zend_string * escaped_class_name ;
382+ zend_string * class_name ;
364383
365384 properties = NULL ;
385+ class_name = Z_OBJCE_P (zv )-> name ;
366386
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 ));
368388
369389 php_stream_printf (stream , ",\n" );
370390 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
392412 }
393413#endif
394414 }
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
395425 } else if (Z_TYPE_P (zv ) == IS_ARRAY ) {
396426 php_stream_printf (stream , ",\n" );
397427 meminfo_hash_dump (stream , Z_ARRVAL_P (zv ), 0 , visited_items , first_element );
0 commit comments