@@ -1546,6 +1546,10 @@ static PHP_MINIT_FUNCTION(ddtrace) {
15461546 ddtrace_minit_remote_config ();
15471547 ddtrace_trace_source_minit ();
15481548
1549+ #ifndef _WIN32
1550+ ddtrace_signals_minit ();
1551+ #endif
1552+
15491553 return SUCCESS ;
15501554}
15511555
@@ -1580,8 +1584,11 @@ static PHP_MSHUTDOWN_FUNCTION(ddtrace) {
15801584 if (ddtrace_coms_flush_shutdown_writer_synchronous ()) {
15811585 ddtrace_coms_curl_shutdown ();
15821586 }
1583- }
1587+ } else /* ! part of the if outside the ifdef */
15841588#endif
1589+ if (get_global_DD_TRACE_FORCE_FLUSH_ON_SHUTDOWN () && ddtrace_sidecar ) {
1590+ ddog_sidecar_flush_traces (& ddtrace_sidecar );
1591+ }
15851592
15861593 ddtrace_log_mshutdown ();
15871594
@@ -1775,8 +1782,8 @@ static void dd_clean_globals(void) {
17751782#endif
17761783}
17771784
1778- static void dd_shutdown_hooks_and_observer (void ) {
1779- zai_hook_clean ();
1785+ static void dd_shutdown_hooks_and_observer (bool fast_shutdown ) {
1786+ zai_hook_clean (fast_shutdown );
17801787
17811788#if PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80200
17821789#if PHP_VERSION_ID < 80100
@@ -1797,7 +1804,7 @@ static void dd_shutdown_hooks_and_observer(void) {
17971804#endif
17981805}
17991806
1800- void dd_force_shutdown_tracing (void ) {
1807+ void dd_force_shutdown_tracing (bool fast_shutdown ) {
18011808 DDTRACE_G (in_shutdown ) = true;
18021809
18031810 zend_try {
@@ -1807,7 +1814,7 @@ void dd_force_shutdown_tracing(void) {
18071814 } zend_end_try ();
18081815
18091816 zend_try {
1810- if (ddtrace_flush_tracer (false, true) == FAILURE ) {
1817+ if (ddtrace_flush_tracer (false, true, fast_shutdown ) == FAILURE ) {
18111818 LOG (WARN , "Unable to flush the tracer" );
18121819 }
18131820 } zend_catch {
@@ -1818,7 +1825,7 @@ void dd_force_shutdown_tracing(void) {
18181825 ddtrace_disable_tracing_in_current_request (); // implicitly calling dd_clean_globals
18191826
18201827 // The hooks shall not be reset, just disabled at runtime.
1821- dd_shutdown_hooks_and_observer ();
1828+ dd_shutdown_hooks_and_observer (fast_shutdown );
18221829
18231830 DDTRACE_G (in_shutdown ) = false;
18241831}
@@ -1832,16 +1839,31 @@ static void dd_finalize_sidecar_lifecycle(bool clear_id) {
18321839static PHP_RSHUTDOWN_FUNCTION (ddtrace ) {
18331840 UNUSED (module_number , type );
18341841
1842+ // We deliberately select to not free some data structures, as to avoid the overhead of freeing them.
1843+ // Just proper destruction can have significant and easily measurable overhead on applications.
1844+ // Prior to PHP 7.2 fast shutdown was an opcache only feature
1845+ #if ZEND_DEBUG || PHP_VERSION_ID < 70200
1846+ bool fast_shutdown = 0 ;
1847+ #elif defined(__SANITIZE_ADDRESS__ )
1848+ char * force_fast_shutdown = getenv ("ZEND_ASAN_FORCE_FAST_SHUTDOWN" );
1849+ bool fast_shutdown = (
1850+ is_zend_mm ()
1851+ || (force_fast_shutdown && ZEND_ATOL (force_fast_shutdown ))
1852+ ) && !EG (full_tables_cleanup );
1853+ #else
1854+ bool fast_shutdown = is_zend_mm () && !EG (full_tables_cleanup );
1855+ #endif
1856+
18351857 zend_hash_destroy (& DDTRACE_G (traced_spans ));
18361858
18371859 // this needs to be done before dropping the spans
18381860 // run unconditionally because ddtrace may've been disabled mid-request
18391861 ddtrace_exec_handlers_rshutdown ();
18401862
18411863 if (get_DD_TRACE_ENABLED ()) {
1842- dd_force_shutdown_tracing ();
1864+ dd_force_shutdown_tracing (fast_shutdown );
18431865 } else if (!ddtrace_disable ) {
1844- dd_shutdown_hooks_and_observer ();
1866+ dd_shutdown_hooks_and_observer (fast_shutdown );
18451867 }
18461868
18471869 if (DDTRACE_G (remote_config_state )) {
@@ -1851,7 +1873,9 @@ static PHP_RSHUTDOWN_FUNCTION(ddtrace) {
18511873 if (!ddtrace_disable ) {
18521874 ddtrace_autoload_rshutdown ();
18531875
1854- OBJ_RELEASE (& DDTRACE_G (active_stack )-> std );
1876+ if (!fast_shutdown ) {
1877+ OBJ_RELEASE (& DDTRACE_G (active_stack )-> std );
1878+ }
18551879 DDTRACE_G (active_stack ) = NULL ;
18561880 }
18571881
@@ -2344,7 +2368,7 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) {
23442368 ddtrace_mark_all_span_stacks_flushable ();
23452369
23462370 ddog_TracesBytes * traces = ddog_get_traces ();
2347- ddtrace_serialize_closed_spans_with_cycle (traces );
2371+ ddtrace_serialize_closed_spans_with_cycle (traces , false );
23482372
23492373 zval traces_zv = dd_serialize_rust_traces_to_zval (traces );
23502374
@@ -3221,7 +3245,7 @@ PHP_FUNCTION(DDTrace_flush) {
32213245 if (get_DD_AUTOFINISH_SPANS ()) {
32223246 ddtrace_close_userland_spans_until (NULL );
32233247 }
3224- if (ddtrace_flush_tracer (false, get_DD_TRACE_FLUSH_COLLECT_CYCLES ()) == FAILURE ) {
3248+ if (ddtrace_flush_tracer (false, get_DD_TRACE_FLUSH_COLLECT_CYCLES (), false ) == FAILURE ) {
32253249 LOG_LINE (WARN , "Unable to flush the tracer" );
32263250 }
32273251 RETURN_NULL ();
0 commit comments