Skip to content
Commits on Source (6)
  • Pekka Paalanen's avatar
    README: drop note about a cairo build option · 27cf5046
    Pekka Paalanen authored
    
    
    That build option has been long gone. cairo-image is the only flavor used
    nowadays.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    27cf5046
  • Pekka Paalanen's avatar
    ivi-shell: replace MEM_ALLOC() with mostly xcalloc() · cbbf0e59
    Pekka Paalanen authored
    
    
    Drop the even more home-grown alloc wrapper and use the xalloc.h
    wrappers directly.
    
    xcalloc() is added and used, because calloc() will detect integer
    overflows in the size multiplication, while doing a simple
    multiplication in the caller is subject to overflows which may result in
    allocating not what was expected, subjecting to out-of-bounds access.
    
    All MEM_ALLOC() calls that had a meaningful multiplication in them were
    converted to xcalloc(), the rest to xzalloc().
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    cbbf0e59
  • Pekka Paalanen's avatar
    shared: rewrite fail_on_null() as abort_oom_if_null() · 9229a451
    Pekka Paalanen authored
    
    
    Recently I learnt that fprintf() is not async-signal-safe. Maybe it also
    attempts to allocate memory sometimes. Hence, using it when we
    presumably are out of memory is wishful thinking.
    
    Therefore replace that with async-signal-safe code. If you have to check
    pointers from traditional signal handlers, now you could do that too!
    
    While doing this, we also lose the string formatting for line number. I
    would argue that printing file and line number is not that useful, if
    the system really is out of memory. If not out of memory, a core dump
    would give us much more detailed information about what went wrong.
    
    clients/window.c had some calls to fail_on_null() and these are simply
    replaced. They were used for checking that creating new wl_proxy by
    issuing a protocol request worked, and IIRC that only fails on
    out-of-memory, so the same rationale applies here.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    9229a451
  • Pekka Paalanen's avatar
    clients/simple-touch: use xzalloc() for buffer · c95feefb
    Pekka Paalanen authored
    
    
    This file relied on shared/xalloc.h to include <libweston/zalloc.h>.
    That would be a problem if xalloc.h stopped doing that.
    
    Just use xzalloc().
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    c95feefb
  • Pekka Paalanen's avatar
    shared/xalloc.h: do not rely on zalloc() · fc26c749
    Pekka Paalanen authored
    
    
    The definition of zalloc is trivial, so let's just have it here instead
    of loading libweston/zalloc.h.
    
    Now xalloc.h does not depend on any libweston header, which makes me
    feel slightly better. It's more clean.
    
    Who knows, maybe one day libweston/zalloc.h will be removed.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    fc26c749
  • Pekka Paalanen's avatar
    README: establish no-malloc-failures policy · 93587067
    Pekka Paalanen authored
    There are many reasons why trying to handle malloc() returning NULL by
    any other way than calling abort() is not beneficial:
    
    - Usually malloc() does not return NULL, thanks to memory overcommit.
      Instead, the program gets SIGSEGV signal when it tries to access the
      memory.
    
    - Trying to handle NULL will create failure paths that are impractical
      to test. There is no way to be sure the compositor still works once
      such path is actually taken.
    
    - Those failure path will clutter the code, increasing maintenance and
      development burden.
    
    - Sometimes there just isn't a good way to handle the failure.
    
    For more discussion, see the issue link below.
    
    Closes: wayland/weston#631
    
    
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    93587067
......@@ -208,6 +208,10 @@ my_function(void)
parameter3, parameter4);
```
- do not write fallback paths for failed simple memory allocations, use the
`x*alloc()` wrappers from `shared/xalloc.h` instead or use
`abort_oom_if_null()`
Conduct
=======
......
......@@ -18,6 +18,12 @@ bugs and shortcomings, we avoid unknown or variable behaviour as much as
possible, including variable performance such as occasional spikes in frame
display time.
Weston and libweston are not suitable for memory constrained environments
where the compositor is expected to continue running even in the face of
trivial memory allocations failing. If standard functions like `malloc()`
fail for small allocations,
[you can expect libweston to abort](https://gitlab.freedesktop.org/wayland/weston/-/issues/631).
A small suite of example or demo clients are also provided: though they can be
useful in themselves, their main purpose is to be an example or test case for
others building compositors or clients.
......@@ -307,8 +313,6 @@ There are still many more details to be decided.
For packagers
-------------
Always build Weston with --with-cairo=image.
The Weston project is (will be) intended to be split into several
binary packages, each with its own dependencies. The maximal split
would be roughly like this:
......
......@@ -75,11 +75,9 @@ create_shm_buffer(struct touch *touch)
struct wl_shm_pool *pool;
int fd, size, stride;
void *data;
struct buffer *buffer = NULL;
struct buffer *buffer;
buffer = zalloc(sizeof(*buffer));
if (!buffer)
return NULL;
buffer = xzalloc(sizeof(*buffer));
stride = touch->width * 4;
size = stride * touch->height;
......
......@@ -5081,14 +5081,14 @@ window_create(struct display *display)
window->xdg_surface =
xdg_wm_base_get_xdg_surface(window->display->xdg_shell,
window->main_surface->surface);
fail_on_null(window->xdg_surface, 0, __FILE__, __LINE__);
abort_oom_if_null(window->xdg_surface);
xdg_surface_add_listener(window->xdg_surface,
&xdg_surface_listener, window);
window->xdg_toplevel =
xdg_surface_get_toplevel(window->xdg_surface);
fail_on_null(window->xdg_toplevel, 0, __FILE__, __LINE__);
abort_oom_if_null(window->xdg_toplevel);
xdg_toplevel_add_listener(window->xdg_toplevel,
&xdg_toplevel_listener, window);
......@@ -5293,7 +5293,7 @@ create_menu(struct display *display,
menu->widget = window_add_widget(menu->window, menu);
menu->frame = frame_create(window->display->theme, 0, 0,
FRAME_BUTTON_NONE, NULL, NULL);
fail_on_null(menu->frame, 0, __FILE__, __LINE__);
abort_oom_if_null(menu->frame);
menu->entries = entries;
menu->count = count;
menu->release_count = 0;
......@@ -5327,7 +5327,7 @@ create_simple_positioner(struct display *display,
struct xdg_positioner *positioner;
positioner = xdg_wm_base_create_positioner(display->xdg_shell);
fail_on_null(positioner, 0, __FILE__, __LINE__);
abort_oom_if_null(positioner);
xdg_positioner_set_anchor_rect(positioner, x, y, 1, 1);
xdg_positioner_set_size(positioner, w, h);
xdg_positioner_set_anchor(positioner,
......@@ -5372,7 +5372,7 @@ window_show_menu(struct display *display,
window->xdg_surface =
xdg_wm_base_get_xdg_surface(display->xdg_shell,
window->main_surface->surface);
fail_on_null(window->xdg_surface, 0, __FILE__, __LINE__);
abort_oom_if_null(window->xdg_surface);
xdg_surface_add_listener(window->xdg_surface,
&xdg_surface_listener, window);
......@@ -5385,7 +5385,7 @@ window_show_menu(struct display *display,
window->xdg_popup = xdg_surface_get_popup(window->xdg_surface,
parent->xdg_surface,
positioner);
fail_on_null(window->xdg_popup, 0, __FILE__, __LINE__);
abort_oom_if_null(window->xdg_popup);
xdg_positioner_destroy(positioner);
xdg_popup_grab(window->xdg_popup, input->seat,
display_get_serial(window->display));
......
......@@ -153,13 +153,6 @@ struct launcher_info {
/*****************************************************************************
* local functions
****************************************************************************/
static void *
mem_alloc(size_t size, char *file, int32_t line)
{
return fail_on_null(calloc(1, size), size, file, line);
}
#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
static int32_t
is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
......@@ -222,8 +215,8 @@ mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
int32_t surf_num = 0;
int32_t idx = 0;
surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
surfaces = xcalloc(surface_length, sizeof(*surfaces));
new_order = xcalloc(surface_length, sizeof(*surfaces));
for (i = 0; i < surface_length; i++) {
ivisurf = pp_surface[i];
......@@ -297,8 +290,8 @@ mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
int32_t surf_num = 0;
int32_t idx = 0;
surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
surfaces = xcalloc(surface_length, sizeof(*surfaces));
new_order = xcalloc(surface_length, sizeof(*surfaces));
for (i = 0; i < surface_length; i++) {
ivisurf = pp_surface[i];
......@@ -362,7 +355,7 @@ mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
int32_t surf_num = 0;
struct ivi_layout_surface **surfaces;
surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
surfaces = xcalloc(surface_length, sizeof(*surfaces));
for (i = 0; i < surface_length; i++) {
ivisurf = pp_surface[i];
......@@ -412,7 +405,7 @@ mode_random_replace(struct hmi_controller *hmi_ctrl,
int32_t i = 0;
int32_t layer_idx = 0;
layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
layers = xcalloc(hmi_ctrl->screen_num, sizeof(*layers));
wl_list_for_each(application_layer, layer_list, link) {
layers[layer_idx] = application_layer;
......@@ -689,7 +682,7 @@ set_notification_configure_desktop_surface(struct wl_listener *listener, void *d
static struct hmi_server_setting *
hmi_server_setting_create(struct weston_compositor *ec)
{
struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
struct hmi_server_setting *setting = xzalloc(sizeof(*setting));
struct weston_config *config = wet_get_config(ec);
struct weston_config_section *shell_section = NULL;
char *ivi_ui_config;
......@@ -804,7 +797,7 @@ hmi_controller_create(struct weston_compositor *ec)
return NULL;
}
hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
hmi_ctrl = xzalloc(sizeof(*hmi_ctrl));
i = 0;
wl_array_init(&hmi_ctrl->ui_widgets);
......@@ -817,7 +810,7 @@ hmi_controller_create(struct weston_compositor *ec)
/* init base ivi_layer*/
wl_list_init(&hmi_ctrl->base_layer_list);
wl_list_for_each(output, &ec->output_list, link) {
base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
base_layer = xzalloc(sizeof(struct hmi_controller_layer));
base_layer->x = 0;
base_layer->y = 0;
base_layer->width = output->current_mode->width;
......@@ -837,7 +830,7 @@ hmi_controller_create(struct weston_compositor *ec)
/* init application ivi_layer */
wl_list_init(&hmi_ctrl->application_layer_list);
wl_list_for_each(output, &ec->output_list, link) {
application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
application_layer = xzalloc(sizeof(struct hmi_controller_layer));
application_layer->x = 0;
application_layer->y = 0;
application_layer->width = output->current_mode->width;
......@@ -872,7 +865,7 @@ hmi_controller_create(struct weston_compositor *ec)
wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
tmp_link_layer = xzalloc(sizeof(*tmp_link_layer));
tmp_link_layer->layout_layer =
hmi_ctrl->workspace_background_layer.ivilayer;
wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
......@@ -1267,7 +1260,7 @@ ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
hmi_ctrl->interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
false);
tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
tmp_link_layer = xzalloc(sizeof(*tmp_link_layer));
tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
&tmp_link_layer->link);
......@@ -1756,7 +1749,7 @@ create_workspace_pointer_move(struct weston_pointer *pointer,
struct wl_resource* resource)
{
struct pointer_move_grab *pnt_move_grab =
MEM_ALLOC(sizeof(*pnt_move_grab));
xzalloc(sizeof(*pnt_move_grab));
pnt_move_grab->base.resource = resource;
move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
......@@ -1770,7 +1763,7 @@ create_workspace_touch_move(struct weston_touch *touch,
struct wl_resource* resource)
{
struct touch_move_grab *tch_move_grab =
MEM_ALLOC(sizeof(*tch_move_grab));
xzalloc(sizeof(*tch_move_grab));
tch_move_grab->base.resource = resource;
tch_move_grab->is_active = 1;
......
/*
* Copyright © 2008 Kristian Høgsberg
* Copyright 2022 Collabora, Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
......@@ -31,34 +32,30 @@ extern "C" {
#endif
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libweston/zalloc.h>
static inline void *
fail_on_null(void *p, size_t size, char *file, int32_t line)
abort_oom_if_null(void *p)
{
if (p == NULL) {
fprintf(stderr, "[%s] ", program_invocation_short_name);
if (file)
fprintf(stderr, "%s:%d: ", file, line);
fprintf(stderr, "out of memory");
if (size)
fprintf(stderr, " (%zd)", size);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
static const char oommsg[] = ": out of memory\n";
if (p)
return p;
write(STDERR_FILENO, program_invocation_short_name,
strlen(program_invocation_short_name));
write(STDERR_FILENO, oommsg, strlen(oommsg));
return p;
abort();
}
#define xmalloc(s) (fail_on_null(malloc(s), (s), __FILE__, __LINE__))
#define xzalloc(s) (fail_on_null(zalloc(s), (s), __FILE__, __LINE__))
#define xstrdup(s) (fail_on_null(strdup(s), 0, __FILE__, __LINE__))
#define xrealloc(p, s) (fail_on_null(realloc(p, s), (s), __FILE__, __LINE__))
#define xmalloc(s) (abort_oom_if_null(malloc(s)))
#define xzalloc(s) (abort_oom_if_null(calloc(1, s)))
#define xcalloc(n, s) (abort_oom_if_null(calloc(n, s)))
#define xstrdup(s) (abort_oom_if_null(strdup(s)))
#define xrealloc(p, s) (abort_oom_if_null(realloc(p, s)))
#ifdef __cplusplus
}
......