(root)/
glib-2.79.0/
glib/
tests/
messages-low-memory.c
       1  /* Unit tests for gmessages on low-memory
       2   *
       3   * Copyright (C) 2022 Marco Trevisan
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Lesser General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2.1 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Lesser General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Lesser General
      18   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19   *
      20   * Author: Marco Trevisan <marco.trevisan@canonical.com>
      21   */
      22  
      23  #include "config.h"
      24  
      25  #include <dlfcn.h>
      26  #include <glib.h>
      27  
      28  static gboolean malloc_eom = FALSE;
      29  static gboolean our_malloc_called = FALSE;
      30  
      31  #ifdef ENOMEM
      32  /* Wrapper around malloc() which returns `ENOMEM` if the test variable
      33   * `malloc_eom` is set.
      34   * Otherwise passes through to the normal malloc() in libc.
      35   */
      36  
      37  void *
      38  malloc (size_t size)
      39  {
      40    static void *(*real_malloc)(size_t);
      41    if (!real_malloc)
      42        real_malloc = dlsym (RTLD_NEXT, "malloc");
      43  
      44    if (malloc_eom)
      45      {
      46        our_malloc_called = TRUE;
      47        errno = ENOMEM;
      48        return NULL;
      49      }
      50  
      51    return real_malloc (size);
      52  }
      53  #endif
      54  
      55  int
      56  main (int   argc,
      57        char *argv[])
      58  {
      59    /* We expect this test to abort, so try to avoid that creating a coredump */
      60    g_test_disable_crash_reporting ();
      61  
      62    g_setenv ("LC_ALL", "C", TRUE);
      63  
      64  #ifndef ENOMEM
      65    g_message ("ENOMEM Not defined, test skipped");
      66    return 77;
      67  #endif
      68  
      69    g_message ("Simulates a situation in which we were crashing because "
      70               "of low-memory, leading malloc to fail instead of aborting");
      71    g_message ("bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2753");
      72  
      73    /* Setting `malloc_eom` to true should cause the override `malloc()`
      74     * in this file to fail on the allocation on the next line. */
      75    malloc_eom = TRUE;
      76    g_message ("Memory is exhausted, but we'll write anyway: %u", 123);
      77  
      78  #ifndef __linux__
      79    if (!our_malloc_called)
      80      {
      81        /* For some reasons this doesn't work darwin systems, so ignore the result
      82         * for non-linux, while we want to ensure the test is valid at least there
      83         */
      84        g_message ("Our malloc implementation has not been called, the test "
      85                   "has not been performed");
      86        return 77;
      87      }
      88  #endif
      89  
      90    return 0;
      91  }