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 }