2

EXIF ​​라이브러리 http://code.google.com/p/iphone-exif/에서 작업 중이며 버그의 실제 스크래쳐를 발견했습니다. 디버그 빌드에서 라이브러리를 구현할 때 모든 것이 아름답게 작동하지만 임시 베타 테스트를 위해 컴파일 할 때 앱이 크게 충돌합니다. 실 5디버그 빌드가 아름답게 작동합니다. 애드혹 빌드가 하드 크래시를받습니다.

Exception Type: EXC_BAD_ACCESS (SIGBUS) 
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000 
Crashed Thread: 5 

:

나는 다음과 같은 오류를 받고 있어요 그것은 방법에 대해 다른 무언가가 나의 의심은

0 Gaia GPS      0x000494e4 -[EXFJpeg scanImageData:] (EXFJpeg.m:372) 
1 Gaia GPS      0x0000524c -[MyAppDelegate saveImage:] (MyAppDelegate.m:935) 
2 Foundation      0x317fef32 0x317ad000 + 335666 
3 Foundation      0x317ae09a 0x317ad000 + 4250 
4 libSystem.B.dylib    0x329c892a 0x329a4000 + 149802 

디버그 빌드는 대 메모리를 처리 ad-hoc 빌드가 메모리를 처리하는 방식. 이 코드가 메모리 블록에 액세스하지 못하도록하려고 시도하는 중 오류가 발생하여 Ad-hoc iPhone OS가 프로세스를 종료 할 때 발생합니다.

ad hoc 배포에서는이 동작이 발생하지만 디버그 빌드에서는 그렇지 않습니다. 전화가 끊어지고 디버거가 꺼지더라도 디버그 빌드가 제대로 작동합니다.

미리 감사드립니다.

코드 :

EXFJpeg* jpegScanner = [[EXFJpeg alloc] init]; 
    [jpegScanner scanImageData:imgData]; 

    CLLocation *location = self.gps.lastReading ? self.gps.lastReading : [self.gps.locationManager location]; 
    [location retain]; 


    NSMutableArray* locArray = [self createLocArray:location.coordinate.latitude]; 
    EXFGPSLoc* gpsLoc = [[EXFGPSLoc alloc] init]; 
    [self populateGPS: gpsLoc :locArray]; 
    [jpegScanner.exifMetaData addTagValue:gpsLoc forKey:[NSNumber numberWithInt:EXIF_GPSLatitude]; 
    [gpsLoc release]; 

    locArray = [self createLocArray:location.coordinate.longitude]; 
    gpsLoc = [[EXFGPSLoc alloc] init]; 
    [self populateGPS: gpsLoc :locArray]; 
    [locArray release]; 

    [jpegScanner.exifMetaData addTagValue:gpsLoc forKey:[NSNumber numberWithInt:EXIF_GPSLongitude]; 
    [gpsLoc release]; 

    NSString *ref = (location.coordinate.latitude <0.0)?ref = @"S": @"N"; 
    [jpegScanner.exifMetaData addTagValue: ref forKey:[NSNumber numberWithInt:EXIF_GPSLatitudeRef] ]; 
    ref = (location.coordinate.longitude <0.0)? @"W": @"E"; 
    [jpegScanner.exifMetaData addTagValue: ref forKey:[NSNumber numberWithInt:EXIF_GPSLongitudeRef]]; 
    [jpegScanner.exifMetaData addTagValue: @"Apple" forKey:[NSNumber numberWithInt:EXIF_Make]; 
    [jpegScanner.exifMetaData addTagValue: @"iPhone" forKey:NSNumber numberWithInt:EXIF_Model]; 
    [jpegScanner.exifMetaData addTagValue:[NSNumber numberWithInt:0] forKey:[NSNumber numberWithInt:EXIF_GPSAltitudeRef] ]; 

    NSArray *arr = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:0], NSNumber numberWithInt:0], [NSNumber numberWithInt:2], [NSNumber numberWithInt:2], nil]; 
    [jpegScanner.exifMetaData addTagValue: arr forKey:[NSNumber numberWithInt:EXIF_GPSVersion] ]; 
    [arr release]; 

    long numDenumArray[2]; 
    long* arrPtr = numDenumArray; 
    [EXFUtils convertRationalToFraction:&arrPtr: [NSNumber numberWithDouble:location.altitude]]; 
    EXFraction *fract = [[EXFraction alloc] initWith:numDenumArray[0] :numDenumArray[1]]; 
    [jpegScanner.exifMetaData addTagValue:fract forKey:[NSNumber 
              numberWithInt:EXIF_GPSAltitude] ]; 

    NSMutableData *newData = [[NSMutableData alloc] init]; 
    [jpegScanner populateImageData:newData]; 
    [jpegScanner release]; 

그리고 마지막으로하지 않을까 : 라이브러리를 구현하는

내 코드

(라인 935은이 블록의 첫 번째 줄의 ALLOC의 한 Statment입니다) 라이브러리 자체의 함수 :

-(void) scanImageData: (NSData*) jpegData { 

    Debug(@"Starting scan headers"); 

    // pointer to the end of the EXIF Data and the start of the rest of the image 
    ByteArray* endOfEXFPtr; 

    imageLength = CFDataGetLength((CFDataRef)jpegData); 

    // CFRetain(&imageLength); 

    Debug(@"Length of image %i", imageLength); 

    imageBytePtr = (UInt8 *) CFDataGetBytePtr((CFDataRef)jpegData); 
    imageStartPtr = imageBytePtr; 

    // check if a valid jpeg file 
    UInt8 val = [self readNextbyte]; 

    if (val != M_BEG){ 
     Debug(@"Not a valid JPEG File"); 
     return; 
    } 

    val = [self readNextbyte]; 

    if (val != M_SOI){ 
     Debug(@"Not a valid start of image JPEG File"); 
     return; 
    } 


    // increment this to position after second byte 
    BOOL finished =FALSE; 

    while(!finished){ 
     // increment the marker 

     val = [self nextMarker]; 

     Debug(@"Got next marker %x at byte count %i", val, (imageBytePtr - imageStartPtr)); 

     switch(val){ 
       case M_SOF0: /* Baseline */ 
       case M_SOF1: /* Extended sequential, Huffman */ 
       case M_SOF2: /* Progressive, Huffman */ 
       case M_SOF3: /* Lossless, Huffman */ 
       case M_SOF5: /* Differential sequential, Huffman */ 
       case M_SOF6: /* Differential progressive, Huffman */ 
       case M_SOF7: /* Differential lossless, Huffman */ 
       case M_SOF9: /* Extended sequential, arithmetic */ 
       case M_SOF10: /* Progressive, arithmetic */ 
       case M_SOF11: /* Lossless, arithmetic */ 
       case M_SOF13: /* Differential sequential, arithmetic */ 
       case M_SOF14: /* Differential progressive, arithmetic */ 
       case M_SOF15: /* Differential lossless, arithmetic */ 
        // Remember the kind of compression we saw 
        { 
         int compression = *imageBytePtr; // <-----------LINE 372 
         self.exifMetaData.compression = compression; 

         // Get the intrinsic properties fo the image 
         [self readImageInfo]; 
        } 
        break; 

       case M_SOS: /* stop before hitting compressed data */ 
       Debug(@"Found SOS at %i", imageBytePtr - imageStartPtr); 
       // [self skipVariable]; 

       // Update the EXIF 
      // updateExif(); 
        finished = TRUE; 
        break; 
       case M_EOI: /* in case it's a tables-only JPEG stream */ 
        Debug(@"End of Image reached at %i ", imageBytePtr - imageStartPtr); 
        finished =TRUE; 
        break; 
       case M_COM: 
        Debug(@"Got com at %i",imageBytePtr - imageStartPtr); 
        break; 

       case M_APP0: 
       case M_APP1: 
       case M_APP2: 
       case M_APP3: 
       case M_APP4: 
       case M_APP5: 
       case M_APP6: 
       case M_APP7: 
       case M_APP8: 
       case M_APP9: 
       case M_APP10: 
       case M_APP11: 
       case M_APP12: 
       case M_APP13: 
       case M_APP14: 
       case M_APP15: 
       // Some digital camera makers put useful textual 
       // information into APP1 and APP12 markers, so we print 
       // those out too when in -verbose mode. 
       { 
        Debug(@"Found app %x at %i", val, imageBytePtr - imageStartPtr); 


        NSData* commentData = [self processComment]; 
        NSNumber* key = [[NSNumber alloc]initWithInt:val]; 

        // add comments to dictionary 
        [self.keyedHeaders setObject:commentData forKey:key]; 
        [key release]; 
        // will always mark the end of the app_x block 
        endOfEXFPtr = imageBytePtr; 

        // we pass a pointer to the NSData pointer here 
        if (val == M_APP0){ 
         Debug(@"Parsing JFIF APP_0 at %i", imageBytePtr - imageStartPtr); 
         [self parseJfif:(CFDataRef*)&commentData]; 
        } else if (val == M_APP1){ 
         [self parseExif:(CFDataRef*)&commentData]; 
         Debug(@"Finished App1 at %i", endOfEXFPtr - imageStartPtr); 
        } else if (val == M_APP2){ 
         Debug(@"Finished APP2 at %i", imageBytePtr - imageStartPtr); 
        }else{ 
         Debug(@"Finished App &x at %i", val, imageBytePtr - imageStartPtr); 
        } 

       } 


       break; 
      case M_SOI: 
       Debug(@"SOI encountered at %i",imageBytePtr - imageStartPtr); 

       break; 
       default:   // Anything else just gets skipped 
       Debug(@"NOt handled %x skipping at %i",val, imageBytePtr - imageStartPtr); 
       [self skipVariable]; // we assume it has a parameter count... 
       break; 
       }  

     } 



    // add in the bytes after the exf block 
    NSData* theRemainingdata = [[NSData alloc] initWithBytes:endOfEXFPtr length:imageLength - (endOfEXFPtr - imageStartPtr)]; 
    self.remainingData = theRemainingdata; 
    [theRemainingdata release]; 

    endOfEXFPtr = NULL; 
    imageStartPtr = NULL; 
    imageBytePtr = NULL; 

} 
+0

출시 빌드를 사용해 보셨습니까? 그런 식으로 당신은 여전히 ​​디버깅 할 수 있지만 이상한 최적화 일이라면 그것을 잡을 수 있습니다. –

답변

2

나는이 똑같은 문제를 오래 전에 보았습니다.

  1. 사용 http://code.google.com/p/iphone-exif/downloads/list에서 대신에 EXFMetaData.m의 소스

  2. 변경 라인 1270에서 컴파일 미리 컴파일 된 라이브러리 :

    CFDataGetBytes (* exifData D는이 개 솔루션 (또는 해결 방법을) 발견 , CFRangeMake (6,2), order);

여기 제안 : http://code.google.com/p/iphone-exif/issues/detail?id=4&can=1

+0

Sweet. 미리 컴파일 된 라이브러리를 사용해 보았지만 # 2가 저에게 효과적이었습니다. 감사! – samvermette

1

가 IT를 패치 :

쓰기 행에 테 파일 EXFJpeg.m이 코드 (330)

경우 (! imageBytePtr) 반환;

다만

UINT8 브로 전에 = 자기 readNextbyte];

모두 !!!!

+0

예외의 0x00000 주소를 기반으로하면 NULL 포인터를 통해 읽은 것처럼 보입니다. –