2017-11-13 20 views
0

私は、ロードされる共有ライブラリがプリコンパイルされたバイナリとして提供される以下のコードを持っています。それはlinaroのツールチェーンでコンパイルされています。#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 

追加情報:

私はこれらの定義がなければgbm-> surface_create(...) `

後の最初のステップを確認するためにGDBを使用:

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 gbm_deviceは、struct stat stat;のメンバーを含んでいます。

struct statは、_LARGEFILE_SOURCEに応じてサイズが変わります。これには、32ビットまたは64ビットのメンバーoff_t st_size;などが含まれています。

_LARGEFILE_SOURCEなしでコンパイルされ、_LARGEFILE_SOURCEでコンパイルされたコードの構造体は、ABI互換ではありません。

ファンクションポインタは、その構造体のメンバの後にあります。そのメンバのサイズを変更すると、次のメンバの見かけ上のオフセットが変更されます。これは、誤った関数ポインタ値がどのように使用されているかを示しています。

+0

普遍的なソリューションは64ビットに移行しています –

関連する問題