在循环结束后调度队列导致 sigabrt

dispatch queue causing sigabrt after a loop ends

我遇到了 st运行ge 崩溃。我正在蓝牙设备上写入数据。当循环结束时,应用程序获得 SIGABRT。直到现在我还无法弄清楚崩溃。有人可以帮我解决这个问题吗? 如果循环被调用 2 次,应用程序在此函数中崩溃,如果调用 1 次则不会崩溃。

BOOL success = [strongSelf.CronoDeviceObject.deviceHandler writeSettingsScreenData:data module:strongSelf.CronoDeviceObject.moduleNumber];




    #pragma mark Button Save and cancel
- (IBAction)OkTaped:(id)sender{
    //for submit
    if ([self validateData]) {

        [[ProgressHUD defaultHUD] setLoadingText:CVLocalizedString(@"Updating",nil)];

        [[ProgressHUD defaultHUD]showInView:self.view];

        [self performSelector:@selector(saveAllSettings) withObject:nil afterDelay:1.0];


    }

}

- (void)saveAllSettings {

        __weak __typeof__(self) weakSelf = self;

         dispatch_queue_t queue = dispatch_queue_create("writesettings",NULL);
        dispatch_async(queue, ^{

            __strong __typeof__(self) strongSelf = weakSelf;
            if (strongSelf.CronoDeviceObject) {
            [strongSelf.CronoDeviceObject.deviceHandler writeFastWindUp:strongSelf.CronoDeviceObject.moduleNumber];
            [strongSelf.CronoDeviceObject.deviceHandler writeLightOnOff:strongSelf.CronoDeviceObject.moduleNumber state:strongSelf.btnCheckBox2.selected?0x01:0x00];

           strongSelf.CronoDeviceObject.lightState = (strongSelf.btnCheckBox2.selected)?0:1;

            NSLog(@"Button Light is %@",([strongSelf.CronoDeviceObject isEnergySavingMode])?@"ON":@"Off");

            NSString* semicolon =[NSString stringWithFormat:@";%@;%@;%@",strongSelf.BrandNametxtfld.text,strongSelf.ModalNametxtfld.text,[NSString stringWithFormat:@"%@;", strongSelf.WatchWinderNametxtfld.text]];

                NSMutableData* data = [[NSMutableData alloc] initWithData:[semicolon dataUsingEncoding:NSUTF8StringEncoding]];


                if ([strongSelf.CronoDeviceObject.deviceHandler respondsToSelector:@selector(writeSettingsScreenData:module:)]) {

                    BOOL success = [strongSelf.CronoDeviceObject.deviceHandler writeSettingsScreenData:data module:strongSelf.CronoDeviceObject.moduleNumber];

    **//The app does not get here if the above function loop called 2 times but if it called 1 time it's working fine.**

                    if (success) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            __strong __typeof__(self) strongSelf = weakSelf;
                            self.CronoDeviceObject.Devicemodal.Brandname = strongSelf.BrandNametxtfld.text;
                            self.CronoDeviceObject.Devicemodal.modalName = strongSelf.ModalNametxtfld.text;
                            self.CronoDeviceObject.Devicemodal.winderName = strongSelf.WatchWinderNametxtfld.text;

                            // Update the UI
                            [[ProgressHUD defaultHUD]hideActivityIndicator];

                            [strongSelf.navigationController popViewControllerAnimated:YES];

                        });
                    }
                }

            }


        });


}



- (BOOL) writeSettingsScreenData:(NSMutableData*) payload module:(Byte) module {

if (payload == nil) {
    return false;
}

int numwrites = 1;
numwrites += (payload.length - 1)/32;
numwrites = (numwrites>8)?8:numwrites;

for(int i = 0; i < numwrites; i++){
    //@try {


        NSUInteger bufferLength = (payload.length - i*32);
        Byte buff[32];
        memset(buff, 0, 32);
        [payload getBytes:&buff range:NSMakeRange(i*32, bufferLength)];


        self.finalString = @"";
        //rcvbuff = new StringBuffer(32);

        self.chronoVisionMessage = [ChronoVisionMessage new];
        //Set Line Address And Dir(R)
        //                 chronoVisionMessage.setLineAddr(ChronoVisionMessage.LINE_BROADCAST);
        //                 chronoVisionMessage.setLineDir(ChronoVisionMessage.LINE_WRITE);
        //Set Module (communicnMstr/Address)
        [self.chronoVisionMessage setModRsvd:(MODULE_BUSMASTER)];//set to 0

        [self.chronoVisionMessage setModCh:(MODULE_BUSMASTER)];//set to default zero
        if (module == 0) {
            [self.chronoVisionMessage setModAddr:(MODULE_BROADCAST)];
        }
        else{
         [self.chronoVisionMessage setModAddr:module];
        }
        //Set Register Access(R)/Addresss
        [self.chronoVisionMessage setRegRw:REIGSTER_WRITE];

        [self.chronoVisionMessage setRegType:REIGSTER_ACCESSTYPE1];//Access standard reg
        [self.chronoVisionMessage setRegAddr:REIGSTER_ACCESSTYPE0];//set to 0
        //[self.chronoVisionMessage setValueHi:REIGSTER_ACCESSTYPE0];//set to 0
        [self.chronoVisionMessage setValueLo:((Byte)i)];//set to 0 to 7

        [self.chronoVisionMessage setNewData:[NSMutableData dataWithBytes:buff length:32]];//set to 0

    @try {
        NSMutableData* header = [self.chronoVisionMessage getMessage];
        NSMutableData* final = [[NSMutableData alloc] initWithBytes:[header bytes] length:[header length]];
        [final appendBytes:buff length:32];
        [self writeData:final];


        int retryCount = 0;
        while (!self.allDataReceived && retryCount<kTimeout) {
            [NSThread sleepForTimeInterval:0.1];
        }
        //String allData = read(5000);
        if(self.finalString.length == 0){
            //_peripheral.setListener(null);
            return false;
        }

        if ([self.finalString length] >= 8  && [self.finalString rangeOfString:@"\r"].location > 0) {
            self.finalString = [self.finalString substringWithRange:NSMakeRange(0, [self.finalString rangeOfString:@"\r"].location)];
        }

        NSData *finalData = [self.finalString dataFromHex];

        NSLog(@"final readBuff is %@",finalData);

        if (i==(numwrites-1) && finalData.length >= 36) {
            return true;
        }

        //free(buff);
    }
    @catch (NSException *exception) {
        NSLog(@"Exception occured when writing user data %@",[exception description]);
    }
}
return false;

}

这是崩溃后的图像

这里是回溯日志

    bt
* thread #12: tid = 0x13cf99, 0x3611c9aa libsystem_c.dylib`__abort + 102, queue = 'com.apple.root.default-qos', stop reason = EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe)
  * frame #0: 0x3611c9aa libsystem_c.dylib`__abort + 102
    frame #1: 0x3611cf94 libsystem_c.dylib`__stack_chk_fail + 180
    frame #2: 0x0007a2d4 Chronovision`-[DeviceHandler writeSettingsScreenData:module:](self=0x17081990, _cmd=0x001069c2, payload=0x00000000, module='\x02') + 3028 at DeviceHandler.m:435
    frame #3: 0x000d1f2c Chronovision`__34-[CVDetailViewController OkTaped:]_block_invoke(.block_descriptor=<unavailable>) + 400 at CVDetailViewController.m:357
    frame #4: 0x002b219a libdispatch.dylib`_dispatch_call_block_and_release + 10
    frame #5: 0x002bcc48 libdispatch.dylib`_dispatch_root_queue_drain + 1596
    frame #6: 0x002bde20 libdispatch.dylib`_dispatch_worker_thread3 + 108
    frame #7: 0x361fada8 libsystem_pthread.dylib`_pthread_wqthread + 668
(lldb) 

更新 我 运行 xcode 7.1.1 中的应用程序,当应用程序崩溃时,我在控制台中获得了以下登录信息。

Dec  7 16:55:09 Rahuls-iPad Chronovision[1650] <Error>: ================================================================
==1650==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x088e06a0 at pc 0x0036f4a9 bp 0x088e02c4 sp 0x088dfe94
WRITE of size 42 at 0x088e06a0 thread T23
    #0 0x36f4a7 in wrap_memmove (/private/var/mobile/Containers/Bundle/Application/33337E25-C69D-49F5-ABA1-5AD65673725C/Chronovision.app/Frameworks/libclang_rt.asan_ios_dynamic.dylib+0x2a4a7)
    #1 0x287936b3 in <redacted> (/System/Library/Frameworks/Foundation.framework/Foundation+0x236b3)
    #2 0x8a971 in -[DeviceHandler writeSettingsScreenData:module:] (/private/var/mobile/Containers/Bundle/Application/33337E25-C69D-49F5-ABA1-5AD65673725C/Chronovision.app/Chronovision+0x2d971)
    #3 0x139eaf in __41-[CVDetailViewController saveAllSettings]_block_invoke (/private/var/mobile/Containers/Bundle/Application/33337E25-C69D-49F5-ABA1-5AD65673725C/Chronovision.app/Chronovision+0xdceaf)
    #4 0x374e15 in __wrap_dispatch_async_block_invoke (/private/var/mobile/Containers/Bundle/Application/33337E25-C69D-49F5-ABA1-5AD65673725C/Chronovision.app/Frameworks/libclang_rt.asan_ios_dynamic.dylib+0x2fe15)
    #5 0x853199 in _dispatch_call_block_and_release (/usr/lib/system/introspection/libdispatch.dylib+0x1199)
    #6 0x85bd87 in _dispatch_queue_drain (/usr/lib/system/introspection/libdispatch.dylib+0x9d87)
    #7 0x855ac3 in _dispatch_queue_invoke (/usr/lib/system/introspection/libdispatch.dylib+0x3ac3)
    #8 0x85db19 in _dispatch_root_queue_drain (/usr/lib/system/introspection/libdispatch.dylib+0xbb19)
    #9 0x85ee1f in _dispatch_worker_thread3 (/usr/lib/system/introspection/libdispatch.dylib+0xce1f)
    #10 0x361fada7 in _pthread_wqthread (/usr/lib/system/libsystem_pthread.dylib+0xda7)
    #11 0x361faafb in start_wqthread (/usr/lib/system/libsystem_pthread.dylib+0xafb)

Address 0x088e06a0 is located in stack of thread T23 at offset 128 in frame
    #0 0x8a427 in -[DeviceHandler writeSettingsScreenData:module:] (/private/var/mobile/Containers/Bundle/Application/33337E25-C69D-49F5-ABA1-5AD65673725C/Chronovision.app/Chronovision+0x2d427)

  This frame has 12 object(s):
    [16, 24) 'r.i1'
    [48, 56) 'r.i'
    [80, 84) ''
    [96, 128) 'buff'
    [160, 168) '' <== Memory access at offset 128 partially underflows this variable
    [192, 196) 'header'
    [208, 212) 'final'
    [224, 232) ''
    [256, 264) ''
    [288, 296) ''
    [320, 324) 'finalData'
    [336, 340) 'exception'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
Thread T23 created by T0 here:
    <empty stack>

SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 wrap_memmove
Shadow bytes around the buggy address:
  0x4111c080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4111c090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4111c0a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4111c0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4111c0c0: 00 00 00 00 f1 f1 00 f2 f2 f2 00 f2 f2 f2 04 f2
=>0x4111c0d0: 00 00 00 00[f2]f2 f2 f2 00 f2 f2 f2 04 f2 04 f2
  0x4111c0e0: 00 f2 f2 f2 00 f2 f2 f2 00 f2 f2 f2 04 f2 04 f3
  0x4111c0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4111c100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4111c110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4111c120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  ==1650==ABORTING

我遇到了 xcode 7.1.1 的问题。 我不知道为什么xcode 6.2 无法检测到崩溃位置。 问题出在我在函数

中使用的范围内
- (BOOL) writeSettingsScreenData:(NSMutableData*) payload module:(Byte) module {

    if (payload == nil) {
        return false;
    }

    int numwrites = 1;
    numwrites += (payload.length - 1)/32;
    numwrites = (numwrites>8)?8:numwrites;

    for(int i = 0; i < numwrites; i++){
        //@try {

        //Changed this
            NSUInteger bufferLength = (payload.length - i*32);
            Byte buff[32];
            memset(buff, 0, 32);
            [payload getBytes:&buff range:NSMakeRange(i*32, bufferLength)];
         //To this
           NSUInteger bufferLength = ((payload.length - i*32)>32)?32:(payload.length-i*32);
            Byte buff[32];
            memset(buff, 0, 32);
            if (payload && payload.length > bufferLength) {
               [payload getBytes:&buff range:NSMakeRange(i*32, bufferLength)];
            } 

            self.finalString = @"";
            //rcvbuff = new StringBuffer(32);

            self.chronoVisionMessage = [ChronoVisionMessage new];
            //Set Line Address And Dir(R)
            //                 chronoVisionMessage.setLineAddr(ChronoVisionMessage.LINE_BROADCAST);
            //                 chronoVisionMessage.setLineDir(ChronoVisionMessage.LINE_WRITE);
            //Set Module (communicnMstr/Address)
            [self.chronoVisionMessage setModRsvd:(MODULE_BUSMASTER)];//set to 0

            [self.chronoVisionMessage setModCh:(MODULE_BUSMASTER)];//set to default zero
            if (module == 0) {
                [self.chronoVisionMessage setModAddr:(MODULE_BROADCAST)];
            }
            else{
             [self.chronoVisionMessage setModAddr:module];
            }
            //Set Register Access(R)/Addresss
            [self.chronoVisionMessage setRegRw:REIGSTER_WRITE];

            [self.chronoVisionMessage setRegType:REIGSTER_ACCESSTYPE1];//Access standard reg
            [self.chronoVisionMessage setRegAddr:REIGSTER_ACCESSTYPE0];//set to 0
            //[self.chronoVisionMessage setValueHi:REIGSTER_ACCESSTYPE0];//set to 0
            [self.chronoVisionMessage setValueLo:((Byte)i)];//set to 0 to 7

            [self.chronoVisionMessage setNewData:[NSMutableData dataWithBytes:buff length:32]];//set to 0

        @try {
            NSMutableData* header = [self.chronoVisionMessage getMessage];
            NSMutableData* final = [[NSMutableData alloc] initWithBytes:[header bytes] length:[header length]];
            [final appendBytes:buff length:32];
            [self writeData:final];


            int retryCount = 0;
            while (!self.allDataReceived && retryCount<kTimeout) {
                [NSThread sleepForTimeInterval:0.1];
            }
            //String allData = read(5000);
            if(self.finalString.length == 0){
                //_peripheral.setListener(null);
                return false;
            }

            if ([self.finalString length] >= 8  && [self.finalString rangeOfString:@"\r"].location > 0) {
                self.finalString = [self.finalString substringWithRange:NSMakeRange(0, [self.finalString rangeOfString:@"\r"].location)];
            }

            NSData *finalData = [self.finalString dataFromHex];

            NSLog(@"final readBuff is %@",finalData);

            if (i==(numwrites-1) && finalData.length >= 36) {
                return true;
            }

            //free(buff);
        }
        @catch (NSException *exception) {
            NSLog(@"Exception occured when writing user data %@",[exception description]);
        }
    }
    return false;
}