@@ -75,6 +75,7 @@ PHP_INI_END()
7575
7676static zend_bool phpdbg_booted = 0 ;
7777static zend_bool phpdbg_fully_started = 0 ;
78+ zend_bool use_mm_wrappers = 0 ;
7879
7980static inline void php_phpdbg_globals_ctor (zend_phpdbg_globals * pg ) /* {{{ */
8081{
@@ -189,79 +190,27 @@ static void php_phpdbg_destroy_registered(zval *data) /* {{{ */
189190 destroy_zend_function (function );
190191} /* }}} */
191192
193+ static void php_phpdbg_destroy_file_source (zval * data ) /* {{{ */
194+ {
195+ phpdbg_file_source * source = (phpdbg_file_source * ) Z_PTR_P (data );
196+ destroy_op_array (& source -> op_array );
197+ if (source -> buf ) {
198+ efree (source -> buf );
199+ }
200+ efree (source );
201+ } /* }}} */
202+
192203
193204static PHP_RINIT_FUNCTION (phpdbg ) /* {{{ */
194205{
195- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE ], 8 , NULL , php_phpdbg_destroy_bp_file , 0 );
196- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_PENDING ], 8 , NULL , php_phpdbg_destroy_bp_file , 0 );
197- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_SYM ], 8 , NULL , php_phpdbg_destroy_bp_symbol , 0 );
198- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FUNCTION_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
199- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
200- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
201- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_opline , 0 );
202- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_OPCODE ], 8 , NULL , php_phpdbg_destroy_bp_opcode , 0 );
203- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
204- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_COND ], 8 , NULL , php_phpdbg_destroy_bp_condition , 0 );
205- zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_MAP ], 8 , NULL , NULL , 0 );
206-
207- zend_hash_init (& PHPDBG_G (seek ), 8 , NULL , NULL , 0 );
208- zend_hash_init (& PHPDBG_G (registered ), 8 , NULL , php_phpdbg_destroy_registered , 0 );
206+ /* deactivate symbol table caching to have these properly destroyed upon stack leaving (especially important for watchpoints) */
207+ EG (symtable_cache_limit ) = EG (symtable_cache ) - 1 ;
209208
210209 return SUCCESS ;
211210} /* }}} */
212211
213212static PHP_RSHUTDOWN_FUNCTION (phpdbg ) /* {{{ */
214213{
215- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE ]);
216- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_PENDING ]);
217- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_SYM ]);
218- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FUNCTION_OPLINE ]);
219- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD_OPLINE ]);
220- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_OPLINE ]);
221- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_OPLINE ]);
222- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_OPCODE ]);
223- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD ]);
224- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_COND ]);
225- zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_MAP ]);
226- zend_hash_destroy (& PHPDBG_G (file_sources ));
227- zend_hash_destroy (& PHPDBG_G (seek ));
228- zend_hash_destroy (& PHPDBG_G (registered ));
229- zend_hash_destroy (& PHPDBG_G (watchpoints ));
230- zend_llist_destroy (& PHPDBG_G (watchlist_mem ));
231-
232- if (PHPDBG_G (buffer )) {
233- free (PHPDBG_G (buffer ));
234- PHPDBG_G (buffer ) = NULL ;
235- }
236-
237- if (PHPDBG_G (exec )) {
238- efree (PHPDBG_G (exec ));
239- PHPDBG_G (exec ) = NULL ;
240- }
241-
242- if (PHPDBG_G (oplog )) {
243- fclose (PHPDBG_G (oplog ));
244- PHPDBG_G (oplog ) = NULL ;
245- }
246-
247- if (PHPDBG_G (ops )) {
248- destroy_op_array (PHPDBG_G (ops ));
249- efree (PHPDBG_G (ops ));
250- PHPDBG_G (ops ) = NULL ;
251- }
252-
253- if (PHPDBG_G (oplog_list )) {
254- phpdbg_oplog_list * cur = PHPDBG_G (oplog_list );
255- do {
256- phpdbg_oplog_list * prev = cur -> prev ;
257- efree (cur );
258- cur = prev ;
259- } while (cur != NULL );
260-
261- zend_arena_destroy (PHPDBG_G (oplog_arena ));
262- PHPDBG_G (oplog_list ) = NULL ;
263- }
264-
265214 return SUCCESS ;
266215} /* }}} */
267216
@@ -845,8 +794,86 @@ static void php_sapi_phpdbg_log_message(char *message, int syslog_type_int) /* {
845794}
846795/* }}} */
847796
797+ static int php_sapi_phpdbg_activate (void ) /* {{{ */
798+ {
799+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE ], 8 , NULL , php_phpdbg_destroy_bp_file , 0 );
800+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_PENDING ], 8 , NULL , php_phpdbg_destroy_bp_file , 0 );
801+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_SYM ], 8 , NULL , php_phpdbg_destroy_bp_symbol , 0 );
802+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FUNCTION_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
803+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
804+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
805+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_OPLINE ], 8 , NULL , php_phpdbg_destroy_bp_opline , 0 );
806+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_OPCODE ], 8 , NULL , php_phpdbg_destroy_bp_opcode , 0 );
807+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD ], 8 , NULL , php_phpdbg_destroy_bp_methods , 0 );
808+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_COND ], 8 , NULL , php_phpdbg_destroy_bp_condition , 0 );
809+ zend_hash_init (& PHPDBG_G (bp )[PHPDBG_BREAK_MAP ], 8 , NULL , NULL , 0 );
810+
811+ zend_hash_init (& PHPDBG_G (seek ), 8 , NULL , NULL , 0 );
812+ zend_hash_init (& PHPDBG_G (registered ), 8 , NULL , php_phpdbg_destroy_registered , 0 );
813+
814+ zend_hash_init (& PHPDBG_G (file_sources ), 0 , NULL , php_phpdbg_destroy_file_source , 0 );
815+ phpdbg_setup_watchpoints ();
816+
817+ return SUCCESS ;
818+ }
819+
848820static int php_sapi_phpdbg_deactivate (void ) /* {{{ */
849821{
822+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE ]);
823+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_PENDING ]);
824+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_SYM ]);
825+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FUNCTION_OPLINE ]);
826+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD_OPLINE ]);
827+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_FILE_OPLINE ]);
828+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_OPLINE ]);
829+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_OPCODE ]);
830+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_METHOD ]);
831+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_COND ]);
832+ zend_hash_destroy (& PHPDBG_G (bp )[PHPDBG_BREAK_MAP ]);
833+ zend_hash_destroy (& PHPDBG_G (file_sources ));
834+ zend_hash_destroy (& PHPDBG_G (seek ));
835+ zend_hash_destroy (& PHPDBG_G (registered ));
836+ phpdbg_destroy_watchpoints ();
837+
838+ /* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
839+ if (use_mm_wrappers ) {
840+ /* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
841+ * (int * ) zend_mm_get_heap () = 0 ;
842+ }
843+
844+ if (PHPDBG_G (buffer )) {
845+ free (PHPDBG_G (buffer ));
846+ PHPDBG_G (buffer ) = NULL ;
847+ }
848+
849+ if (PHPDBG_G (exec )) {
850+ efree (PHPDBG_G (exec ));
851+ PHPDBG_G (exec ) = NULL ;
852+ }
853+
854+ if (PHPDBG_G (oplog )) {
855+ fclose (PHPDBG_G (oplog ));
856+ PHPDBG_G (oplog ) = NULL ;
857+ }
858+
859+ if (PHPDBG_G (ops )) {
860+ destroy_op_array (PHPDBG_G (ops ));
861+ efree (PHPDBG_G (ops ));
862+ PHPDBG_G (ops ) = NULL ;
863+ }
864+
865+ if (PHPDBG_G (oplog_list )) {
866+ phpdbg_oplog_list * cur = PHPDBG_G (oplog_list );
867+ do {
868+ phpdbg_oplog_list * prev = cur -> prev ;
869+ efree (cur );
870+ cur = prev ;
871+ } while (cur != NULL );
872+
873+ zend_arena_destroy (PHPDBG_G (oplog_arena ));
874+ PHPDBG_G (oplog_list ) = NULL ;
875+ }
876+
850877 fflush (stdout );
851878 if (SG (request_info ).argv0 ) {
852879 free (SG (request_info ).argv0 );
@@ -994,7 +1021,7 @@ static sapi_module_struct phpdbg_sapi_module = {
9941021 php_sapi_phpdbg_module_startup , /* startup */
9951022 php_module_shutdown_wrapper , /* shutdown */
9961023
997- NULL , /* activate */
1024+ php_sapi_phpdbg_activate , /* activate */
9981025 php_sapi_phpdbg_deactivate , /* deactivate */
9991026
10001027 php_sapi_phpdbg_ub_write , /* unbuffered write */
@@ -1236,11 +1263,11 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
12361263 switch (sig ) {
12371264 case SIGBUS :
12381265 case SIGSEGV :
1239- if (PHPDBG_G (sigsegv_bailout )) {
1240- LONGJMP (* PHPDBG_G (sigsegv_bailout ), FAILURE );
1241- }
12421266 is_handled = phpdbg_watchpoint_segfault_handler (info , context );
12431267 if (is_handled == FAILURE ) {
1268+ if (PHPDBG_G (sigsegv_bailout )) {
1269+ LONGJMP (* PHPDBG_G (sigsegv_bailout ), FAILURE );
1270+ }
12441271 zend_sigaction (sig , & PHPDBG_G (old_sigsegv_signal ), NULL );
12451272 }
12461273 break ;
@@ -1308,7 +1335,6 @@ int main(int argc, char **argv) /* {{{ */
13081335 FILE * stream = NULL ;
13091336 char * print_opline_func ;
13101337 zend_bool ext_stmt = 0 ;
1311- zend_bool use_mm_wrappers = 0 ;
13121338 zend_bool is_exit ;
13131339 int exit_status ;
13141340
@@ -1635,8 +1661,6 @@ int main(int argc, char **argv) /* {{{ */
16351661
16361662 use_mm_wrappers = !_malloc && !_realloc && !_free ;
16371663
1638- phpdbg_init_list ();
1639-
16401664 PHPDBG_G (original_free_function ) = _free ;
16411665 _free = phpdbg_watch_efree ;
16421666
@@ -1650,14 +1674,14 @@ int main(int argc, char **argv) /* {{{ */
16501674 zend_mm_set_custom_handlers (mm_heap , _malloc , _free , _realloc );
16511675 }
16521676
1653- phpdbg_setup_watchpoints ();
1654-
16551677#if defined(ZEND_SIGNALS ) && !defined(_WIN32 )
16561678 zend_try {
16571679 zend_signal_activate ();
16581680 } zend_end_try ();
16591681#endif
16601682
1683+ phpdbg_init_list ();
1684+
16611685 PHPDBG_G (sapi_name_ptr ) = sapi_name ;
16621686
16631687 if (exec ) { /* set execution context */
@@ -1976,11 +2000,6 @@ int main(int argc, char **argv) /* {{{ */
19762000 }
19772001 }
19782002
1979- /* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
1980- if (use_mm_wrappers ) {
1981- /* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
1982- * (int * ) mm_heap = 0 ;
1983- }
19842003 zend_try {
19852004 php_request_shutdown (NULL );
19862005 } zend_end_try ();
0 commit comments