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

cpputest / cpputest / 10776895588

09 Sep 2024 04:02PM UTC coverage: 99.279%. First build
10776895588

Pull #1810

github

web-flow
Revert "Encode newlines for -ojunit as their XML equivalent instead of {newline}"
Pull Request #1810: Revert "Encode newlines for -ojunit as their XML equivalent instead of {newline}"

1 of 1 new or added line in 1 file covered. (100.0%)

6748 of 6797 relevant lines covered (99.28%)

18724.05 hits per line

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

99.06
/src/CppUTest/MemoryLeakWarningPlugin.cpp
1
/*
2
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *     * Redistributions of source code must retain the above copyright
8
 *       notice, this list of conditions and the following disclaimer.
9
 *     * Redistributions in binary form must reproduce the above copyright
10
 *       notice, this list of conditions and the following disclaimer in the
11
 *       documentation and/or other materials provided with the distribution.
12
 *     * Neither the name of the <organization> nor the
13
 *       names of its contributors may be used to endorse or promote products
14
 *       derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ''AS IS'' AND ANY
17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
20
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27

28
#include "CppUTest/TestHarness.h"
29
#include "CppUTest/MemoryLeakWarningPlugin.h"
30
#include "CppUTest/MemoryLeakDetector.h"
31
#include "CppUTest/TestMemoryAllocator.h"
32
#include "CppUTest/PlatformSpecificFunctions.h"
33
#include "CppUTest/SimpleMutex.h"
34

35
/********** Enabling and disabling for C also *********/
36

37
#if CPPUTEST_USE_MEM_LEAK_DETECTION
38

39
class MemLeakScopedMutex
40
{
41
public:
42
    MemLeakScopedMutex() : lock(MemoryLeakWarningPlugin::getGlobalDetector()->getMutex()) { }
15✔
43
private:
44
    ScopedMutexLock lock;
45
};
46

47
static void* threadsafe_mem_leak_malloc(size_t size, const char* file, size_t line)
1✔
48
{
49
    MemLeakScopedMutex lock;
1✔
50
    return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentMallocAllocator(), size, file, line, true);
2✔
51
}
1✔
52

53
static void threadsafe_mem_leak_free(void* buffer, const char* file, size_t line)
1✔
54
{
55
    MemLeakScopedMutex lock;
1✔
56
    MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) buffer);
1✔
57
    MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentMallocAllocator(), (char*) buffer, file, line, true);
1✔
58
}
1✔
59

60
static void* threadsafe_mem_leak_realloc(void* memory, size_t size, const char* file, size_t line)
1✔
61
{
62
    MemLeakScopedMutex lock;
1✔
63
    return MemoryLeakWarningPlugin::getGlobalDetector()->reallocMemory(getCurrentMallocAllocator(), (char*) memory, size, file, line, true);
2✔
64
}
1✔
65

66

67
static void* mem_leak_malloc(size_t size, const char* file, size_t line)
40✔
68
{
69
    return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentMallocAllocator(), size, file, line, true);
40✔
70
}
71

72
static void mem_leak_free(void* buffer, const char* file, size_t line)
28✔
73
{
74
    MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) buffer);
28✔
75
    MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentMallocAllocator(), (char*) buffer, file, line, true);
28✔
76
}
28✔
77

78
static void* mem_leak_realloc(void* memory, size_t size, const char* file, size_t line)
2✔
79
{
80
    return MemoryLeakWarningPlugin::getGlobalDetector()->reallocMemory(getCurrentMallocAllocator(), (char*) memory, size, file, line, true);
2✔
81
}
82

83
#endif
84

85
static void* normal_malloc(size_t size, const char*, size_t)
2✔
86
{
87
    return PlatformSpecificMalloc(size);
2✔
88
}
89

90
static void* normal_realloc(void* memory, size_t size, const char*, size_t)
1✔
91
{
92
    return PlatformSpecificRealloc(memory, size);
1✔
93
}
94

95
static void normal_free(void* buffer, const char*, size_t)
3✔
96
{
97
    PlatformSpecificFree(buffer);
3✔
98
}
3✔
99

100
#if CPPUTEST_USE_MEM_LEAK_DETECTION
101
static void *(*malloc_fptr)(size_t size, const char* file, size_t line) = mem_leak_malloc;
102
static void (*free_fptr)(void* mem, const char* file, size_t line) = mem_leak_free;
103
static void*(*realloc_fptr)(void* memory, size_t size, const char* file, size_t line) = mem_leak_realloc;
104
static void *(*saved_malloc_fptr)(size_t size, const char* file, size_t line) = mem_leak_malloc;
105
static void (*saved_free_fptr)(void* mem, const char* file, size_t line) = mem_leak_free;
106
static void*(*saved_realloc_fptr)(void* memory, size_t size, const char* file, size_t line) = mem_leak_realloc;
107
#else
108
static void *(*malloc_fptr)(size_t size, const char* file, size_t line) = normal_malloc;
109
static void (*free_fptr)(void* mem, const char* file, size_t line) = normal_free;
110
static void*(*realloc_fptr)(void* memory, size_t size, const char* file, size_t line) = normal_realloc;
111
#endif
112

113
void* cpputest_malloc_location_with_leak_detection(size_t size, const char* file, size_t line)
43✔
114
{
115
    return malloc_fptr(size, file, line);
43✔
116
}
117

118
void* cpputest_realloc_location_with_leak_detection(void* memory, size_t size, const char* file, size_t line)
4✔
119
{
120
    return realloc_fptr(memory, size, file, line);
4✔
121
}
122

123
void cpputest_free_location_with_leak_detection(void* buffer, const char* file, size_t line)
32✔
124
{
125
    free_fptr(buffer, file, line);
32✔
126
}
32✔
127

128
/********** C++ *************/
129

130
#if CPPUTEST_USE_MEM_LEAK_DETECTION
131
#undef new
132

133
#if CPPUTEST_HAVE_EXCEPTIONS
134
#define UT_THROW_BAD_ALLOC_WHEN_NULL(memory) if ((memory) == NULLPTR) throw CPPUTEST_BAD_ALLOC()
135
#else
136
#define UT_THROW_BAD_ALLOC_WHEN_NULL(memory)
137
#endif
138

139
static void* threadsafe_mem_leak_operator_new (size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
140
{
141
    MemLeakScopedMutex lock;
1✔
142
    void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
1✔
143
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
1✔
144
    return memory;
1✔
145
}
1✔
146

147
static void* threadsafe_mem_leak_operator_new_nothrow (size_t size) UT_NOTHROW
1✔
148
{
149
    MemLeakScopedMutex lock;
1✔
150
    return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
1✔
151
}
1✔
152

153
static void* threadsafe_mem_leak_operator_new_debug (size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
154
{
155
    MemLeakScopedMutex lock;
1✔
156
    void *memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size, file, line);
1✔
157
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
1✔
158
    return memory;
1✔
159
}
1✔
160

161
static void* threadsafe_mem_leak_operator_new_array (size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
162
{
163
    MemLeakScopedMutex lock;
1✔
164
    void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
1✔
165
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
1✔
166
    return memory;
1✔
167
}
1✔
168

169
static void* threadsafe_mem_leak_operator_new_array_nothrow (size_t size) UT_NOTHROW
1✔
170
{
171
    MemLeakScopedMutex lock;
1✔
172
    return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
1✔
173
}
1✔
174

175
static void* threadsafe_mem_leak_operator_new_array_debug (size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
176
{
177
    MemLeakScopedMutex lock;
1✔
178
    void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size, file, line);
1✔
179
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
1✔
180
    return memory;
1✔
181
}
1✔
182

183
static void threadsafe_mem_leak_operator_delete (void* mem) UT_NOTHROW
3✔
184
{
185
    MemLeakScopedMutex lock;
3✔
186
    MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
3✔
187
    MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewAllocator(), (char*) mem);
3✔
188
}
3✔
189

190
static void threadsafe_mem_leak_operator_delete_array (void* mem) UT_NOTHROW
3✔
191
{
192
    MemLeakScopedMutex lock;
3✔
193
    MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
3✔
194
    MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewArrayAllocator(), (char*) mem);
3✔
195
}
3✔
196

197

198
static void* mem_leak_operator_new (size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
13✔
199
{
200
    void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
13✔
201
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
13✔
202
    return memory;
12✔
203
}
204

205
static void* mem_leak_operator_new_nothrow (size_t size) UT_NOTHROW
1✔
206
{
207
    return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
1✔
208
}
209

210
static void* mem_leak_operator_new_debug (size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC)
10,343✔
211
{
212
    void *memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size, file, line);
10,343✔
213
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
10,343✔
214
    return memory;
10,342✔
215
}
216

217
static void* mem_leak_operator_new_array (size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
3✔
218
{
219
    void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
3✔
220
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
3✔
221
    return memory;
2✔
222
}
223

224
static void* mem_leak_operator_new_array_nothrow (size_t size) UT_NOTHROW
1✔
225
{
226
    return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
1✔
227
}
228

229
static void* mem_leak_operator_new_array_debug (size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC)
96✔
230
{
231
    void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size, file, line);
96✔
232
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
96✔
233
    return memory;
95✔
234
}
235

236
static void mem_leak_operator_delete (void* mem) UT_NOTHROW
10,263✔
237
{
238
    MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
10,263✔
239
    MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewAllocator(), (char*) mem);
10,263✔
240
}
10,263✔
241

242
static void mem_leak_operator_delete_array (void* mem) UT_NOTHROW
97✔
243
{
244
    MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
97✔
245
    MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewArrayAllocator(), (char*) mem);
97✔
246
}
97✔
247

248
static void* normal_operator_new (size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
164✔
249
{
250
    void* memory = PlatformSpecificMalloc(size);
164✔
251
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
164✔
252
    return memory;
164✔
253
}
254

255
static void* normal_operator_new_nothrow (size_t size) UT_NOTHROW
1✔
256
{
257
    return PlatformSpecificMalloc(size);
1✔
258
}
259

260
static void* normal_operator_new_debug (size_t size, const char* /*file*/, size_t /*line*/) UT_THROW(CPPUTEST_BAD_ALLOC)
219✔
261
{
262
    void* memory = PlatformSpecificMalloc(size);
219✔
263
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
219✔
264
    return memory;
219✔
265
}
266

267
static void* normal_operator_new_array (size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
268
{
269
    void* memory = PlatformSpecificMalloc(size);
1✔
270
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
1✔
271
    return memory;
1✔
272
}
273

274
static void* normal_operator_new_array_nothrow (size_t size) UT_NOTHROW
1✔
275
{
276
    return PlatformSpecificMalloc(size);
1✔
277
}
278

279
static void* normal_operator_new_array_debug (size_t size, const char* /*file*/, size_t /*line*/) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
280
{
281
    void* memory = PlatformSpecificMalloc(size);
1✔
282
    UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
1✔
283
    return memory;
1✔
284
}
285

286
static void normal_operator_delete (void* mem) UT_NOTHROW
460✔
287
{
288
    PlatformSpecificFree(mem);
460✔
289
}
460✔
290

291
static void normal_operator_delete_array (void* mem) UT_NOTHROW
3✔
292
{
293
    PlatformSpecificFree(mem);
3✔
294
}
3✔
295

296
static void *(*operator_new_fptr)(size_t size) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new;
297
static void *(*operator_new_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_nothrow;
298
static void *(*operator_new_debug_fptr)(size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new_debug;
299
static void *(*operator_new_array_fptr)(size_t size) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new_array;
300
static void *(*operator_new_array_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_array_nothrow;
301
static void *(*operator_new_array_debug_fptr)(size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new_array_debug;
302
static void (*operator_delete_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete;
303
static void (*operator_delete_array_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete_array;
304

305
static void *(*saved_operator_new_fptr)(size_t size) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new;
306
static void *(*saved_operator_new_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_nothrow;
307
static void *(*saved_operator_new_debug_fptr)(size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new_debug;
308
static void *(*saved_operator_new_array_fptr)(size_t size) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new_array;
309
static void *(*saved_operator_new_array_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_array_nothrow;
310
static void *(*saved_operator_new_array_debug_fptr)(size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC) = mem_leak_operator_new_array_debug;
311
static void (*saved_operator_delete_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete;
312
static void (*saved_operator_delete_array_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete_array;
313
static int save_counter = 0;
314

315
void* operator new(size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
178✔
316
{
317
    return operator_new_fptr(size);
178✔
318
}
319

320
void* operator new(size_t size, const char* file, int line) UT_THROW(CPPUTEST_BAD_ALLOC)
10,562✔
321
{
322
    return operator_new_debug_fptr(size, file, (size_t)line);
10,562✔
323
}
324

325
void* operator new(size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
326
{
327
    return operator_new_debug_fptr(size, file, line);
1✔
328
}
329

330
void operator delete(void* mem) UT_NOTHROW
10,722✔
331
{
332
    operator_delete_fptr(mem);
10,722✔
333
}
10,722✔
334

335
void operator delete(void* mem, const char*, int) UT_NOTHROW
2✔
336
{
337
    operator_delete_fptr(mem);
2✔
338
}
2✔
339

340
void operator delete(void* mem, const char*, size_t) UT_NOTHROW
1✔
341
{
342
    operator_delete_fptr(mem);
1✔
343
}
1✔
344

345
#if __cplusplus >= 201402L
346
void operator delete (void* mem, size_t) UT_NOTHROW
347
{
348
    operator_delete_fptr(mem);
349
}
350
#endif
351

352
void* operator new[](size_t size) UT_THROW(CPPUTEST_BAD_ALLOC)
5✔
353
{
354
    return operator_new_array_fptr(size);
5✔
355
}
356

357
void* operator new [](size_t size, const char* file, int line) UT_THROW(CPPUTEST_BAD_ALLOC)
97✔
358
{
359
    return operator_new_array_debug_fptr(size, file, (size_t)line);
97✔
360
}
361

362
void* operator new [](size_t size, const char* file, size_t line) UT_THROW(CPPUTEST_BAD_ALLOC)
1✔
363
{
364
    return operator_new_array_debug_fptr(size, file, line);
1✔
365
}
366

367
void operator delete[](void* mem) UT_NOTHROW
98✔
368
{
369
     operator_delete_array_fptr(mem);
98✔
370
}
98✔
371

372
void operator delete[](void* mem, const char*, int) UT_NOTHROW
2✔
373
{
374
     operator_delete_array_fptr(mem);
2✔
375
}
2✔
376

377
void operator delete[](void* mem, const char*, size_t) UT_NOTHROW
1✔
378
{
379
     operator_delete_array_fptr(mem);
1✔
380
}
1✔
381

382
#if __cplusplus >= 201402L
383
void operator delete[] (void* mem, size_t) UT_NOTHROW
384
{
385
     operator_delete_array_fptr(mem);
386
}
387
#endif
388

389
#if CPPUTEST_USE_STD_CPP_LIB
390

391
void* operator new(size_t size, const std::nothrow_t&) UT_NOTHROW
3✔
392
{
393
    return operator_new_nothrow_fptr(size);
3✔
394
}
395

396
void operator delete(void* mem, const std::nothrow_t&) UT_NOTHROW
1✔
397
{
398
    operator_delete_fptr(mem);
1✔
399
}
1✔
400

401
void* operator new[](size_t size, const std::nothrow_t&) UT_NOTHROW
3✔
402
{
403
    return operator_new_array_nothrow_fptr(size);
3✔
404
}
405

406
void operator delete[](void* mem, const std::nothrow_t&) UT_NOTHROW
2✔
407
{
408
    operator_delete_array_fptr(mem);
2✔
409
}
2✔
410

411
#else
412

413
/* Have a similar method. This avoid unused operator_new_nothrow_fptr warning */
414

415
extern void* operator_new_nothrow(size_t size) UT_NOTHROW;
416
extern void* operator_new_array_nothrow(size_t size) UT_NOTHROW;
417

418
void* operator_new_nothrow(size_t size) UT_NOTHROW
419
{
420
    return operator_new_nothrow_fptr(size);
421
}
422

423
void* operator_new_array_nothrow(size_t size) UT_NOTHROW
424
{
425
    return operator_new_array_nothrow_fptr(size);
426
}
427

428
#endif
429
#endif
430

431
void MemoryLeakWarningPlugin::turnOffNewDeleteOverloads()
278✔
432
{
433
#if CPPUTEST_USE_MEM_LEAK_DETECTION
434
    operator_new_fptr = normal_operator_new;
278✔
435
    operator_new_nothrow_fptr = normal_operator_new_nothrow;
278✔
436
    operator_new_debug_fptr = normal_operator_new_debug;
278✔
437
    operator_new_array_fptr = normal_operator_new_array;
278✔
438
    operator_new_array_nothrow_fptr = normal_operator_new_array_nothrow;
278✔
439
    operator_new_array_debug_fptr = normal_operator_new_array_debug;
278✔
440
    operator_delete_fptr = normal_operator_delete;
278✔
441
    operator_delete_array_fptr = normal_operator_delete_array;
278✔
442
    malloc_fptr = normal_malloc;
278✔
443
    realloc_fptr = normal_realloc;
278✔
444
    free_fptr = normal_free;
278✔
445

446
#endif
447
}
278✔
448

449
void MemoryLeakWarningPlugin::turnOnDefaultNotThreadSafeNewDeleteOverloads()
6✔
450
{
451
#if CPPUTEST_USE_MEM_LEAK_DETECTION
452
    operator_new_fptr = mem_leak_operator_new;
6✔
453
    operator_new_nothrow_fptr = mem_leak_operator_new_nothrow;
6✔
454
    operator_new_debug_fptr = mem_leak_operator_new_debug;
6✔
455
    operator_new_array_fptr = mem_leak_operator_new_array;
6✔
456
    operator_new_array_nothrow_fptr = mem_leak_operator_new_array_nothrow;
6✔
457
    operator_new_array_debug_fptr = mem_leak_operator_new_array_debug;
6✔
458
    operator_delete_fptr = mem_leak_operator_delete;
6✔
459
    operator_delete_array_fptr = mem_leak_operator_delete_array;
6✔
460
    malloc_fptr = mem_leak_malloc;
6✔
461
    realloc_fptr = mem_leak_realloc;
6✔
462
    free_fptr = mem_leak_free;
6✔
463
#endif
464
}
6✔
465

466
void MemoryLeakWarningPlugin::turnOnThreadSafeNewDeleteOverloads()
4✔
467
{
468
#if CPPUTEST_USE_MEM_LEAK_DETECTION
469
    operator_new_fptr = threadsafe_mem_leak_operator_new;
4✔
470
    operator_new_nothrow_fptr = threadsafe_mem_leak_operator_new_nothrow;
4✔
471
    operator_new_debug_fptr = threadsafe_mem_leak_operator_new_debug;
4✔
472
    operator_new_array_fptr = threadsafe_mem_leak_operator_new_array;
4✔
473
    operator_new_array_nothrow_fptr = threadsafe_mem_leak_operator_new_array_nothrow;
4✔
474
    operator_new_array_debug_fptr = threadsafe_mem_leak_operator_new_array_debug;
4✔
475
    operator_delete_fptr = threadsafe_mem_leak_operator_delete;
4✔
476
    operator_delete_array_fptr = threadsafe_mem_leak_operator_delete_array;
4✔
477
    malloc_fptr = threadsafe_mem_leak_malloc;
4✔
478
    realloc_fptr = threadsafe_mem_leak_realloc;
4✔
479
    free_fptr = threadsafe_mem_leak_free;
4✔
480
#endif
481
}
4✔
482

483
bool MemoryLeakWarningPlugin::areNewDeleteOverloaded()
8✔
484
{
485
#if CPPUTEST_USE_MEM_LEAK_DETECTION
486
    return operator_new_fptr == mem_leak_operator_new || operator_new_fptr == threadsafe_mem_leak_operator_new;
8✔
487
#else
488
    return false;
489
#endif
490
}
491

492
void MemoryLeakWarningPlugin::saveAndDisableNewDeleteOverloads()
116✔
493
{
494
#if CPPUTEST_USE_MEM_LEAK_DETECTION
495
    if (++save_counter > 1) return;
116✔
496
    saved_operator_new_fptr = operator_new_fptr;
113✔
497
    saved_operator_new_nothrow_fptr = operator_new_nothrow_fptr;
113✔
498
    saved_operator_new_debug_fptr = operator_new_debug_fptr;
113✔
499
    saved_operator_new_array_fptr = operator_new_array_fptr;
113✔
500
    saved_operator_new_array_nothrow_fptr = operator_new_array_nothrow_fptr;
113✔
501
    saved_operator_new_array_debug_fptr = operator_new_array_debug_fptr;
113✔
502
    saved_operator_delete_fptr = operator_delete_fptr;
113✔
503
    saved_operator_delete_array_fptr = operator_delete_array_fptr;
113✔
504
    saved_malloc_fptr = malloc_fptr;
113✔
505
    saved_realloc_fptr = realloc_fptr;
113✔
506
    saved_free_fptr = free_fptr;
113✔
507
    turnOffNewDeleteOverloads();
113✔
508
#endif
509
}
510

511
void MemoryLeakWarningPlugin::restoreNewDeleteOverloads()
116✔
512
{
513
#if CPPUTEST_USE_MEM_LEAK_DETECTION
514
    if (--save_counter > 0) return;
116✔
515
    operator_new_fptr = saved_operator_new_fptr;
113✔
516
    operator_new_nothrow_fptr = saved_operator_new_nothrow_fptr;
113✔
517
    operator_new_debug_fptr = saved_operator_new_debug_fptr;
113✔
518
    operator_new_array_fptr = saved_operator_new_array_fptr;
113✔
519
    operator_new_array_nothrow_fptr = saved_operator_new_array_nothrow_fptr;
113✔
520
    operator_new_array_debug_fptr = saved_operator_new_array_debug_fptr;
113✔
521
    operator_delete_fptr = saved_operator_delete_fptr;
113✔
522
    operator_delete_array_fptr = saved_operator_delete_array_fptr;
113✔
523
    malloc_fptr = saved_malloc_fptr;
113✔
524
    realloc_fptr = saved_realloc_fptr;
113✔
525
    free_fptr = saved_free_fptr;
113✔
526
#endif
527
}
528

529
void crash_on_allocation_number(unsigned alloc_number)
3✔
530
{
531
    static CrashOnAllocationAllocator crashAllocator;
3✔
532
    crashAllocator.setNumberToCrashOn(alloc_number);
3✔
533
    setCurrentMallocAllocator(&crashAllocator);
3✔
534
    setCurrentNewAllocator(&crashAllocator);
3✔
535
    setCurrentNewArrayAllocator(&crashAllocator);
3✔
536
}
3✔
537

538
class MemoryLeakWarningReporter: public MemoryLeakFailure
539
{
540
public:
541
    virtual ~MemoryLeakWarningReporter() CPPUTEST_DESTRUCTOR_OVERRIDE
162✔
542
    {
81✔
543
    }
162✔
544

545
    virtual void fail(char* fail_string) CPPUTEST_OVERRIDE
×
546
    {
547
        UtestShell* currentTest = UtestShell::getCurrent();
×
548
        currentTest->failWith(FailFailure(currentTest, currentTest->getName().asCharString(), currentTest->getLineNumber(), fail_string), UtestShell::getCurrentTestTerminatorWithoutExceptions());
×
549
    } // LCOV_EXCL_LINE
550
};
551

552
static MemoryLeakFailure* globalReporter = NULLPTR;
553
static MemoryLeakDetector* globalDetector = NULLPTR;
554

555
MemoryLeakDetector* MemoryLeakWarningPlugin::getGlobalDetector()
35,588✔
556
{
557
    if (globalDetector == NULLPTR) {
35,588✔
558
        saveAndDisableNewDeleteOverloads();
82✔
559

560
        globalReporter = new MemoryLeakWarningReporter;
82✔
561
        globalDetector = new MemoryLeakDetector(globalReporter);
82✔
562

563
        restoreNewDeleteOverloads();
82✔
564
    }
565
    return globalDetector;
35,588✔
566
}
567

568
MemoryLeakFailure* MemoryLeakWarningPlugin::getGlobalFailureReporter()
14✔
569
{
570
    return globalReporter;
14✔
571
}
572

573
void MemoryLeakWarningPlugin::destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(bool des)
82✔
574
{
575
    destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_ = des;
82✔
576
}
82✔
577

578
void MemoryLeakWarningPlugin::setGlobalDetector(MemoryLeakDetector* detector, MemoryLeakFailure* reporter)
20✔
579
{
580
    globalDetector = detector;
20✔
581
    globalReporter = reporter;
20✔
582
}
20✔
583

584
void MemoryLeakWarningPlugin::destroyGlobalDetector()
82✔
585
{
586
    turnOffNewDeleteOverloads();
82✔
587
    delete globalDetector;
82✔
588
    delete globalReporter;
82✔
589
    globalDetector = NULLPTR;
82✔
590
}
82✔
591

592

593
MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::firstPlugin_ = NULLPTR;
594

595
MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::getFirstPlugin()
8✔
596
{
597
    return firstPlugin_;
8✔
598
}
599

600
MemoryLeakDetector* MemoryLeakWarningPlugin::getMemoryLeakDetector()
3✔
601
{
602
    return memLeakDetector_;
3✔
603
}
604

605
void MemoryLeakWarningPlugin::ignoreAllLeaksInTest()
4✔
606
{
607
    ignoreAllWarnings_ = true;
4✔
608
}
4✔
609

610
void MemoryLeakWarningPlugin::expectLeaksInTest(size_t n)
2✔
611
{
612
    expectedLeaks_ = n;
2✔
613
}
2✔
614

615
MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(const SimpleString& name, MemoryLeakDetector* localDetector) :
89✔
616
    TestPlugin(name), ignoreAllWarnings_(false), destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_(false), expectedLeaks_(0)
89✔
617
{
618
    if (firstPlugin_ == NULLPTR) firstPlugin_ = this;
89✔
619

620
    if (localDetector) memLeakDetector_ = localDetector;
89✔
621
    else memLeakDetector_ = getGlobalDetector();
84✔
622

623
    memLeakDetector_->enable();
89✔
624
}
89✔
625

626
MemoryLeakWarningPlugin::~MemoryLeakWarningPlugin()
93✔
627
{
628
    if (destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_) {
88✔
629
        MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
81✔
630
        MemoryLeakWarningPlugin::destroyGlobalDetector();
81✔
631
    }
632
}
93✔
633

634
void MemoryLeakWarningPlugin::preTestAction(UtestShell& /*test*/, TestResult& result)
1,357✔
635
{
636
    memLeakDetector_->startChecking();
1,357✔
637
    failureCount_ = result.getFailureCount();
1,357✔
638
}
1,357✔
639

640
void MemoryLeakWarningPlugin::postTestAction(UtestShell& test, TestResult& result)
1,356✔
641
{
642
    memLeakDetector_->stopChecking();
1,356✔
643
    size_t leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_checking);
1,356✔
644

645
    if (!ignoreAllWarnings_ && expectedLeaks_ != leaks && failureCount_ == result.getFailureCount()) {
1,356✔
646
        if(MemoryLeakWarningPlugin::areNewDeleteOverloaded()) {
2✔
647
            TestFailure f(&test, memLeakDetector_->report(mem_leak_period_checking));
1✔
648
            result.addFailure(f);
1✔
649
        } else if(expectedLeaks_ > 0) {
2✔
650
            result.print(StringFromFormat("Warning: Expected %d leak(s), but leak detection was disabled", (int) expectedLeaks_).asCharString());
1✔
651
        }
652
    }
653
    memLeakDetector_->markCheckingPeriodLeaksAsNonCheckingPeriod();
1,356✔
654
    ignoreAllWarnings_ = false;
1,356✔
655
    expectedLeaks_ = 0;
1,356✔
656
}
1,356✔
657

658
const char* MemoryLeakWarningPlugin::FinalReport(size_t toBeDeletedLeaks)
80✔
659
{
660
    size_t leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_enabled);
80✔
661
    if (leaks != toBeDeletedLeaks) return memLeakDetector_->report(mem_leak_period_enabled);
80✔
662
    return "";
80✔
663
}
664

665

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

© 2025 Coveralls, Inc