요약 : 내 컴파일러 설정이어떤 컴파일러/링커 옵션은 구조체가 메모리에 배치하는 방법에 영향을 미칠 수
자세한 사항은 메모리에 설치 얼마나 stucts 변경 될지 알아 내려고 노력하고 있어요 : 나는 동일한 라이브러리 파일 (libgbm.so)의 두 가지 버전을 가지고 있는데, 하나는 사전 빌드 된 바이너리로, 다른 하나는 내 컴퓨터에서 컴파일 된 것이다. 하나는 올바르게 작동하고 하나는 세분화 오류를 발생시킵니다. 내 컴파일러가 미리 컴파일 된 버전과 다른 방식으로 데이터 구조를 전달하는 것 같습니다.
나는 트림 다운 된 버전의 코드를 제공합니다 (하단의 관련 구조 참조). 기본적으로 공유 라이브러리를로드하고 create_device()
함수를 호출합니다. 함수 포인터가있는 데이터 구조 (gbm_device
)를 반환합니다.
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);
}
코드가 다르게 실행되는 곳입니다. 미리 컴파일 된 라이브러리를 사용하는 경우, GDB 내 로컬 컴파일 된 버전을 사용하는 경우 gbm->surface_create
0xb6beb5d0 in ??() from /usr/lib/gbm/gbm_pvr.so
로 후 다음 단계는, GDB는
0xb6c414a4 in ??() from /usr/lib/gbm/gbm_pvr.so
으로 다음 단계 내가 디버그 기호가없는 음료수 gbm_pvr.so (독점 라이브러리)에 대해서는이 코드가 분명히 두 개의 다른 기능을 수행하고 있습니다 (적어도 메모리 주소의 마지막 3 자리는 동일해야 함).
내가 생각할 수있는 유일한 점은 어떤 컴파일러/링커 설정이 누락 된 것인가라는 것인데, gbm_device
구조가 메모리에 어떻게 배치되어 있는지를 놓친 것이므로 모든 포인터를 엉망으로 만든다.
다음은 준 구조체
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 (*destroy)(struct gbm_device *gbm);
int (*is_format_supported)(struct gbm_device *gbm,
uint32_t format,
uint32_t usage);
struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format,
uint32_t usage);
struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type,
void *buffer, uint32_t usage);
int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data);
int (*bo_get_fd)(struct gbm_bo *bo);
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);
void (*surface_release_buffer)(struct gbm_surface *surface,
struct gbm_bo *bo);
int (*surface_has_free_buffers)(struct gbm_surface *surface);
void (*surface_destroy)(struct gbm_surface *surface);
};
그리고
struct gbm_backend {
const char *backend_name;
struct gbm_device *(*create_device)(int fd);
};