new-op.cc revision 1.1.1.3 1 1.1 christos /* Replace operator new/new[], for GDB, the GNU debugger.
2 1.1 christos
3 1.1.1.3 christos Copyright (C) 2016-2024 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 "host-defs.h"
27 1.1 christos #include <new>
28 1.1 christos
29 1.1.1.3 christos /* These are declared in <new> starting C++14, but removing them
30 1.1.1.3 christos caused a build failure with clang. See PR build/31141. */
31 1.1.1.2 christos extern void operator delete (void *p, std::size_t) noexcept;
32 1.1.1.2 christos extern void operator delete[] (void *p, std::size_t) noexcept;
33 1.1.1.2 christos
34 1.1 christos /* Override operator new / operator new[], in order to internal_error
35 1.1 christos on allocation failure and thus query the user for abort/core
36 1.1 christos dump/continue, just like xmalloc does. We don't do this from a
37 1.1 christos new-handler function instead (std::set_new_handler) because we want
38 1.1 christos to catch allocation errors from within global constructors too.
39 1.1 christos
40 1.1 christos Skip overriding if building with -fsanitize=address though.
41 1.1 christos Address sanitizer wants to override operator new/delete too in
42 1.1 christos order to detect malloc+delete and new+free mismatches. Our
43 1.1 christos versions would mask out ASan's, with the result of losing that
44 1.1 christos useful mismatch detection.
45 1.1 christos
46 1.1 christos Note that C++ implementations could either have their throw
47 1.1 christos versions call the nothrow versions (libstdc++), or the other way
48 1.1 christos around (clang/libc++). For that reason, we replace both throw and
49 1.1 christos nothrow variants and call malloc directly. */
50 1.1 christos
51 1.1 christos void *
52 1.1 christos operator new (std::size_t sz)
53 1.1 christos {
54 1.1 christos /* malloc (0) is unpredictable; avoid it. */
55 1.1 christos if (sz == 0)
56 1.1 christos sz = 1;
57 1.1 christos
58 1.1 christos void *p = malloc (sz); /* ARI: malloc */
59 1.1 christos if (p == NULL)
60 1.1 christos {
61 1.1 christos /* If the user decides to continue debugging, throw a
62 1.1 christos gdb_quit_bad_alloc exception instead of a regular QUIT
63 1.1 christos gdb_exception. The former extends both std::bad_alloc and a
64 1.1 christos QUIT gdb_exception. This is necessary because operator new
65 1.1 christos can only ever throw std::bad_alloc, or something that extends
66 1.1 christos it. */
67 1.1 christos try
68 1.1 christos {
69 1.1 christos malloc_failure (sz);
70 1.1 christos }
71 1.1 christos catch (gdb_exception &ex)
72 1.1 christos {
73 1.1 christos throw gdb_quit_bad_alloc (std::move (ex));
74 1.1 christos }
75 1.1 christos }
76 1.1 christos return p;
77 1.1 christos }
78 1.1 christos
79 1.1 christos void *
80 1.1 christos operator new (std::size_t sz, const std::nothrow_t&) noexcept
81 1.1 christos {
82 1.1 christos /* malloc (0) is unpredictable; avoid it. */
83 1.1 christos if (sz == 0)
84 1.1 christos sz = 1;
85 1.1 christos return malloc (sz); /* ARI: malloc */
86 1.1 christos }
87 1.1 christos
88 1.1 christos void *
89 1.1 christos operator new[] (std::size_t sz)
90 1.1 christos {
91 1.1 christos return ::operator new (sz);
92 1.1 christos }
93 1.1 christos
94 1.1 christos void*
95 1.1 christos operator new[] (std::size_t sz, const std::nothrow_t&) noexcept
96 1.1 christos {
97 1.1 christos return ::operator new (sz, std::nothrow);
98 1.1 christos }
99 1.1.1.2 christos
100 1.1.1.2 christos /* Define also operators delete as one can LD_PRELOAD=libasan.so.*
101 1.1.1.2 christos without recompiling the program with -fsanitize=address and then one would
102 1.1.1.2 christos get false positive alloc-dealloc-mismatch (malloc vs operator delete [])
103 1.1.1.2 christos errors from AddressSanitizers. */
104 1.1.1.2 christos
105 1.1.1.2 christos void
106 1.1.1.2 christos operator delete (void *p) noexcept
107 1.1.1.2 christos {
108 1.1.1.2 christos free (p);
109 1.1.1.2 christos }
110 1.1.1.2 christos
111 1.1.1.2 christos void
112 1.1.1.2 christos operator delete (void *p, const std::nothrow_t&) noexcept
113 1.1.1.2 christos {
114 1.1.1.2 christos return ::operator delete (p);
115 1.1.1.2 christos }
116 1.1.1.2 christos
117 1.1.1.2 christos void
118 1.1.1.2 christos operator delete (void *p, std::size_t) noexcept
119 1.1.1.2 christos {
120 1.1.1.2 christos return ::operator delete (p, std::nothrow);
121 1.1.1.2 christos }
122 1.1.1.2 christos
123 1.1.1.2 christos void
124 1.1.1.2 christos operator delete[] (void *p) noexcept
125 1.1.1.2 christos {
126 1.1.1.2 christos return ::operator delete (p);
127 1.1.1.2 christos }
128 1.1.1.2 christos
129 1.1.1.2 christos void
130 1.1.1.2 christos operator delete[] (void *p, const std::nothrow_t&) noexcept
131 1.1.1.2 christos {
132 1.1.1.2 christos return ::operator delete (p, std::nothrow);
133 1.1.1.2 christos }
134 1.1.1.2 christos
135 1.1.1.2 christos void
136 1.1.1.2 christos operator delete[] (void *p, std::size_t) noexcept
137 1.1.1.2 christos {
138 1.1.1.2 christos return ::operator delete[] (p, std::nothrow);
139 1.1.1.2 christos }
140 1.1.1.2 christos
141 1.1 christos #endif
142