Coverage Report

Created: 2026-07-12 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pacemaker/include/crm/common/memory_internal.h
Line
Count
Source
1
/*
2
 * Copyright 2015-2026 the Pacemaker project contributors
3
 *
4
 * The version control history for this file may have further details.
5
 *
6
 * This source code is licensed under the GNU Lesser General Public License
7
 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8
 */
9
10
#ifndef PCMK__INCLUDED_CRM_COMMON_INTERNAL_H
11
#error "Include <crm/common/internal.h> instead of <memory_internal.h> directly"
12
#endif
13
14
#ifndef PCMK__CRM_COMMON_MEMORY_INTERNAL__H
15
#define PCMK__CRM_COMMON_MEMORY_INTERNAL__H
16
17
#include <stddef.h>                         // size_t
18
#include <stdint.h>                         // uint32_t
19
#include <stdlib.h>                         // abort, calloc, free, realloc
20
21
#include <glib.h>                           // FALSE, TRUE
22
23
#include <crm/common/results.h>             // CRM_EX_OSERR, crm_abort, crm_exit
24
#include <crm/common/results_internal.h>    // pcmk__assert
25
26
#ifdef __cplusplus
27
extern "C" {
28
#endif
29
30
/*!
31
 * \internal
32
 * \brief Abort without dumping core if a pointer is \c NULL
33
 *
34
 * This is intended to check for memory allocation failure, rather than for null
35
 * pointers in general.
36
 *
37
 * \param[in] ptr  Pointer to check
38
 */
39
0
#define pcmk__mem_assert(ptr) do {                                          \
40
0
        if ((ptr) == NULL) {                                                \
41
0
            crm_abort(__FILE__, __func__, __LINE__, "Out of memory", FALSE, \
42
0
                      TRUE);                                                \
43
0
            crm_exit(CRM_EX_OSERR);                                         \
44
0
        }                                                                   \
45
0
    } while (0)
46
47
/*!
48
 * \internal
49
 * \brief Allocate new zero-initialized memory, asserting on failure
50
 *
51
 * \param[in] file      File where \p function is located
52
 * \param[in] function  Calling function
53
 * \param[in] line      Line within \p file
54
 * \param[in] nmemb     Number of elements to allocate memory for
55
 * \param[in] size      Size of each element
56
 *
57
 * \return Newly allocated memory of of size <tt>nmemb * size</tt> (guaranteed
58
 *         not to be \c NULL)
59
 *
60
 * \note The caller is responsible for freeing the return value using \c free().
61
 */
62
static inline void *
63
pcmk__assert_alloc_as(const char *file, const char *function, uint32_t line,
64
                      size_t nmemb, size_t size)
65
2.35k
{
66
2.35k
    void *ptr = calloc(nmemb, size);
67
68
2.35k
    if (ptr == NULL) {
69
0
        crm_abort(file, function, line, "Out of memory", FALSE, TRUE);
70
0
        crm_exit(CRM_EX_OSERR);
71
0
    }
72
2.35k
    return ptr;
73
2.35k
}
scores_fuzzer.c:pcmk__assert_alloc_as
Line
Count
Source
65
176
{
66
176
    void *ptr = calloc(nmemb, size);
67
68
176
    if (ptr == NULL) {
69
0
        crm_abort(file, function, line, "Out of memory", FALSE, TRUE);
70
0
        crm_exit(CRM_EX_OSERR);
71
0
    }
72
176
    return ptr;
73
176
}
Unexecuted instantiation: results.c:pcmk__assert_alloc_as
Unexecuted instantiation: scores.c:pcmk__assert_alloc_as
Unexecuted instantiation: strings.c:pcmk__assert_alloc_as
utils.c:pcmk__assert_alloc_as
Line
Count
Source
65
23
{
66
23
    void *ptr = calloc(nmemb, size);
67
68
23
    if (ptr == NULL) {
69
0
        crm_abort(file, function, line, "Out of memory", FALSE, TRUE);
70
0
        crm_exit(CRM_EX_OSERR);
71
0
    }
72
23
    return ptr;
73
23
}
iso8601.c:pcmk__assert_alloc_as
Line
Count
Source
65
892
{
66
892
    void *ptr = calloc(nmemb, size);
67
68
892
    if (ptr == NULL) {
69
0
        crm_abort(file, function, line, "Out of memory", FALSE, TRUE);
70
0
        crm_exit(CRM_EX_OSERR);
71
0
    }
72
892
    return ptr;
73
892
}
Unexecuted instantiation: logging.c:pcmk__assert_alloc_as
Unexecuted instantiation: mainloop.c:pcmk__assert_alloc_as
Unexecuted instantiation: options.c:pcmk__assert_alloc_as
Unexecuted instantiation: output.c:pcmk__assert_alloc_as
Unexecuted instantiation: output_log.c:pcmk__assert_alloc_as
Unexecuted instantiation: output_text.c:pcmk__assert_alloc_as
Unexecuted instantiation: output_xml.c:pcmk__assert_alloc_as
Unexecuted instantiation: patchset_display.c:pcmk__assert_alloc_as
Unexecuted instantiation: schemas.c:pcmk__assert_alloc_as
Unexecuted instantiation: xml.c:pcmk__assert_alloc_as
Unexecuted instantiation: xml_attr.c:pcmk__assert_alloc_as
Unexecuted instantiation: xml_comment.c:pcmk__assert_alloc_as
Unexecuted instantiation: xml_display.c:pcmk__assert_alloc_as
Unexecuted instantiation: xml_element.c:pcmk__assert_alloc_as
Unexecuted instantiation: xml_idref.c:pcmk__assert_alloc_as
Unexecuted instantiation: xml_io.c:pcmk__assert_alloc_as
Unexecuted instantiation: xpath.c:pcmk__assert_alloc_as
Unexecuted instantiation: acl.c:pcmk__assert_alloc_as
Unexecuted instantiation: actions.c:pcmk__assert_alloc_as
Unexecuted instantiation: agents.c:pcmk__assert_alloc_as
Unexecuted instantiation: cmdline.c:pcmk__assert_alloc_as
Unexecuted instantiation: digest.c:pcmk__assert_alloc_as
Unexecuted instantiation: health.c:pcmk__assert_alloc_as
Unexecuted instantiation: io.c:pcmk__assert_alloc_as
Unexecuted instantiation: ipc_client.c:pcmk__assert_alloc_as
Unexecuted instantiation: ipc_common.c:pcmk__assert_alloc_as
Unexecuted instantiation: ipc_controld.c:pcmk__assert_alloc_as
Unexecuted instantiation: ipc_pacemakerd.c:pcmk__assert_alloc_as
Unexecuted instantiation: ipc_schedulerd.c:pcmk__assert_alloc_as
Unexecuted instantiation: ipc_server.c:pcmk__assert_alloc_as
Unexecuted instantiation: messages.c:pcmk__assert_alloc_as
Unexecuted instantiation: nodes.c:pcmk__assert_alloc_as
Unexecuted instantiation: nvpair.c:pcmk__assert_alloc_as
Unexecuted instantiation: options_display.c:pcmk__assert_alloc_as
Unexecuted instantiation: patchset.c:pcmk__assert_alloc_as
Unexecuted instantiation: procfs.c:pcmk__assert_alloc_as
Unexecuted instantiation: rules.c:pcmk__assert_alloc_as
Unexecuted instantiation: servers.c:pcmk__assert_alloc_as
Unexecuted instantiation: cib.c:pcmk__assert_alloc_as
Unexecuted instantiation: ipc_attrd.c:pcmk__assert_alloc_as
Unexecuted instantiation: pid.c:pcmk__assert_alloc_as
Unexecuted instantiation: attrs.c:pcmk__assert_alloc_as
strings_fuzzer.c:pcmk__assert_alloc_as
Line
Count
Source
65
1.24k
{
66
1.24k
    void *ptr = calloc(nmemb, size);
67
68
1.24k
    if (ptr == NULL) {
69
0
        crm_abort(file, function, line, "Out of memory", FALSE, TRUE);
70
0
        crm_exit(CRM_EX_OSERR);
71
0
    }
72
1.24k
    return ptr;
73
1.24k
}
cib_file_fuzzer.c:pcmk__assert_alloc_as
Line
Count
Source
65
23
{
66
23
    void *ptr = calloc(nmemb, size);
67
68
23
    if (ptr == NULL) {
69
0
        crm_abort(file, function, line, "Out of memory", FALSE, TRUE);
70
0
        crm_exit(CRM_EX_OSERR);
71
0
    }
72
23
    return ptr;
73
23
}
Unexecuted instantiation: cib_client.c:pcmk__assert_alloc_as
Unexecuted instantiation: cib_file.c:pcmk__assert_alloc_as
Unexecuted instantiation: cib_native.c:pcmk__assert_alloc_as
Unexecuted instantiation: cib_ops.c:pcmk__assert_alloc_as
Unexecuted instantiation: cib_remote.c:pcmk__assert_alloc_as
Unexecuted instantiation: cib_utils.c:pcmk__assert_alloc_as
Unexecuted instantiation: remote.c:pcmk__assert_alloc_as
Unexecuted instantiation: tls.c:pcmk__assert_alloc_as
Unexecuted instantiation: watchdog.c:pcmk__assert_alloc_as
Unexecuted instantiation: iso8601_fuzzer.c:pcmk__assert_alloc_as
74
75
/*!
76
 * \internal
77
 * \brief Allocate new zero-initialized memory, asserting on failure
78
 *
79
 * \param[in] nmemb  Number of elements to allocate memory for
80
 * \param[in] size   Size of each element
81
 *
82
 * \return Newly allocated memory of of size <tt>nmemb * size</tt> (guaranteed
83
 *         not to be \c NULL)
84
 *
85
 * \note The caller is responsible for freeing the return value using \c free().
86
 */
87
#define pcmk__assert_alloc(nmemb, size) \
88
4.88k
    pcmk__assert_alloc_as(__FILE__, __func__, __LINE__, nmemb, size)
89
90
/*!
91
 * \internal
92
 * \brief Resize a dynamically allocated memory block
93
 *
94
 * \param[in] ptr   Memory block to resize (or NULL to allocate new memory)
95
 * \param[in] size  New size of memory block in bytes (must be > 0)
96
 *
97
 * \return Pointer to resized memory block
98
 *
99
 * \note This asserts on error, so the result is guaranteed to be non-NULL
100
 *       (which is the main advantage of this over directly using realloc()).
101
 */
102
static inline void *
103
pcmk__realloc(void *ptr, size_t size)
104
0
{
105
0
    void *new_ptr;
106
107
    // realloc(p, 0) can replace free(p) but this wrapper can't
108
0
    pcmk__assert(size > 0);
109
110
0
    new_ptr = realloc(ptr, size);
111
0
    if (new_ptr == NULL) {
112
0
        free(ptr);
113
0
        abort();
114
0
    }
115
0
    return new_ptr;
116
0
}
Unexecuted instantiation: scores_fuzzer.c:pcmk__realloc
Unexecuted instantiation: results.c:pcmk__realloc
Unexecuted instantiation: scores.c:pcmk__realloc
Unexecuted instantiation: strings.c:pcmk__realloc
Unexecuted instantiation: utils.c:pcmk__realloc
Unexecuted instantiation: iso8601.c:pcmk__realloc
Unexecuted instantiation: logging.c:pcmk__realloc
Unexecuted instantiation: mainloop.c:pcmk__realloc
Unexecuted instantiation: options.c:pcmk__realloc
Unexecuted instantiation: output.c:pcmk__realloc
Unexecuted instantiation: output_log.c:pcmk__realloc
Unexecuted instantiation: output_text.c:pcmk__realloc
Unexecuted instantiation: output_xml.c:pcmk__realloc
Unexecuted instantiation: patchset_display.c:pcmk__realloc
Unexecuted instantiation: schemas.c:pcmk__realloc
Unexecuted instantiation: xml.c:pcmk__realloc
Unexecuted instantiation: xml_attr.c:pcmk__realloc
Unexecuted instantiation: xml_comment.c:pcmk__realloc
Unexecuted instantiation: xml_display.c:pcmk__realloc
Unexecuted instantiation: xml_element.c:pcmk__realloc
Unexecuted instantiation: xml_idref.c:pcmk__realloc
Unexecuted instantiation: xml_io.c:pcmk__realloc
Unexecuted instantiation: xpath.c:pcmk__realloc
Unexecuted instantiation: acl.c:pcmk__realloc
Unexecuted instantiation: actions.c:pcmk__realloc
Unexecuted instantiation: agents.c:pcmk__realloc
Unexecuted instantiation: cmdline.c:pcmk__realloc
Unexecuted instantiation: digest.c:pcmk__realloc
Unexecuted instantiation: health.c:pcmk__realloc
Unexecuted instantiation: io.c:pcmk__realloc
Unexecuted instantiation: ipc_client.c:pcmk__realloc
Unexecuted instantiation: ipc_common.c:pcmk__realloc
Unexecuted instantiation: ipc_controld.c:pcmk__realloc
Unexecuted instantiation: ipc_pacemakerd.c:pcmk__realloc
Unexecuted instantiation: ipc_schedulerd.c:pcmk__realloc
Unexecuted instantiation: ipc_server.c:pcmk__realloc
Unexecuted instantiation: messages.c:pcmk__realloc
Unexecuted instantiation: nodes.c:pcmk__realloc
Unexecuted instantiation: nvpair.c:pcmk__realloc
Unexecuted instantiation: options_display.c:pcmk__realloc
Unexecuted instantiation: patchset.c:pcmk__realloc
Unexecuted instantiation: procfs.c:pcmk__realloc
Unexecuted instantiation: rules.c:pcmk__realloc
Unexecuted instantiation: servers.c:pcmk__realloc
Unexecuted instantiation: cib.c:pcmk__realloc
Unexecuted instantiation: ipc_attrd.c:pcmk__realloc
Unexecuted instantiation: pid.c:pcmk__realloc
Unexecuted instantiation: attrs.c:pcmk__realloc
Unexecuted instantiation: strings_fuzzer.c:pcmk__realloc
Unexecuted instantiation: cib_file_fuzzer.c:pcmk__realloc
Unexecuted instantiation: cib_client.c:pcmk__realloc
Unexecuted instantiation: cib_file.c:pcmk__realloc
Unexecuted instantiation: cib_native.c:pcmk__realloc
Unexecuted instantiation: cib_ops.c:pcmk__realloc
Unexecuted instantiation: cib_remote.c:pcmk__realloc
Unexecuted instantiation: cib_utils.c:pcmk__realloc
Unexecuted instantiation: remote.c:pcmk__realloc
Unexecuted instantiation: tls.c:pcmk__realloc
Unexecuted instantiation: watchdog.c:pcmk__realloc
Unexecuted instantiation: iso8601_fuzzer.c:pcmk__realloc
117
118
#ifdef __cplusplus
119
}
120
#endif
121
122
#endif // PCMK__CRM_COMMON_MEMORY_INTERNAL__H