77#import " RCTConvert.h"
88#endif
99
10+ #if __has_include(<hermes/hermes.h>)
11+ #define SENTRY_PROFILING_ENABLED 1
12+ #import < Sentry/SentryProfilingConditionals.h>
13+ #else
14+ #define SENTRY_PROFILING_ENABLED 0
15+ #define SENTRY_TARGET_PROFILING_SUPPORTED 0
16+ #endif
17+
1018#import < Sentry/Sentry.h>
1119#import < Sentry/PrivateSentrySDKOnly.h>
1220#import < Sentry/SentryScreenFrames.h>
1321#import < Sentry/SentryOptions+HybridSDKs.h>
1422#import < Sentry/SentryBinaryImageCache.h>
1523#import < Sentry/SentryDependencyContainer.h>
1624#import < Sentry/SentryFormatter.h>
17-
18- #if __has_include(<hermes/hermes.h>)
19- #define SENTRY_PROFILING_ENABLED 1
20- #else
21- #define SENTRY_PROFILING_ENABLED 0
22- #endif
25+ #import < Sentry/SentryCurrentDateProvider.h>
2326
2427// This guard prevents importing Hermes in JSC apps
2528#if SENTRY_PROFILING_ENABLED
@@ -594,16 +597,40 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray<NSNumber*>*)instructionsAdd
594597}
595598
596599static NSString * const enabledProfilingMessage = @" Enable Hermes to use Sentry Profiling." ;
600+ static SentryId* nativeProfileTraceId = nil ;
601+ static uint64_t nativeProfileStartTime = 0 ;
597602
598603RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD (NSDictionary *, startProfiling)
599604{
600605#if SENTRY_PROFILING_ENABLED
601606 try {
602607 facebook::hermes::HermesRuntime::enableSamplingProfiler ();
608+ if (nativeProfileTraceId == nil && nativeProfileStartTime == 0 ) {
609+ #if SENTRY_TARGET_PROFILING_SUPPORTED
610+ nativeProfileTraceId = [[SentryId alloc ] init ];
611+ nativeProfileStartTime = [PrivateSentrySDKOnly startProfilerForTrace: nativeProfileTraceId];
612+ #endif
613+ } else {
614+ NSLog (@" Native profiling already in progress. Currently existing trace: %@ " , nativeProfileTraceId);
615+ }
603616 return @{ @" started" : @YES };
604617 } catch (const std::exception& ex) {
618+ if (nativeProfileTraceId != nil ) {
619+ #if SENTRY_TARGET_PROFILING_SUPPORTED
620+ [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
621+ #endif
622+ nativeProfileTraceId = nil ;
623+ }
624+ nativeProfileStartTime = 0 ;
605625 return @{ @" error" : [NSString stringWithCString: ex.what () encoding: [NSString defaultCStringEncoding ]] };
606626 } catch (...) {
627+ if (nativeProfileTraceId != nil ) {
628+ #if SENTRY_TARGET_PROFILING_SUPPORTED
629+ [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
630+ #endif
631+ nativeProfileTraceId = nil ;
632+ }
633+ nativeProfileStartTime = 0 ;
607634 return @{ @" error" : @" Failed to start profiling" };
608635 }
609636#else
@@ -615,6 +642,17 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray<NSNumber*>*)instructionsAdd
615642{
616643#if SENTRY_PROFILING_ENABLED
617644 try {
645+ NSDictionary <NSString *, id > * nativeProfile = nil ;
646+ if (nativeProfileTraceId != nil && nativeProfileStartTime != 0 ) {
647+ #if SENTRY_TARGET_PROFILING_SUPPORTED
648+ uint64_t nativeProfileStopTime = [[[SentryDependencyContainer sharedInstance ] dateProvider ] systemTime ];
649+ nativeProfile = [PrivateSentrySDKOnly collectProfileBetween: nativeProfileStartTime and: nativeProfileStopTime forTrace: nativeProfileTraceId];
650+ #endif
651+ }
652+ // Cleanup native profiles
653+ nativeProfileTraceId = nil ;
654+ nativeProfileStartTime = 0 ;
655+
618656 facebook::hermes::HermesRuntime::disableSamplingProfiler ();
619657 std::stringstream ss;
620658 facebook::hermes::HermesRuntime::dumpSampledTraceToStream (ss);
@@ -633,10 +671,35 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray<NSNumber*>*)instructionsAdd
633671 }
634672#endif
635673
636- return @{ @" profile" : data };
674+ if (data == nil ) {
675+ return @{ @" error" : @" Failed to retrieve Hermes profile." };
676+ }
677+
678+ if (nativeProfile == nil ) {
679+ return @{ @" profile" : data };
680+ }
681+
682+ return @{
683+ @" profile" : data,
684+ @" nativeProfile" : nativeProfile,
685+ };
637686 } catch (const std::exception& ex) {
687+ if (nativeProfileTraceId != nil ) {
688+ #if SENTRY_TARGET_PROFILING_SUPPORTED
689+ [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
690+ #endif
691+ nativeProfileTraceId = nil ;
692+ }
693+ nativeProfileStartTime = 0 ;
638694 return @{ @" error" : [NSString stringWithCString: ex.what () encoding: [NSString defaultCStringEncoding ]] };
639695 } catch (...) {
696+ if (nativeProfileTraceId != nil ) {
697+ #if SENTRY_TARGET_PROFILING_SUPPORTED
698+ [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
699+ #endif
700+ nativeProfileTraceId = nil ;
701+ }
702+ nativeProfileStartTime = 0 ;
640703 return @{ @" error" : @" Failed to stop profiling" };
641704 }
642705#else
0 commit comments