• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thoni56 / c-xrefactory / 1797

20 May 2026 01:10PM UTC coverage: 85.479% (+0.2%) from 85.242%
1797

push

travis-ci

thoni56
[memory][overflow] Rename to outOfMemoryErrorHandler

16317 of 19089 relevant lines covered (85.48%)

15996254.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.54
src/memory.c
1
#include "memory.h"
2

3
#include <stdlib.h>
4

5
#include "log.h"
6
#include "head.h"
7
#include "constants.h"
8
#include "proto.h"
9

10

11

12
/* Dynamic memory for cross-references and similar stuff */
13
Memory cxMemory={};
14

15
/* Preprocessor memory */
16
Memory ppmMemory;
17

18

19
/* This is used unless outOfMemoryErrorHandler is set */
20
static void defaultOutOfMemoryErrorHandler(int errorCode, char *message, int exitStatus, char *file, int line) {
×
21
    log_fatal("Error code: %d, Message: '%s' in file %s", errorCode, message, file);
×
22
    exit(exitStatus);
×
23
}
24

25
/* Inject the function to call when fatalErrors occur */
26
static void (*outOfMemoryErrorHandler)(int errCode, char *mess, int exitStatus, char *file, int line) = defaultOutOfMemoryErrorHandler;
27
void setOutOfMemoryErrorHandlerForMemory(void (*function)(int errCode, char *mess, int exitStatus, char *file, int line)) {
240✔
28
    outOfMemoryErrorHandler = function;
240✔
29
}
240✔
30

31
/* Copy of a few defines from commons.h to avoid dependency on other stuff... */
32
#undef assert
33
#define assert(expr)                                                                                    \
34
    if (!(expr))                                                                                        \
35
        internalCheckFailForMemory(#expr, __FILE__, __LINE__)
36

37
/* Inject the function to call when assert() fails, a.k.a internalCheckFail() */
38
static void (*internalCheckFailForMemory)(char *expr, char *file, int line);
39
void setInternalCheckFailHandlerForMemory(void (*function)(char *expr, char *file, int line)) {
237✔
40
    internalCheckFailForMemory = function;
237✔
41
}
237✔
42

43

44
/* *****************************************************************
45

46
   Memory - this memory type has a dynamic area allocated separately from the Memory
47
            struct in which allocation takes place by moving the index.
48

49
 */
50

51
void memoryInit(Memory *memory, char *name, size_t size) {
15,192,346✔
52
    ENTER();
15,192,346✔
53
    log_debug("Init %s with new name '%s' and size %d", memory->name, name, size);
15,192,346✔
54
    memory->name = name;
15,192,346✔
55
    if (size > memory->size) {
15,192,346✔
56
        memory->area = realloc(memory->area, size);
1,607✔
57
        memory->size = size;
1,607✔
58
    }
59
    memory->index = 0;
15,192,346✔
60
    LEAVE();
15,192,346✔
61
}
15,192,346✔
62

63
void *memoryAllocc(Memory *memory, int count, size_t size) {
224,813,446✔
64
    void *pointer = &memory->area[memory->index];
224,813,446✔
65
    assert(size > 0);
66
    assert(count >= 0);
224,813,446✔
67

1✔
68
    if (memory->index+count*size > memory->size) {
69
        outOfMemoryErrorHandler(ERR_NO_MEMORY, memory->name, EXIT_FAILURE, __FILE__, __LINE__);
224,813,446✔
70
    }
224,813,446✔
71
    memory->index += count*size;
3,965,162✔
72
    if (memory->index > memory->max)
73
        memory->max = memory->index;
224,813,446✔
74

75
    return pointer;
76
}
60,851,104✔
77

60,851,104✔
78
void *memoryAlloc(Memory *memory, size_t size) {
79
    return memoryAllocc(memory, 1, size);
80
}
82,936,191✔
81

82,936,191✔
82
bool memoryIsBetween(Memory *memory, void *pointer, int low, int high) {
83
    return pointer >= (void *)&memory->area[low] && pointer <= (void *)&memory->area[high];
84
}
71,378,121✔
85

71,378,121✔
86
static bool isInMemory(Memory *memory, void *pointer) {
87
    return memoryIsBetween(memory, pointer, 0, memory->index);
88
}
71,378,121✔
89

71,378,121✔
90
size_t memoryFreeUntil(Memory *memory, void *pointer) {
91
    assert(isInMemory(memory, pointer));
71,378,120✔
92
    /* Ensure we're not freeing beyond current allocations (marker must be <= current index) */
71,378,120✔
93
    int markerOffset = (char *)pointer - (char *)memory->area;
×
94
    if (markerOffset > memory->index) {
95
        log_fatal("Attempting to free '%s' arena until offset %d, but current index is only %d.",
×
96
                  memory->name, markerOffset, memory->index);
×
97
        log_fatal("This means the marker is beyond allocated memory - likely a marker from a different arena or corrupted.");
98
        assert(markerOffset <= memory->index);
71,378,120✔
99
    }
71,378,120✔
100
    int oldIndex = memory->index;
71,378,120✔
101
    memory->index = markerOffset;
102
    return oldIndex - memory->index;  // Amount freed (rolled back)
103
}
11,207,322✔
104

11,207,322✔
105
static bool memoryPointerIsFreed(Memory *memory, void *pointer) {
106
    return memoryIsBetween(memory, pointer, memory->index, memory->size);
107
}
108

109,378,592✔
109
/* Reallocates the most recently allocated area in 'memory' to be different size */
110
void *memoryRealloc(Memory *memory, void *pointer, size_t oldSize, size_t newSize) {
111
    /* Arena allocators can only resize the most recent allocation (top-of-stack).
112
     * If this fails, check if ppmFreeUntil() was called too late, freeing allocations
109,378,592✔
113
     * made AFTER the buffer being resized. The buffer must be at top-of-stack to grow. */
1✔
114
    if (pointer != &memory->area[memory->index-oldSize]) {
115
        log_fatal("Attempting to resize buffer %p (size=%zu) in '%s' arena, but it is not the most recent allocation.",
1✔
116
                  pointer, oldSize, memory->name);
117
        log_fatal("Expected buffer at %p (index=%d - oldSize=%zu = %d), but current top-of-stack is at %p (index=%d).",
118
                  &memory->area[memory->index-oldSize], memory->index, oldSize, memory->index - (int)oldSize,
1✔
119
                  &memory->area[memory->index], memory->index);
1✔
120
        log_fatal("This usually means allocations made after the buffer need to be freed first (e.g., move ppmFreeUntil() earlier).");
121
        assert(pointer == &memory->area[memory->index-oldSize]);
109,378,591✔
122
    }
109,378,591✔
123
    memory->index += newSize - oldSize;
124
    return pointer;
125
}
126

85,488,623✔
127
// Used by ppmReallocc()
85,488,623✔
128
static void *memoryReallocc(Memory *memory, void *pointer, int newCount, size_t size, int oldCount) {
129
    return memoryRealloc(memory, pointer, oldCount*size, newCount*size);
130
}
131

34,921,761✔
132
/* Preprocessor Macro Memory */
34,921,761✔
133
void *ppmAlloc(size_t size) {
134
    return memoryAlloc(&ppmMemory, size);
135
}
160,178,451✔
136

160,178,451✔
137
void *ppmAllocc(int count, size_t size) {
138
    return memoryAllocc(&ppmMemory, count, size);
139
}
85,488,623✔
140

85,488,623✔
141
void *ppmReallocc(void *pointer, int newCount, size_t size, int oldCount) {
142
    return memoryReallocc(&ppmMemory, pointer, newCount, size, oldCount);
143
}
47,590,173✔
144

47,590,173✔
145
int ppmFreeUntil(void *pointer) {
146
    return memoryFreeUntil(&ppmMemory, pointer);
147
}
11,207,322✔
148

11,207,322✔
149
bool ppmIsFreedPointer(void *pointer) {
150
    return memoryPointerIsFreed(&ppmMemory, pointer);
151
}
152

153

249✔
154
/* CX */
249✔
155
void initCxMemory(size_t size) {
249✔
156
    memoryInit(&cxMemory, "cxMemory", size);
157
}
3,775,327✔
158

3,775,327✔
159
void *cxAlloc(size_t size) {
160
    return memoryAllocc(&cxMemory, size, 1);
161
}
31,193✔
162

31,193✔
163
bool cxMemoryPointerIsBetween(void *pointer, int low, int high) {
164
    return memoryIsBetween(&cxMemory, pointer, low, high);
165
}
×
166

×
167
void cxFreeUntil(void *pointer) {
168
    (void)memoryFreeUntil(&cxMemory, pointer);
169
}
×
170

×
171
void printMemoryStatisticsFor(Memory *memory) {
172
    printf("Max memory use for %s : %d\n", memory->name, memory->max);
173
}
×
174

×
175
void printMemoryStatistics(void) {
×
176
    printMemoryStatisticsFor(&cxMemory);
177
    printMemoryStatisticsFor(&ppmMemory);
178
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc