Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,7 @@
F4DCC9E52E4AACE0008ECE45 /* SentrySDKSettings+Equality.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DCC9E42E4AACE0008ECE45 /* SentrySDKSettings+Equality.m */; };
F4E1E9812E8C2B150007B080 /* SentryDateUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E1E9802E8C2B150007B080 /* SentryDateUtil.swift */; };
F4E3DCCB2E1579240093CB80 /* SentryScopePersistentStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E3DCCA2E1579240093CB80 /* SentryScopePersistentStore.swift */; };
F4EF69232E95ABE800B6B46A /* SentryCrashMachineContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EF69222E95ABE800B6B46A /* SentryCrashMachineContextTests.m */; };
F4FE9DBD2E621F100014FED5 /* SentryRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FE9DBC2E621F100014FED5 /* SentryRandom.swift */; };
F4FE9DFD2E622CD70014FED5 /* SentryDefaultObjCRuntimeWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FE9DFB2E622CD70014FED5 /* SentryDefaultObjCRuntimeWrapper.swift */; };
F4FE9DFE2E622CD70014FED5 /* SentryObjCRuntimeWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FE9DFC2E622CD70014FED5 /* SentryObjCRuntimeWrapper.swift */; };
Expand Down Expand Up @@ -2356,6 +2357,7 @@
F4DCC9E42E4AACE0008ECE45 /* SentrySDKSettings+Equality.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentrySDKSettings+Equality.m"; sourceTree = "<group>"; };
F4E1E9802E8C2B150007B080 /* SentryDateUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryDateUtil.swift; sourceTree = "<group>"; };
F4E3DCCA2E1579240093CB80 /* SentryScopePersistentStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryScopePersistentStore.swift; sourceTree = "<group>"; };
F4EF69222E95ABE800B6B46A /* SentryCrashMachineContextTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCrashMachineContextTests.m; sourceTree = "<group>"; };
F4FE9DBC2E621F100014FED5 /* SentryRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryRandom.swift; sourceTree = "<group>"; };
F4FE9DFB2E622CD70014FED5 /* SentryDefaultObjCRuntimeWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryDefaultObjCRuntimeWrapper.swift; sourceTree = "<group>"; };
F4FE9DFC2E622CD70014FED5 /* SentryObjCRuntimeWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryObjCRuntimeWrapper.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3315,6 +3317,7 @@
621655652DB12A8900810504 /* SentryCrashMach-OTests.m */,
628B45332DB8D5E700934391 /* SentryCrashCxaThrowSwapper_Tests.mm */,
629258542DAF91940049388F /* SentryCrashStackCursorSelfThreadTests.swift */,
F4EF69222E95ABE800B6B46A /* SentryCrashMachineContextTests.m */,
);
path = SentryCrash;
sourceTree = "<group>";
Expand Down Expand Up @@ -6198,6 +6201,7 @@
F4AACD612E01ACE800DDDD1E /* SentryCrashDynamicLinkerTests.m in Sources */,
7B6438A726A70DDB000D0F65 /* UIViewControllerSentryTests.swift in Sources */,
D8BC28D62C00C6DF0054DA4D /* StringExtensionsTests.swift in Sources */,
F4EF69232E95ABE800B6B46A /* SentryCrashMachineContextTests.m in Sources */,
15E0A8F0240F638200F044E3 /* SentrySerializationNilTests.m in Sources */,
0A2D8D8728992260008720F6 /* SentryBaseIntegrationTests.swift in Sources */,
7B6D135C27F4605D00331ED2 /* TestEnvelopeRateLimitDelegate.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
SENTRY_ASYNC_SAFE_LOG_ERROR("task_threads: %s", mach_error_string(kr));
return false;
}
SENTRY_ASYNC_SAFE_LOG_TRACE("Got %d threads", context->threadCount);
SENTRY_ASYNC_SAFE_LOG_TRACE("Got %d threads", actualThreadCount);
int threadCount = (int)actualThreadCount;
int maxThreadCount = sizeof(context->allThreads) / sizeof(context->allThreads[0]);
if (threadCount > maxThreadCount) {
Expand All @@ -84,7 +84,7 @@
context->threadCount = threadCount;

for (mach_msg_type_number_t i = 0; i < actualThreadCount; i++) {
mach_port_deallocate(thisTask, context->allThreads[i]);
mach_port_deallocate(thisTask, threads);

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Check no UIKit linkage (DebugWithoutUIKit)

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit tvOS 26 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit iOS 17 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Check compiling Async Safe Logs

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit iOS 26 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit tvOS 17 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit iOS 17 SentrySwiftUI

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit Catalyst 14 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit macOS 14 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Check UIKit linkage (Debug)

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Build SDK v9

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit macOS 26 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample macOS-Swift Debug

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit macOS 15 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit Catalyst 15 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample macOS-Swift DebugV9

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Check no UIKit linkage (ReleaseWithoutUIKit)

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample tvOS-Swift DebugV9

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample visionOS-Swift DebugV9

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Check UIKit linkage (Release)

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Check API Stability ()

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit iOS 18 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample visionOS-Swift Debug

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit iOS 16 Sentry

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Werror,-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Build XCFramework Slices (Sentry, mh_dylib, -WithoutUIKitOrAppKit, WithoutUIKit, sentry-withoutui... / maccatalyst

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Werror,-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Build XCFramework Slices (Sentry, mh_dylib, -Dynamic, sentry-dynamic) / iphonesimulator

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Werror,-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Build XCFramework Slices (SentrySwiftUI, mh_dylib, sentry-swiftui) / iphoneos

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Werror,-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Build XCFramework Slices (SentrySwiftUI, mh_dylib, sentry-swiftui) / watchos

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Werror,-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample SessionReplay-CameraTest Debug

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Build XCFramework Slices (Sentry, mh_dylib, -WithoutUIKitOrAppKit, WithoutUIKit, sentry-withoutui... / iphonesimulator

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Werror,-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample watchOS-Swift WatchKit App Debug

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Build XCFramework Slices (Sentry, mh_dylib, -Dynamic, sentry-dynamic) / appletvos

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Werror,-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample macOS-SwiftUI Debug

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample iOS-Swift DebugV9

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Unit with Test Server macOS 15

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample iOS-ObjectiveC DebugV9

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Sample iOS-SwiftUI DebugV9

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Lint

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]

Check failure on line 87 in Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c

View workflow job for this annotation

GitHub Actions / Run SwiftUI Crash Test

incompatible pointer to integer conversion passing 'thread_act_array_t' (aka 'unsigned int *') to parameter of type 'mach_port_name_t' (aka 'unsigned int'); dereference with * [-Wint-conversion]
}
vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * actualThreadCount);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ extern "C" {
# define STRUCT_MCONTEXT_L _STRUCT_MCONTEXT
#endif

#define SENTRY_CRASH_MAX_THREADS 100

typedef struct SentryCrashMachineContext {
thread_t thisThread;
thread_t allThreads[100];
thread_t allThreads[SENTRY_CRASH_MAX_THREADS];
int threadCount;
bool isCrashedContext;
bool isCurrentThread;
Expand Down
122 changes: 122 additions & 0 deletions Tests/SentryTests/SentryCrash/SentryCrashMachineContextTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#import <XCTest/XCTest.h>

#import "SentryCrashMachineContext.h"
#import "SentryCrashMachineContext_Apple.h"
#import "TestThread.h"
#import <mach/mach.h>

@interface SentryCrashMachineContextTests : XCTestCase
@end

@implementation SentryCrashMachineContextTests

- (void)testGetContextForThread_NonCrashedContext_DoesNotPopulateThreadList
{
// Create a test thread
NSObject *notificationObject = [[NSObject alloc] init];
TestThread *thread = [[TestThread alloc] init];
thread.notificationObject = notificationObject;

XCTestExpectation *exp = [self expectationWithDescription:@"thread started"];
[NSNotificationCenter.defaultCenter
addObserverForName:@"io.sentry.test.TestThread.main"
object:notificationObject
queue:nil
usingBlock:^(NSNotification *_Nonnull __unused notification) {
[NSNotificationCenter.defaultCenter
removeObserver:self
name:@"io.sentry.test.TestThread.main"
object:notificationObject];
[exp fulfill];
}];

[thread start];
[self waitForExpectationsWithTimeout:1 handler:nil];

kern_return_t kr;
kr = thread_suspend(thread.thread);
XCTAssertTrue(kr == KERN_SUCCESS, @"Thread suspension failed");

// Get context for a non-crashed thread
SentryCrashMC_NEW_CONTEXT(machineContext);
bool result = sentrycrashmc_getContextForThread(thread.thread, machineContext, NO);

XCTAssertTrue(result, @"Failed to get context for thread");
XCTAssertFalse(
sentrycrashmc_isCrashedContext(machineContext), @"Should not be marked as crashed context");

// For non-crashed contexts, thread list should not be populated (will be 0)
int threadCount = sentrycrashmc_getThreadCount(machineContext);
XCTAssertEqual(
threadCount, 0, @"Thread count should be 0 for non-crashed context, got %d", threadCount);

thread_resume(thread.thread);
[thread cancel];
}

- (void)testGetContextForThread_WithManyThreads
{
NSInteger numberOfThreads = 10;
NSMutableArray<TestThread *> *threads = [NSMutableArray arrayWithCapacity:numberOfThreads];
NSMutableArray<XCTestExpectation *> *expectations =
[NSMutableArray arrayWithCapacity:numberOfThreads];

for (int i = 0; i < numberOfThreads; i++) {
NSObject *notificationObject = [[NSObject alloc] init];
TestThread *thread = [[TestThread alloc] init];
thread.notificationObject = notificationObject;

XCTestExpectation *exp =
[self expectationWithDescription:[NSString stringWithFormat:@"thread %d started", i]];
[expectations addObject:exp];

[NSNotificationCenter.defaultCenter
addObserverForName:@"io.sentry.test.TestThread.main"
object:notificationObject
queue:nil
usingBlock:^(NSNotification *_Nonnull __unused notification) {
[NSNotificationCenter.defaultCenter
removeObserver:self
name:@"io.sentry.test.TestThread.main"
object:notificationObject];
[exp fulfill];
}];

[threads addObject:thread];
[thread start];
}

[self waitForExpectations:expectations timeout:2];

// Suspend the first thread and get its context
TestThread *firstThread = threads[0];
kern_return_t kr = thread_suspend(firstThread.thread);
XCTAssertTrue(kr == KERN_SUCCESS, @"Thread suspension failed");

// Get context for the crashed thread
SentryCrashMC_NEW_CONTEXT(machineContext);
bool result = sentrycrashmc_getContextForThread(firstThread.thread, machineContext, YES);

XCTAssertTrue(result, @"Failed to get context for thread");

// Verify that thread list includes all our test threads
int threadCount = sentrycrashmc_getThreadCount(machineContext);
XCTAssertTrue(
threadCount >= 10, @"Thread count should include all test threads, got %d", threadCount);
XCTAssertTrue(threadCount <= SENTRY_CRASH_MAX_THREADS,
@"Thread count should not exceed maximum of SENTRY_CRASH_MAX_THREADS, got %d", threadCount);

// Verify that all our threads are in the list
for (TestThread *thread in threads) {
int threadIndex = sentrycrashmc_indexOfThread(machineContext, thread.thread);
XCTAssertTrue(threadIndex >= 0, @"Thread should be found in the list");
}

// Clean up
thread_resume(firstThread.thread);
for (TestThread *thread in threads) {
[thread cancel];
}
}

@end
Loading