new-op.cc revision 1.1.1.2 1 1.1 christos /* Replace operator new/new[], for GDB, the GNU debugger.
2 1.1 christos
3 1.1.1.2 christos Copyright (C) 2016-2023 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos /* GCC does not understand __has_feature. */
21 1.1 christos #if !defined(__has_feature)
22 1.1 christos # define __has_feature(x) 0
23 1.1 christos #endif
24 1.1 christos
25 1.1 christos #if !__has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__)
26 1.1 christos #include "common-defs.h"
27 1.1 christos #include "host-defs.h"
28 1.1 christos #include <new>
29 1.1 christos
30 1.1.1.2 christos /* These are declared in <new> starting C++14. Add these here to enable
31 1.1.1.2 christos compilation using C++11. */
32 1.1.1.2 christos extern void operator delete (void *p, std::size_t) noexcept;
33 1.1.1.2 christos extern void operator delete[] (void *p, std::size_t) noexcept;
34 1.1.1.2 christos
35 1.1 christos /* Override operator new / operator new[], in order to internal_error
36 1.1 christos on allocation failure and thus query the user for abort/core
37 1.1 christos dump/continue, just like xmalloc does. We don't do this from a
38 1.1 christos new-handler function instead (std::set_new_handler) because we want
39 1.1 christos to catch allocation errors from within global constructors too.
40 1.1 christos
41 1.1 christos Skip overriding if building with -fsanitize=address though.
42 1.1 christos Address sanitizer wants to override operator new/delete too in
43 1.1 christos order to detect malloc+delete and new+free mismatches. Our
44 1.1 christos versions would mask out ASan's, with the result of losing that
45 1.1 christos useful mismatch detection.
46 1.1 christos
47 1.1 christos Note that C++ implementations could either have their throw
48 1.1 christos versions call the nothrow versions (libstdc++), or the other way
49 1.1 christos around (clang/libc++). For that reason, we replace both throw and
50 1.1 christos nothrow variants and call malloc directly. */
51 1.1 christos
52 1.1 christos void *
53 1.1 christos operator new (std::size_t sz)
54 1.1 christos {
55 1.1 christos /* malloc (0) is unpredictable; avoid it. */
56 1.1 christos if (sz == 0)
57 1.1 christos sz = 1;
58 1.1 christos
59 1.1 christos void *p = malloc (sz); /* ARI: malloc */
60 1.1 christos if (p == NULL)
61 1.1 christos {
62 1.1 christos /* If the user decides to continue debugging, throw a
63 1.1 christos gdb_quit_bad_alloc exception instead of a regular QUIT
64 1.1 christos gdb_exception. The former extends both std::bad_alloc and a
65 1.1 christos QUIT gdb_exception. This is necessary because operator new
66 1.1 christos can only ever throw std::bad_alloc, or something that extends
67 1.1 christos it. */
68 1.1 christos try
69 1.1 christos {
70 1.1 christos malloc_failure (sz);
71 1.1 christos }
72 1.1 christos catch (gdb_exception &ex)
73 1.1 christos {
74 1.1 christos throw gdb_quit_bad_alloc (std::move (ex));
75 1.1 christos }
76 1.1 christos }
77 1.1 christos return p;
78 1.1 christos }
79 1.1 christos
80 1.1 christos void *
81 1.1 christos operator new (std::size_t sz, const std::nothrow_t&) noexcept
82 1.1 christos {
83 1.1 christos /* malloc (0) is unpredictable; avoid it. */
84 1.1 christos if (sz == 0)
85 1.1 christos sz = 1;
86 1.1 christos return malloc (sz); /* ARI: malloc */
87 1.1 christos }
88 1.1 christos
89 1.1 christos void *
90 1.1 christos operator new[] (std::size_t sz)
91 1.1 christos {
92 1.1 christos return ::operator new (sz);
93 1.1 christos }
94 1.1 christos
95 1.1 christos void*
96 1.1 christos operator new[] (std::size_t sz, const std::nothrow_t&) noexcept
97 1.1 christos {
98 1.1 christos return ::operator new (sz, std::nothrow);
99 1.1 christos }
100 1.1.1.2 christos
101 1.1.1.2 christos /* Define also operators delete as one can LD_PRELOAD=libasan.so.*
102 1.1.1.2 christos without recompiling the program with -fsanitize=address and then one would
103 1.1.1.2 christos get false positive alloc-dealloc-mismatch (malloc vs operator delete [])
104 1.1.1.2 christos errors from AddressSanitizers. */
105 1.1.1.2 christos
106 1.1.1.2 christos void
107 1.1.1.2 christos operator delete (void *p) noexcept
108 1.1.1.2 christos {
109 1.1.1.2 christos free (p);
110 1.1.1.2 christos }
111 1.1.1.2 christos
112 1.1.1.2 christos void
113 1.1.1.2 christos operator delete (void *p, const std::nothrow_t&) noexcept
114 1.1.1.2 christos {
115 1.1.1.2 christos return ::operator delete (p);
116 1.1.1.2 christos }
117 1.1.1.2 christos
118 1.1.1.2 christos void
119 1.1.1.2 christos operator delete (void *p, std::size_t) noexcept
120 1.1.1.2 christos {
121 1.1.1.2 christos return ::operator delete (p, std::nothrow);
122 1.1.1.2 christos }
123 1.1.1.2 christos
124 1.1.1.2 christos void
125 1.1.1.2 christos operator delete[] (void *p) noexcept
126 1.1.1.2 christos {
127 1.1.1.2 christos return ::operator delete (p);
128 1.1.1.2 christos }
129 1.1.1.2 christos
130 1.1.1.2 christos void
131 1.1.1.2 christos operator delete[] (void *p, const std::nothrow_t&) noexcept
132 1.1.1.2 christos {
133 1.1.1.2 christos return ::operator delete (p, std::nothrow);
134 1.1.1.2 christos }
135 1.1.1.2 christos
136 1.1.1.2 christos void
137 1.1.1.2 christos operator delete[] (void *p, std::size_t) noexcept
138 1.1.1.2 christos {
139 1.1.1.2 christos return ::operator delete[] (p, std::nothrow);
140 1.1.1.2 christos }
141 1.1.1.2 christos
142 1.1 christos #endif
143