2011-08-31 5 views
2

Mac OSX에서 루비 1.9.2로 작업하는 루비 확장자를 C로 작성하려고합니다. 64 비트 포인터가 32 비트 값으로 잘리고 저용량 메모리에 액세스하려는 함수에서 반환 된 segfault가 계속 발생합니다.루비 C 확장 - 세그 폴트를 일으키는 64 비트 포인터가 잘림

여기에 대해 알아 냈습니다. VALUE는 루비 소스 코드에 정의 된 long이며, sizeof (long)가 8 바이트가 아니면 코드가 컴파일되지 않습니다.

함수 호출이 종료 file_a.c

VALUE 
func_do_stuff(int argc, VALUE *argv, VALUE obj) 
{ 
    VALUE filename, file_path; 

    ... 

    // But here, the size of what is returned is 4 bytes 
    // file_path has a size of 8 bytes though 
    file_path = rb_helper_function_foo(filename); 

    //This statement will segfault :-(
    if(!RTEST(file_path)) 
    { 
    ... 
    } 
    ... 
} 

에서

VALUE 
rb_helper_function_foo(VALUE file) 
{ 
    VALUE blah; 

    ... 

    //Using gdb, blah right here is a 64bit address, ex: 0x1 009d 62a0 
    return blah; 
} 

는 반환 값이 올바른 어드레스를 갖지만, 오직 하위 4 바이트 얻을 : file_b.c에서

0x1009d52a0 대신 0x009d52a0이 반환되었습니다. 낮은 메모리 주소에 액세스하면 segfault가 발생합니다. 반환시에 호출되는 어셈블리 코드에서

,이 명령 만 복사 하위 4 바이트,하지만 난 %의 RAX의 모든 8 바이트 필요가 복사 할
movslq %eax, %r12 

있다.

xcode 4.0.1 (gcc 4.2.1)을 사용하여 루비 1.9.2-p290 (p180과 동일 함), Mac OSX 10.6.8을 사용하고 있지만 gcc로 업그레이드도 시도했습니다. 4.6.1. 또한 이전에 xcode 3.2를 시도했습니다.

도움을 주셔서 감사합니다.

+0

'long'의 크기는 구현에 따라 정의되므로 8 바이트 길이가 보장되지는 않습니다. –

답변

3

아마도 이것은 rb_helper_function_foo이 file_a.c 컴파일 단위에서 선언되지 않은 것일 수 있습니다. 컴파일러는 VALUE 대신 int를 반환한다고 가정합니다.

+0

그걸 고쳤다. 감사! – keithepley

관련 문제