2014-01-16 3 views
0

오픈 소스 프로젝트 MHTextSearch을 테스트 할 때 이상한 문제가 발생했습니다. 라인 169 of MHTextIndex.m에서 :Objective-C on x86_64의 비정상적인 메모리 동작

uint64_t maxLength = [indexedString maximumLengthOfBytesUsingEncoding:encoding]; 
// some code 

for (...) { 

    [indexedString getBytes:keyPtr 
        maxLength:maxLength 
       usedLength:&usedLength 
        encoding:encoding 
        options:NSStringEncodingConversionAllowLossy 
         range:subRange 
      remainingRange:NULL]; 

    // some more code 
} 

아무것도, 다른 곳, maxLength을 수정합니다. 두 번째 반복에서 maxLength는 이전 값이 무엇이든간에 0과 같습니다. 나는 그것에 와치 포인트를 설정하면, 나는 이것에 대해 매우 이상한 것은 그것이 단지 x86_64의 아키텍처에서 발생한다는 것입니다

0x100038d19: movq -0x30(%rbp), %rdx 
0x100038d1d: movq %rdx, (%rsi) 
0x100038d20: testq %rcx, %rcx   << this instruction 

에서, 그것은 -[NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange:]의 변화를보고, 내가 좋아하는 코드를 변경하는 경우는 고정 할 수 있습니다 이 코드와이

uint64_t maxLength = [indexedString maximumLengthOfBytesUsingEncoding:encoding]; 
uint64_t strLength = maxLength; 
// some code 

for (...) { 

    [indexedString getBytes:keyPtr 
        maxLength:strLength 
       usedLength:&usedLength 
        encoding:encoding 
        options:NSStringEncodingConversionAllowLossy 
         range:subRange 
      remainingRange:NULL]; 

    // some more code 
} 

maxLength 여전히 같은 명령에서 0 으로 변경됩니다,하지만 strLength 일관성 유지, 그래서 효과가 제거됩니다.

어째서?

답변

2

usedLength의 유형이 잘못되었습니다. uint32_t이라고 선언되었습니다. 그러나 이것은 NSUInteger으로 선언되어야하며 32 비트 아키텍처에서는 32 비트이고 64 비트 아키텍처에서는 64 비트입니다.

+0

네가 맞아! 하지만 여전히, 나는 그것이 maxLength의 값에 어떻게 영향을 미치는지 이해하지 못한다 ... – matehat

+0

그들은 스택에 연속적이다. 'getBytes : maxLength : usedLength : encoding : options : range : remainingRange :'는 64 비트로 취급하고,'usedLength' 변수에 인접한 32 비트를 덮어 씁니다. 그것은 'maxLength'의 하위 32 비트입니다. –

+0

하루에 지우기. 고마워요! – matehat