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