@@ -121,6 +121,7 @@ zend_bool fallback_process = 0; /* process uses file cache fallback */
121
121
static zend_op_array * (* accelerator_orig_compile_file )(zend_file_handle * file_handle , int type );
122
122
static int (* accelerator_orig_zend_stream_open_function )(const char * filename , zend_file_handle * handle );
123
123
static zend_string * (* accelerator_orig_zend_resolve_path )(const char * filename , size_t filename_len );
124
+ static void (* accelerator_orig_zend_error_cb )(int type , const char * error_filename , const uint32_t error_lineno , const char * format , va_list args );
124
125
static zif_handler orig_chdir = NULL ;
125
126
static ZEND_INI_MH ((* orig_include_path_on_modify )) = NULL ;
126
127
static int (* orig_post_startup_cb )(void );
@@ -1661,6 +1662,56 @@ static void zend_accel_init_auto_globals(void)
1661
1662
}
1662
1663
}
1663
1664
1665
+ static void persistent_error_cb (int type , const char * error_filename , const uint32_t error_lineno , const char * format , va_list args ) {
1666
+ if (ZCG (record_warnings )) {
1667
+ zend_recorded_warning * warning = emalloc (sizeof (zend_recorded_warning ));
1668
+ va_list args_copy ;
1669
+ warning -> type = type ;
1670
+ warning -> error_lineno = error_lineno ;
1671
+ warning -> error_filename = zend_string_init (error_filename , strlen (error_filename ), 0 );
1672
+ va_copy (args_copy , args );
1673
+ warning -> error_message = zend_vstrpprintf (0 , format , args_copy );
1674
+ va_end (args_copy );
1675
+
1676
+ ZCG (num_warnings )++ ;
1677
+ ZCG (warnings ) = erealloc (ZCG (warnings ), sizeof (zend_recorded_warning ) * ZCG (num_warnings ));
1678
+ ZCG (warnings )[ZCG (num_warnings )- 1 ] = warning ;
1679
+ }
1680
+ accelerator_orig_zend_error_cb (type , error_filename , error_lineno , format , args );
1681
+ }
1682
+
1683
+ /* Hack to get us a va_list to pass to zend_error_cb. */
1684
+ static void replay_warning_helper (const zend_recorded_warning * warning , ...) {
1685
+ va_list va ;
1686
+ va_start (va , warning );
1687
+ accelerator_orig_zend_error_cb (
1688
+ warning -> type , ZSTR_VAL (warning -> error_filename ), warning -> error_lineno , "%s" , va );
1689
+ va_end (va );
1690
+ }
1691
+
1692
+ static void replay_warnings (zend_persistent_script * script ) {
1693
+ for (uint32_t i = 0 ; i < script -> num_warnings ; i ++ ) {
1694
+ zend_recorded_warning * warning = script -> warnings [i ];
1695
+ replay_warning_helper (warning , ZSTR_VAL (warning -> error_message ));
1696
+ }
1697
+ }
1698
+
1699
+ static void free_recorded_warnings () {
1700
+ if (!ZCG (num_warnings )) {
1701
+ return ;
1702
+ }
1703
+
1704
+ for (uint32_t i = 0 ; i < ZCG (num_warnings ); i ++ ) {
1705
+ zend_recorded_warning * warning = ZCG (warnings )[i ];
1706
+ zend_string_release (warning -> error_filename );
1707
+ zend_string_release (warning -> error_message );
1708
+ efree (warning );
1709
+ }
1710
+ efree (ZCG (warnings ));
1711
+ ZCG (warnings ) = NULL ;
1712
+ ZCG (num_warnings ) = 0 ;
1713
+ }
1714
+
1664
1715
static zend_persistent_script * opcache_compile_file (zend_file_handle * file_handle , int type , const char * key , zend_op_array * * op_array_p )
1665
1716
{
1666
1717
zend_persistent_script * new_persistent_script ;
@@ -1739,6 +1790,9 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
1739
1790
1740
1791
/* Override them with ours */
1741
1792
ZVAL_UNDEF (& EG (user_error_handler ));
1793
+ ZCG (record_warnings ) = ZCG (accel_directives ).record_warnings ;
1794
+ ZCG (num_warnings ) = 0 ;
1795
+ ZCG (warnings ) = NULL ;
1742
1796
1743
1797
zend_try {
1744
1798
orig_compiler_options = CG (compiler_options );
@@ -1761,9 +1815,11 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
1761
1815
/* Restore originals */
1762
1816
CG (active_op_array ) = orig_active_op_array ;
1763
1817
EG (user_error_handler ) = orig_user_error_handler ;
1818
+ ZCG (record_warnings ) = 0 ;
1764
1819
1765
1820
if (!op_array ) {
1766
1821
/* compilation failed */
1822
+ free_recorded_warnings ();
1767
1823
if (do_bailout ) {
1768
1824
zend_bailout ();
1769
1825
}
@@ -1782,6 +1838,10 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
1782
1838
(op_array -> fn_flags & ZEND_ACC_EARLY_BINDING ) ?
1783
1839
zend_build_delayed_early_binding_list (op_array ) :
1784
1840
(uint32_t )-1 ;
1841
+ new_persistent_script -> num_warnings = ZCG (num_warnings );
1842
+ new_persistent_script -> warnings = ZCG (warnings );
1843
+ ZCG (num_warnings ) = 0 ;
1844
+ ZCG (warnings ) = NULL ;
1785
1845
1786
1846
efree (op_array ); /* we have valid persistent_script, so it's safe to free op_array */
1787
1847
@@ -1866,6 +1926,7 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
1866
1926
}
1867
1927
}
1868
1928
}
1929
+ replay_warnings (persistent_script );
1869
1930
zend_file_handle_dtor (file_handle );
1870
1931
1871
1932
if (persistent_script -> ping_auto_globals_mask ) {
@@ -2187,6 +2248,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
2187
2248
}
2188
2249
}
2189
2250
}
2251
+ replay_warnings (persistent_script );
2190
2252
zend_file_handle_dtor (file_handle );
2191
2253
from_shared_memory = 1 ;
2192
2254
}
@@ -3051,6 +3113,10 @@ static int accel_post_startup(void)
3051
3113
accelerator_orig_zend_resolve_path = zend_resolve_path ;
3052
3114
zend_resolve_path = persistent_zend_resolve_path ;
3053
3115
3116
+ /* Override error callback, so we can store errors that occur during compilation */
3117
+ accelerator_orig_zend_error_cb = zend_error_cb ;
3118
+ zend_error_cb = persistent_error_cb ;
3119
+
3054
3120
/* Override chdir() function */
3055
3121
if ((func = zend_hash_str_find_ptr (CG (function_table ), "chdir" , sizeof ("chdir" )- 1 )) != NULL &&
3056
3122
func -> type == ZEND_INTERNAL_FUNCTION ) {
0 commit comments