@@ -120,103 +120,6 @@ bool doesCurrentPidMatchPidOnInit( pid_t pidOnInit, String dbgDesc )
120
120
return true;
121
121
}
122
122
123
- void elasticApmModuleInit ( int moduleType , int moduleNumber )
124
- {
125
- registerOsSignalHandler ();
126
-
127
- ELASTIC_APM_LOG_DIRECT_DEBUG ( "%s entered: moduleType: %d, moduleNumber: %d, parent PID: %d" , __FUNCTION__ , moduleType , moduleNumber , (int )(getParentProcessId ()) );
128
-
129
- ResultCode resultCode ;
130
- Tracer * const tracer = getGlobalTracer ();
131
- const ConfigSnapshot * config = NULL ;
132
-
133
- ELASTIC_APM_CALL_IF_FAILED_GOTO ( constructTracer ( tracer ) );
134
-
135
- if ( ! tracer -> isInited )
136
- {
137
- ELASTIC_APM_LOG_DEBUG ( "Extension is not initialized" );
138
- ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE ();
139
- }
140
-
141
- registerElasticApmIniEntries ( moduleType , moduleNumber , & tracer -> iniEntriesRegistrationState );
142
-
143
- ELASTIC_APM_CALL_IF_FAILED_GOTO ( ensureLoggerInitialConfigIsLatest ( tracer ) );
144
- ELASTIC_APM_CALL_IF_FAILED_GOTO ( ensureAllComponentsHaveLatestConfig ( tracer ) );
145
-
146
- logSupportabilityInfo ( logLevel_debug );
147
-
148
- config = getTracerCurrentConfigSnapshot ( tracer );
149
-
150
- if ( ! config -> enabled )
151
- {
152
- resultCode = resultSuccess ;
153
- ELASTIC_APM_LOG_DEBUG ( "Extension is disabled" );
154
- goto finally ;
155
- }
156
-
157
- registerCallbacksToLogFork ();
158
- registerAtExitLogging ();
159
-
160
- CURLcode curlCode = curl_global_init ( CURL_GLOBAL_ALL );
161
- if ( curlCode != CURLE_OK )
162
- {
163
- resultCode = resultFailure ;
164
- ELASTIC_APM_LOG_ERROR ( "curl_global_init failed: %s (%d)" , curl_easy_strerror ( curlCode ), (int )curlCode );
165
- goto finally ;
166
- }
167
- tracer -> curlInited = true;
168
-
169
- resultCode = resultSuccess ;
170
- finally :
171
-
172
- ELASTIC_APM_LOG_DEBUG_RESULT_CODE_FUNCTION_EXIT ();
173
- // We ignore errors because we want the monitored application to continue working
174
- // even if APM encountered an issue that prevent it from working
175
- return ;
176
-
177
- failure :
178
- moveTracerToFailedState ( tracer );
179
- goto finally ;
180
- }
181
-
182
- void elasticApmModuleShutdown ( int moduleType , int moduleNumber )
183
- {
184
- ResultCode resultCode ;
185
-
186
- ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG ( "moduleType: %d, moduleNumber: %d" , moduleType , moduleNumber );
187
-
188
- Tracer * const tracer = getGlobalTracer ();
189
- const ConfigSnapshot * const config = getTracerCurrentConfigSnapshot ( tracer );
190
-
191
- if ( ! config -> enabled )
192
- {
193
- resultCode = resultSuccess ;
194
- ELASTIC_APM_LOG_DEBUG_FUNCTION_EXIT_MSG ( "Because extension is not enabled" );
195
- goto finally ;
196
- }
197
-
198
- backgroundBackendCommOnModuleShutdown ( config );
199
-
200
- if ( tracer -> curlInited )
201
- {
202
- curl_global_cleanup ();
203
- tracer -> curlInited = false;
204
- }
205
-
206
- unregisterElasticApmIniEntries ( moduleType , moduleNumber , & tracer -> iniEntriesRegistrationState );
207
-
208
- resultCode = resultSuccess ;
209
-
210
- finally :
211
- destructTracer ( tracer );
212
-
213
- // We ignore errors because we want the monitored application to continue working
214
- // even if APM encountered an issue that prevent it from working
215
- ELASTIC_APM_UNUSED ( resultCode );
216
-
217
- ELASTIC_APM_LOG_DIRECT_DEBUG ( "%s exiting..." , __FUNCTION__ );
218
- }
219
-
220
123
typedef void (* ZendThrowExceptionHook )(
221
124
#if PHP_MAJOR_VERSION >= 8 /* if PHP version is 8.* and later */
222
125
zend_object * exception
@@ -225,7 +128,8 @@ typedef void (* ZendThrowExceptionHook )(
225
128
#endif
226
129
);
227
130
228
- static bool isOriginalZendThrowExceptionHookSet = false;
131
+ static bool elasticApmZendErrorCallbackSet = false;
132
+ static bool elasticApmZendThrowExceptionHookSet = false;
229
133
static ZendThrowExceptionHook originalZendThrowExceptionHook = NULL ;
230
134
static bool g_isLastThrownSet = false;
231
135
static zval g_lastThrown ;
@@ -284,7 +188,17 @@ void elasticApmZendThrowExceptionHook(
284
188
#endif
285
189
)
286
190
{
287
- elasticApmZendThrowExceptionHookImpl ( thrownObj );
191
+ Tracer * const tracer = getGlobalTracer ();
192
+ const ConfigSnapshot * config = getTracerCurrentConfigSnapshot ( tracer );
193
+ if (config -> captureErrors ) {
194
+ elasticApmZendThrowExceptionHookImpl ( thrownObj );
195
+ }
196
+
197
+ if (originalZendThrowExceptionHook == elasticApmZendThrowExceptionHook ) {
198
+ ELASTIC_APM_LOG_CRITICAL ( "originalZendThrowExceptionHook == elasticApmZendThrowExceptionHook" );
199
+ return ;
200
+ }
201
+
288
202
289
203
if ( originalZendThrowExceptionHook != NULL )
290
204
{
@@ -352,7 +266,6 @@ const char* zendErrorCallbackFileNameToCString( ZendErrorCallbackFileName fileNa
352
266
353
267
typedef void (* ZendErrorCallback )( ELASTIC_APM_ZEND_ERROR_CALLBACK_SIGNATURE () );
354
268
355
- static bool isOriginalZendErrorCallbackSet = false;
356
269
static ZendErrorCallback originalZendErrorCallback = NULL ;
357
270
358
271
struct PhpErrorData
@@ -511,6 +424,178 @@ void elasticApmZendErrorCallbackImpl( ELASTIC_APM_ZEND_ERROR_CALLBACK_SIGNATURE(
511
424
goto finally ;
512
425
}
513
426
427
+ void elasticApmZendErrorCallback ( ELASTIC_APM_ZEND_ERROR_CALLBACK_SIGNATURE () )
428
+ {
429
+ Tracer * const tracer = getGlobalTracer ();
430
+ const ConfigSnapshot * config = getTracerCurrentConfigSnapshot ( tracer );
431
+ if (config -> captureErrors ) {
432
+ elasticApmZendErrorCallbackImpl ( ELASTIC_APM_ZEND_ERROR_CALLBACK_ARGS () );
433
+ }
434
+
435
+
436
+ if (originalZendErrorCallback == elasticApmZendErrorCallback ) {
437
+ ELASTIC_APM_LOG_CRITICAL ( "originalZendErrorCallback == elasticApmZendErrorCallback" );
438
+ return ;
439
+ }
440
+
441
+ if ( originalZendErrorCallback != NULL )
442
+ {
443
+ originalZendErrorCallback ( ELASTIC_APM_ZEND_ERROR_CALLBACK_ARGS () );
444
+ }
445
+ }
446
+
447
+
448
+ static void registerErrorAndExceptionHooks () {
449
+ if (!elasticApmZendErrorCallbackSet ) {
450
+ originalZendErrorCallback = zend_error_cb ;
451
+ zend_error_cb = elasticApmZendErrorCallback ;
452
+ elasticApmZendErrorCallbackSet = true;
453
+ ELASTIC_APM_LOG_DEBUG ( "Set zend_error_cb: %p (%s elasticApmZendErrorCallback) -> %p"
454
+ , originalZendErrorCallback , originalZendErrorCallback == elasticApmZendErrorCallback ? "==" : "!="
455
+ , elasticApmZendErrorCallback );
456
+ } else {
457
+ ELASTIC_APM_LOG_WARNING ( "zend_error_cb already set: %p. Original: %p, Elastic: %p" , zend_error_cb , originalZendErrorCallback , elasticApmZendErrorCallback );
458
+ }
459
+
460
+
461
+ if (!elasticApmZendThrowExceptionHookSet ) {
462
+ originalZendThrowExceptionHook = zend_throw_exception_hook ;
463
+ zend_throw_exception_hook = elasticApmZendThrowExceptionHook ;
464
+ elasticApmZendThrowExceptionHookSet = true;
465
+ ELASTIC_APM_LOG_DEBUG ( "Set zend_throw_exception_hook: %p (%s elasticApmZendThrowExceptionHook) -> %p"
466
+ , originalZendThrowExceptionHook , originalZendThrowExceptionHook == elasticApmZendThrowExceptionHook ? "==" : "!="
467
+ , elasticApmZendThrowExceptionHook );
468
+ } else {
469
+ ELASTIC_APM_LOG_WARNING ( "zend_erzend_throw_exception_hook already set: %p. Original: %p, Elastic: %p" , zend_throw_exception_hook , originalZendThrowExceptionHook , elasticApmZendThrowExceptionHook );
470
+ }
471
+ }
472
+
473
+
474
+ static void unregisterErrorAndExceptionHooks () {
475
+ if (elasticApmZendThrowExceptionHookSet ) {
476
+ ZendThrowExceptionHook zendThrowExceptionHookBeforeRestore = zend_throw_exception_hook ;
477
+ zend_throw_exception_hook = originalZendThrowExceptionHook ;
478
+ ELASTIC_APM_LOG_DEBUG ( "Restored zend_throw_exception_hook: %p (%s elasticApmZendThrowExceptionHook: %p) -> %p"
479
+ , zendThrowExceptionHookBeforeRestore , zendThrowExceptionHookBeforeRestore == elasticApmZendThrowExceptionHook ? "==" : "!="
480
+ , elasticApmZendThrowExceptionHook , originalZendThrowExceptionHook );
481
+ originalZendThrowExceptionHook = NULL ;
482
+ } else {
483
+ ELASTIC_APM_LOG_DEBUG ("zend_throw_exception_hook not restored: %p, elastic: %p" , zend_throw_exception_hook , elasticApmZendThrowExceptionHook );
484
+ }
485
+
486
+ if (!elasticApmZendErrorCallbackSet ) {
487
+ ZendErrorCallback zendErrorCallbackBeforeRestore = zend_error_cb ;
488
+ zend_error_cb = originalZendErrorCallback ;
489
+ ELASTIC_APM_LOG_DEBUG ( "Restored zend_error_cb: %p (%s elasticApmZendErrorCallback: %p) -> %p"
490
+ , zendErrorCallbackBeforeRestore , zendErrorCallbackBeforeRestore == elasticApmZendErrorCallback ? "==" : "!="
491
+ , elasticApmZendErrorCallback , originalZendErrorCallback );
492
+ originalZendErrorCallback = NULL ;
493
+ } else {
494
+ ELASTIC_APM_LOG_DEBUG ("zend_error_cb not restored: %p, elastic: %p" , zend_error_cb , elasticApmZendErrorCallback );
495
+ }
496
+
497
+ }
498
+
499
+ void elasticApmModuleInit ( int moduleType , int moduleNumber )
500
+ {
501
+ registerOsSignalHandler ();
502
+
503
+ ELASTIC_APM_LOG_DIRECT_DEBUG ( "%s entered: moduleType: %d, moduleNumber: %d, parent PID: %d" , __FUNCTION__ , moduleType , moduleNumber , (int )(getParentProcessId ()) );
504
+
505
+ ResultCode resultCode ;
506
+ Tracer * const tracer = getGlobalTracer ();
507
+ const ConfigSnapshot * config = NULL ;
508
+
509
+ ELASTIC_APM_CALL_IF_FAILED_GOTO ( constructTracer ( tracer ) );
510
+
511
+ if ( ! tracer -> isInited )
512
+ {
513
+ ELASTIC_APM_LOG_DEBUG ( "Extension is not initialized" );
514
+ ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE ();
515
+ }
516
+
517
+ registerElasticApmIniEntries ( moduleType , moduleNumber , & tracer -> iniEntriesRegistrationState );
518
+
519
+ ELASTIC_APM_CALL_IF_FAILED_GOTO ( ensureLoggerInitialConfigIsLatest ( tracer ) );
520
+ ELASTIC_APM_CALL_IF_FAILED_GOTO ( ensureAllComponentsHaveLatestConfig ( tracer ) );
521
+
522
+ logSupportabilityInfo ( logLevel_debug );
523
+
524
+ config = getTracerCurrentConfigSnapshot ( tracer );
525
+
526
+ if ( ! config -> enabled )
527
+ {
528
+ resultCode = resultSuccess ;
529
+ ELASTIC_APM_LOG_DEBUG ( "Extension is disabled" );
530
+ goto finally ;
531
+ }
532
+
533
+ registerCallbacksToLogFork ();
534
+ registerAtExitLogging ();
535
+ registerErrorAndExceptionHooks ();
536
+
537
+ CURLcode curlCode = curl_global_init ( CURL_GLOBAL_ALL );
538
+ if ( curlCode != CURLE_OK )
539
+ {
540
+ resultCode = resultFailure ;
541
+ ELASTIC_APM_LOG_ERROR ( "curl_global_init failed: %s (%d)" , curl_easy_strerror ( curlCode ), (int )curlCode );
542
+ goto finally ;
543
+ }
544
+ tracer -> curlInited = true;
545
+
546
+ resultCode = resultSuccess ;
547
+ finally :
548
+
549
+ ELASTIC_APM_LOG_DEBUG_RESULT_CODE_FUNCTION_EXIT ();
550
+ // We ignore errors because we want the monitored application to continue working
551
+ // even if APM encountered an issue that prevent it from working
552
+ return ;
553
+
554
+ failure :
555
+ moveTracerToFailedState ( tracer );
556
+ goto finally ;
557
+ }
558
+
559
+ void elasticApmModuleShutdown ( int moduleType , int moduleNumber )
560
+ {
561
+ ResultCode resultCode ;
562
+
563
+ ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG ( "moduleType: %d, moduleNumber: %d" , moduleType , moduleNumber );
564
+
565
+ Tracer * const tracer = getGlobalTracer ();
566
+ const ConfigSnapshot * const config = getTracerCurrentConfigSnapshot ( tracer );
567
+
568
+ if ( ! config -> enabled )
569
+ {
570
+ resultCode = resultSuccess ;
571
+ ELASTIC_APM_LOG_DEBUG_FUNCTION_EXIT_MSG ( "Because extension is not enabled" );
572
+ goto finally ;
573
+ }
574
+
575
+ unregisterErrorAndExceptionHooks ();
576
+
577
+ backgroundBackendCommOnModuleShutdown ( config );
578
+
579
+ if ( tracer -> curlInited )
580
+ {
581
+ curl_global_cleanup ();
582
+ tracer -> curlInited = false;
583
+ }
584
+
585
+ unregisterElasticApmIniEntries ( moduleType , moduleNumber , & tracer -> iniEntriesRegistrationState );
586
+
587
+ resultCode = resultSuccess ;
588
+
589
+ finally :
590
+ destructTracer ( tracer );
591
+
592
+ // We ignore errors because we want the monitored application to continue working
593
+ // even if APM encountered an issue that prevent it from working
594
+ ELASTIC_APM_UNUSED ( resultCode );
595
+
596
+ ELASTIC_APM_LOG_DIRECT_DEBUG ( "%s exiting..." , __FUNCTION__ );
597
+ }
598
+
514
599
void elasticApmGetLastPhpError ( zval * return_value )
515
600
{
516
601
if ( ! g_lastPhpErrorDataSet )
@@ -527,16 +612,6 @@ void elasticApmGetLastPhpError( zval* return_value )
527
612
ELASTIC_APM_ZEND_ADD_ASSOC ( return_value , "stackTrace" , zval , & ( g_lastPhpErrorData .stackTrace ) );
528
613
}
529
614
530
- void elasticApmZendErrorCallback ( ELASTIC_APM_ZEND_ERROR_CALLBACK_SIGNATURE () )
531
- {
532
- elasticApmZendErrorCallbackImpl ( ELASTIC_APM_ZEND_ERROR_CALLBACK_ARGS () );
533
-
534
- if ( originalZendErrorCallback != NULL )
535
- {
536
- originalZendErrorCallback ( ELASTIC_APM_ZEND_ERROR_CALLBACK_ARGS () );
537
- }
538
- }
539
-
540
615
void elasticApmRequestInit ()
541
616
{
542
617
requestCounter ++ ;
@@ -599,24 +674,7 @@ void elasticApmRequestInit()
599
674
600
675
// readSystemMetrics( &tracer->startSystemMetricsReading );
601
676
602
- if ( config -> captureErrors )
603
- {
604
- originalZendErrorCallback = zend_error_cb ;
605
- isOriginalZendErrorCallbackSet = true;
606
- zend_error_cb = elasticApmZendErrorCallback ;
607
- ELASTIC_APM_LOG_DEBUG ( "Set zend_error_cb: %p (%s elasticApmZendErrorCallback) -> %p"
608
- , originalZendErrorCallback , originalZendErrorCallback == elasticApmZendErrorCallback ? "==" : "!="
609
- , elasticApmZendErrorCallback );
610
-
611
- originalZendThrowExceptionHook = zend_throw_exception_hook ;
612
- isOriginalZendThrowExceptionHookSet = true;
613
- zend_throw_exception_hook = elasticApmZendThrowExceptionHook ;
614
- ELASTIC_APM_LOG_DEBUG ( "Set zend_throw_exception_hook: %p (%s elasticApmZendThrowExceptionHook) -> %p"
615
- , originalZendThrowExceptionHook , originalZendThrowExceptionHook == elasticApmZendThrowExceptionHook ? "==" : "!="
616
- , elasticApmZendThrowExceptionHook );
617
- }
618
- else
619
- {
677
+ if (!config -> captureErrors ) {
620
678
ELASTIC_APM_LOG_DEBUG ( "capture_errors (captureErrors) configuration option is set to false which means errors will NOT be captured" );
621
679
}
622
680
@@ -686,29 +744,6 @@ void elasticApmRequestShutdown()
686
744
goto finally ;
687
745
}
688
746
689
-
690
- if ( isOriginalZendThrowExceptionHookSet )
691
- {
692
- ZendThrowExceptionHook zendThrowExceptionHookBeforeRestore = zend_throw_exception_hook ;
693
- zend_throw_exception_hook = originalZendThrowExceptionHook ;
694
- ELASTIC_APM_LOG_DEBUG ( "Restored zend_throw_exception_hook: %p (%s elasticApmZendThrowExceptionHook: %p) -> %p"
695
- , zendThrowExceptionHookBeforeRestore , zendThrowExceptionHookBeforeRestore == elasticApmZendThrowExceptionHook ? "==" : "!="
696
- , elasticApmZendThrowExceptionHook , originalZendThrowExceptionHook );
697
- originalZendThrowExceptionHook = NULL ;
698
- isOriginalZendThrowExceptionHookSet = false;
699
- }
700
-
701
- if ( isOriginalZendErrorCallbackSet )
702
- {
703
- ZendErrorCallback zendErrorCallbackBeforeRestore = zend_error_cb ;
704
- zend_error_cb = originalZendErrorCallback ;
705
- ELASTIC_APM_LOG_DEBUG ( "Restored zend_error_cb: %p (%s elasticApmZendErrorCallback: %p) -> %p"
706
- , zendErrorCallbackBeforeRestore , zendErrorCallbackBeforeRestore == elasticApmZendErrorCallback ? "==" : "!="
707
- , elasticApmZendErrorCallback , originalZendErrorCallback );
708
- originalZendErrorCallback = NULL ;
709
- isOriginalZendErrorCallbackSet = false;
710
- }
711
-
712
747
// We should shutdown PHP part first because sendMetrics() uses metadata sent by PHP part on shutdown
713
748
shutdownTracerPhpPart ( config );
714
749
0 commit comments