You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS多线程非安全访问整数变量的崩溃实例及相关咨询

Hey there, let's tackle your questions about thread-unsafe integer access on iOS—this is a super common pain point when dealing with multi-threaded code, so I'll break this down clearly for you.

1. Crash Types Caused by Non-Thread-Safe Integer Access

When multiple threads read/write a plain integer variable (like NSInteger, int, or Swift Int) without atomic protections, the most common direct crashes you'll see are:

  • EXC_BAD_ACCESS (SIGSEGV/SIGBUS): This often happens when a "torn read" (partial value from a write operation interrupted by another thread) produces an invalid integer that's used as an array index, pointer offset, or memory address. For example, a 64-bit integer might have its 32 high bits from one write and 32 low bits from another, creating a value that points to invalid memory.
  • EXC_ARITHMETIC (SIGFPE): Rare but possible if a torn integer value leads to an illegal arithmetic operation—like division by zero, or integer overflow that triggers a hardware exception (depends on compiler flags and CPU architecture).
  • EXC_BAD_INSTRUCTION (SIGILL): An edge case from aggressive compiler optimizations. If multi-threaded interference corrupts the instruction sequence generated for the integer access, the CPU might try to execute an invalid instruction.

Note: Most non-thread-safe integer access leads to silent data corruption first, but crashes happen when that corrupted value is used in a dangerous context (like array indexing) that directly triggers an exception.

2. Reproducible Test Cases (Unit Tests & Demo Code)

To reliably trigger crashes from thread-unsafe integer access, you need to amplify the race condition with lots of threads, frequent operations, and a dangerous use of the corrupted value (like array indexing). Here are working examples:

Objective-C Unit Test

#import <XCTest/XCTest.h>

@interface IntegerThreadSafetyTests : XCTestCase
@property (nonatomic, assign) NSInteger unsafeCounter;
@end

@implementation IntegerThreadSafetyTests

- (void)testUnsafeIntegerCrash {
    self.unsafeCounter = 0;
    const NSInteger threadCount = 60;
    dispatch_group_t group = dispatch_group_create();
    
    for (NSInteger i = 0; i < threadCount; i++) {
        dispatch_group_enter(group);
        dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
            for (NSInteger j = 0; j < 150000; j++) {
                // Non-atomic read/write to trigger race conditions
                self.unsafeCounter += 1;
                NSInteger corruptedValue = self.unsafeCounter;
                
                // Use the corrupted value to trigger an array out-of-bounds crash
                static NSArray *tinyArray = nil;
                static dispatch_once_t onceToken;
                dispatch_once(&onceToken, ^{
                    tinyArray = @[@"foo", @"bar", @"baz"];
                });
                // When corruptedValue is torn, modulo can produce an invalid index
                NSString *unused = tinyArray[corruptedValue % tinyArray.count];
                (void)unused;
            }
            dispatch_group_leave(group);
        });
    }
    
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}

@end

Swift Unit Test

import XCTest

class IntegerThreadSafetyTests: XCTestCase {
    private var unsafeCounter: Int = 0
    
    func testUnsafeIntegerCrash() {
        unsafeCounter = 0
        let threadCount = 60
        let group = DispatchGroup()
        
        for _ in 0..<threadCount {
            group.enter()
            DispatchQueue.global(qos: .userInitiated).async {
                for _ in 0..<150000 {
                    self.unsafeCounter += 1
                    let corruptedValue = self.unsafeCounter
                    
                    // Trigger array out-of-bounds with the corrupted value
                    let tinyArray = ["foo", "bar", "baz"]
                    let unused = tinyArray[corruptedValue % tinyArray.count]
                    _ = unused
                }
                group.leave()
            }
        }
        
        group.wait()
    }
}

Tips for Higher Crash Probability

  • Increase thread count (60+ works well) and loop iterations (150k+)
  • Add a tiny usleep(1) inside the inner loop to widen the race window
  • Run the test on a physical device (simulators have different thread scheduling behavior)

3. Crash Log Keywords & Regex Patterns

To filter crash logs related to your unsafe integer access, use these patterns:

Key Crash Type Strings

  • EXC_BAD_ACCESS (SIGSEGV): Most common for array out-of-bounds crashes from torn integers
  • EXC_ARITHMETIC (SIGFPE): For overflow or division crashes
  • __NSArrayI objectAtIndexedSubscript:: Objective-C array subscript crash call stack entry
  • Swift._ContiguousArrayStorage.subscript.get: Swift array subscript crash call stack entry

Regex Examples

  • Match array out-of-bounds crashes linked to your integer variable:
    EXC_BAD_ACCESS.*(__NSArrayI objectAtIndexedSubscript:|Swift._ContiguousArrayStorage.subscript.get).*unsafeCounter
    
  • Match crashes involving your integer property's setter/getter:
    (\[.*setUnsafeCounter:|\[.*unsafeCounter]|IntegerThreadSafetyTests\.unsafeCounter\.(set|get))
    
  • Match integer overflow-related crashes:
    EXC_ARITHMETIC.*integer overflow
    

内容的提问来源于stack exchange,提问作者cbutton9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:16:54