CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_Common/c++.cpp
Views: 1798
1
/*
2
wrapper around new for C++ to ensure we always get zero filled memory
3
*/
4
5
#include <AP_HAL/AP_HAL.h>
6
#include <stdlib.h>
7
#include <new>
8
#include <AP_InternalError/AP_InternalError.h>
9
10
/*
11
globally override new and delete to ensure that we always start with
12
zero memory. This ensures consistent behaviour.
13
14
Note that new comes in multiple different variants. When new is used
15
without std::nothrow the compiler is free to assume it will not fail
16
as it assumes exceptions are enabled. This makes code like this
17
unsafe when using -fno-exceptions:
18
19
a = new b;
20
if (a == nullptr) {
21
handle_error()
22
}
23
24
the compiler may remove the error handling. With g++ you can use
25
-fcheck-new to avoid this, but on clang++ the compiler accepts
26
-fcheck-new as a valid flag, but doesn't implement it, and may elide
27
the error checking. That makes using clang++ unsafe with
28
-fno-exceptions if you ever call new without std::nothrow.
29
30
To avoid this we define NEW_NOTHROW as new(std::nothrow) and use it
31
everywhere in ArduPilot, then we catch any missing cases with both
32
an internal error and with a check of the elf for the symbols we
33
want to avoid
34
*/
35
36
/*
37
variant for new(std::nothrow), which is all that should be used in
38
ArduPilot
39
*/
40
void * operator new(size_t size, std::nothrow_t const &nothrow)
41
{
42
if (size < 1) {
43
size = 1;
44
}
45
return(calloc(size, 1));
46
}
47
48
void * operator new[](size_t size, std::nothrow_t const &nothrow)
49
{
50
if (size < 1) {
51
size = 1;
52
}
53
return(calloc(size, 1));
54
}
55
56
/*
57
These variants are for new without std::nothrow. We don't want to ever
58
use this from ArduPilot code
59
*/
60
void * operator new(size_t size)
61
{
62
if (size < 1) {
63
size = 1;
64
}
65
return(calloc(size, 1));
66
}
67
68
69
void * operator new[](size_t size)
70
{
71
if (size < 1) {
72
size = 1;
73
}
74
return(calloc(size, 1));
75
}
76
77
void operator delete(void *p)
78
{
79
if (p) free(p);
80
}
81
82
void operator delete[](void * ptr)
83
{
84
if (ptr) free(ptr);
85
}
86
87
#if defined(CYGWIN_BUILD) && CONFIG_HAL_BOARD == HAL_BOARD_SITL
88
/*
89
wrapper around malloc to ensure all memory is initialised as zero
90
cygwin needs to wrap _malloc_r
91
*/
92
#undef _malloc_r
93
extern "C" {
94
void *__wrap__malloc_r(_reent *r, size_t size);
95
void *__real__malloc_r(_reent *r, size_t size);
96
void *_malloc_r(_reent *r, size_t size);
97
}
98
void *__wrap__malloc_r(_reent *r, size_t size)
99
{
100
void *ret = __real__malloc_r(r, size);
101
if (ret != nullptr) {
102
memset(ret, 0, size);
103
}
104
return ret;
105
}
106
void *_malloc_r(_reent *x, size_t size)
107
{
108
void *ret = __real__malloc_r(x, size);
109
if (ret != nullptr) {
110
memset(ret, 0, size);
111
}
112
return ret;
113
}
114
115
#elif CONFIG_HAL_BOARD != HAL_BOARD_CHIBIOS && CONFIG_HAL_BOARD != HAL_BOARD_QURT
116
/*
117
wrapper around malloc to ensure all memory is initialised as zero
118
ChibiOS and QURT have their own wrappers
119
*/
120
extern "C" {
121
void *__wrap_malloc(size_t size);
122
void *__real_malloc(size_t size);
123
}
124
void *__wrap_malloc(size_t size)
125
{
126
void *ret = __real_malloc(size);
127
if (ret != nullptr) {
128
memset(ret, 0, size);
129
}
130
return ret;
131
}
132
#endif
133
134