2017-11-13 4 views
0

다음 코드는 미리로드 된 공유 라이브러리가 미리 컴파일 된 바이너리로 제공되는 코드입니다. 그것은 linaro toolchain으로 컴파일됩니다.#define _LARGEFILE_SOURCE가 이러한 함수 포인터를 중단하는 이유는 무엇입니까?

gbm_create_device(int fd) 
{ 
    struct gbm_device *gbm = NULL; 
    void *module; 
    const struct gbm_backend *backend = NULL 

    module = dlopen("/usr/lib/gbm/gbm_pvr.so", RTLD_NOW | RTLD_GLOBAL); 
    backend = dlsym(module, "gbm_backend"); 
    gbm = backend->create_device(fd); 

    gbm->surface_create(gbm, width, height, format, flags); 
} 

struct gbm_device { 
    /* Hack to make a gbm_device detectable by its first element. */ 
    struct gbm_device *(*dummy)(int); 

    int fd; 
    const char *name; 
    unsigned int refcount; 
    struct stat stat; 

    ... 
    void (*bo_destroy)(struct gbm_bo *bo); 

    struct gbm_surface *(*surface_create)(struct gbm_device *gbm, 
             uint32_t width, uint32_t height, 
             uint32_t format, uint32_t flags); 
    struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface); 
    ... 
}; 

코드는 정상적으로 올바르게 작동합니다. 그러나 다음 정의를 추가하면 gbm->surface_create(...)은 공유 라이브러리의 잘못된 메모리 위치로 점프합니다. 왜? official GNU page에서 나에게는 분명하지 않습니다.

#define _LARGEFILE_SOURCE 
#define _LARGEFILE64_SOURCE 
#define _FILE_OFFSET_BITS=64 

추가 정보 :

난 후 첫 번째 단계를 확인하기 위해 GDB를 사용 gbm-> surface_create (...) 이러한 정의없이`

:

0xb6beb5d0 in ??() from /usr/lib/gbm/gbm_pvr.so 
... 
// Correct behavior 

정의 :

0xb6c414a4 in ??() from /usr/lib/gbm/gbm_pvr.so 
... 
// Segmentation fault 
+0

gdb 백 트랙을 추가 할 수 있습니까? – yugr

+0

@yugr 몇 시간 만에 얻을 수 있지만 (지금 당장 보드에 액세스 할 수 없음), gdb에서 추가 정보를 추가했습니다. – user8908459

답변

5

에는 struct stat stat; 회원이 있습니다.

struct stat_LARGEFILE_SOURCE에 따라 크기가 변경됩니다. 여기에는 32 비트 또는 64 비트 멤버 인 off_t st_size; 등이 포함됩니다.

_LARGEFILE_SOURCE없이 컴파일 된 코드와 _LARGEFILE_SOURCE으로 컴파일 된 코드는 ABI와 호환되지 않습니다.

함수 포인터는 구조체의 해당 멤버 뒤에 위치합니다. 해당 멤버의 크기를 변경하면 잘못된 멤버 포인터 값이 사용되는 방식 인 다음 멤버의 겉보기 오프셋이 변경됩니다.

+0

범용 솔루션이 64 비트로 마이그레이션 중입니다. –

관련 문제