Home | History | Annotate | Line # | Download | only in gdbsupport
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