2014-11-05 63 views
1

,當我試圖從網上教程Wayland的代碼,它工作正常,它顯示在下面的代碼行*pixel++ = 0xffff;分段錯誤,我韋蘭共享內存代碼中發現分段錯誤

static void 
paint_pixels_A(void *temp_data) { 
    int n; 
    uint32_t *pixel = temp_data; 

    fprintf(stderr, "Painting pixels\n"); 
    for (n =0; n < WIDTH*HEIGHT; n++) { 
     *pixel++ = 0xffff; 
    } 
} 

的變化我已經對這個碼,

static struct wl_buffer * 
create_buffer() { 
    struct wl_shm_pool *pool; 
    int stride = WIDTH * 4; // 4 bytes per pixel 
    int size = stride * HEIGHT; 
    int fd; 
    struct wl_buffer *buff; 

    fd = os_create_anonymous_file(size); 
    if (fd < 0) { 
    fprintf(stderr, "creating a buffer file for %d B failed: %m\n", 
     size); 
    exit(1); 
    } 

    shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if (shm_data == MAP_FAILED) { 
    close(fd); 
    exit(1); 
    } 

    pool = wl_shm_create_pool(shm, fd, size); 
    buff = wl_shm_pool_create_buffer(pool, 0, 
         WIDTH, HEIGHT, 
         stride, 
         WL_SHM_FORMAT_XRGB8888); 

    wl_shm_pool_destroy(pool); 
    return buff; 
} 

我修改上面的代碼行作爲

static struct wl_buffer * 
create_buffer(void *temp_data) { // modification 1 
    struct wl_shm_pool *pool; 
    int stride = WIDTH * 4; 
    int size = stride * HEIGHT; 
    int fd; 
    struct wl_buffer *buff; 

    fd = os_create_anonymous_file(size); 
    if (fd < 0) { 
    fprintf(stderr, "creating a buffer file for %d B failed: %m\n", 
     size); 
    exit(1); 
    } 

    temp_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); //modification 2 
    if (temp_data == MAP_FAILED) { 
    close(fd); 
    exit(1); 
    } 

    pool = wl_shm_create_pool(shm, fd, size); 
    buff = wl_shm_pool_create_buffer(pool, 0, 
         WIDTH, HEIGHT, 
         stride, 
         WL_SHM_FORMAT_XRGB8888) 
    wl_shm_pool_destroy(pool); 
    return buff; 
} 

和相應的功能還呼籲, 你可以看到在這個link 正確的代碼這裏是我的全部代碼,請檢查並給予反饋

struct wl_display *display = NULL; 
struct wl_compositor *compositor = NULL; 
struct wl_surface *surface; 
struct wl_shell *shell; 
struct wl_shell_surface *shell_surface; 
struct wl_shm *shm; 
struct wl_buffer *buffer; 

void *shm_data; 

int WIDTH = 480; 
int HEIGHT = 360; 

static void 
handle_ping(void *data, struct wl_shell_surface *shell_surface, 
          uint32_t serial) 
{ 
    wl_shell_surface_pong(shell_surface, serial); 
} 

static void 
handle_configure(void *data, struct wl_shell_surface *shell_surface, 
     uint32_t edges, int32_t width, int32_t height) 
{ 
} 

static void 
handle_popup_done(void *data, struct wl_shell_surface *shell_surface) 
{ 
} 

static const struct wl_shell_surface_listener shell_surface_listener = { 
    handle_ping, 
    handle_configure, 
    handle_popup_done 
}; 

static int 
set_cloexec_or_close(int fd) 
{ 
     long flags; 

     if (fd == -1) 
       return -1; 

     flags = fcntl(fd, F_GETFD); 

     if (flags == -1) 
       goto err; 

     if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) 
       goto err; 

     return fd; 

err: 
     close(fd); 
     return -1; 
} 

static int 
create_tmpfile_cloexec(char *tmpname) 
{ 
     int fd; 

#ifdef HAVE_MKOSTEMP 
     fd = mkostemp(tmpname, O_CLOEXEC); 
     if (fd >= 0) 
       unlink(tmpname); 
#else 
     fd = mkstemp(tmpname); 
     if (fd >= 0) { 
       fd = set_cloexec_or_close(fd); 
       unlink(tmpname); 
     } 
#endif 

     return fd; 
} 

int 
os_create_anonymous_file(off_t size) 
{ 
     static const char template[] = "/weston-shared-XXXXXX"; 
     const char *path; 
     char *name; 
     int fd; 

     path = getenv("XDG_RUNTIME_DIR"); 
     if (!path) { 
       errno = ENOENT; 
       return -1; 
     } 

     name = malloc(strlen(path) + sizeof(template)); 
     if (!name) 
       return -1; 
     strcpy(name, path); 
     strcat(name, template); 

     fd = create_tmpfile_cloexec(name); 

     free(name); 

     if (fd < 0) 
       return -1; 

     if (ftruncate(fd, size) < 0) { 
       close(fd); 
       return -1; 
     } 

     return fd; 
} 

static void 
paint_pixels_A(void *temp_data) { 
    int n; 
    uint32_t *pixel = temp_data; 

    fprintf(stderr, "Painting pixels\n"); 
    for (n =0; n < WIDTH*HEIGHT; n++) { 
     *pixel++ = 0xffff; 
    } 
} 


static struct wl_buffer * 
create_buffer(void *temp_data) { 
    struct wl_shm_pool *pool; 
    int stride = WIDTH * 4; // 4 bytes per pixel 
    int size = stride * HEIGHT; 
    int fd; 
    struct wl_buffer *buff; 

    fd = os_create_anonymous_file(size); 
    if (fd < 0) { 
    exit(1); 
    } 

    temp_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if (temp_data == MAP_FAILED) { 
    fprintf(stderr, "mmap failed: %m\n"); 
    close(fd); 
    exit(1); 
    } 

    pool = wl_shm_create_pool(shm, fd, size); 
    buff = wl_shm_pool_create_buffer(pool, 0, 
         WIDTH, HEIGHT, 
         stride, 
         WL_SHM_FORMAT_XRGB8888); 
    wl_shm_pool_destroy(pool); 
    return buff; 
} 

static void 
create_window() { 
    buffer = create_buffer((void *)shm_data); 

    wl_surface_attach(surface, buffer, 0, 0); 
    wl_surface_commit(surface); 
} 


static void 
shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) 
{ 
    fprintf(stderr, "Format %d\n", format); 
} 

struct wl_shm_listener shm_listener = { 
    shm_format 
}; 

static void 
global_registry_handler(void *data, struct wl_registry *registry, uint32_t id, 
      const char *interface, uint32_t version) 
{ 
    if (strcmp(interface, "wl_compositor") == 0) { 
     compositor = wl_registry_bind(registry, 
         id, 
         &wl_compositor_interface, 
         1); 
    } else if (strcmp(interface, "wl_shell") == 0) { 
     shell = wl_registry_bind(registry, id, 
           &wl_shell_interface, 1); 
    } else if (strcmp(interface, "wl_shm") == 0) { 
     shm = wl_registry_bind(registry, id, 
           &wl_shm_interface, 1); 
    wl_shm_add_listener(shm, &shm_listener, NULL); 

    } 
} 

static void 
global_registry_remover(void *data, struct wl_registry *registry, uint32_t id) 
{ 
    printf("Got a registry losing event for %d\n", id); 
} 

static const struct wl_registry_listener registry_listener = { 
    global_registry_handler, 
    global_registry_remover 
}; 


int main(int argc, char **argv) { 


    int checker; 

    display = wl_display_connect(NULL); 
    if (display == NULL) { 
    exit(1); 
    } 

    struct wl_registry *registry = wl_display_get_registry(display); 
    wl_registry_add_listener(registry, &registry_listener, NULL); 

    wl_display_dispatch(display); 
    wl_display_roundtrip(display); 

    if (compositor == NULL) { 
    exit(1); 
    } 

    surface = wl_compositor_create_surface(compositor); 
    if (surface == NULL) { 
    exit(1); 
    } 

    shell_surface = wl_shell_get_shell_surface(shell, surface); 
    if (shell_surface == NULL) { 
    exit(1); 
    } 
    wl_shell_surface_set_toplevel(shell_surface); 

    wl_shell_surface_add_listener(shell_surface, 
        &shell_surface_listener, NULL); 


    create_window(); 
    paint_pixels_A((void *)shm_data); 

    while (wl_display_dispatch(display) != -1) { 
    ; 
    } 

    wl_display_disconnect(display); 

    exit(0); 
} 
+0

那些奇怪的'else {; '子句看起來很可怕。刪除它們。 – unwind 2014-11-05 10:43:53

回答

-1

你永遠不分配shm_data

此:

buffer = create_buffer((void *)shm_data); 

變化shm_data。另外,你幾乎從不需要在C中使用void *,所以不要這樣做。

該行也許應該是:

shm_data = create_buffer(); 

當然create_buffer()的,應改爲不採取僞參數,只是返回一個指針mmap()編輯區域。