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