]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Prefer to use mmap instead of malloc in libbacktrace
authorJonathan Wakely <jwakely@redhat.com>
Tue, 12 Apr 2022 16:56:45 +0000 (17:56 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Tue, 12 Apr 2022 21:38:31 +0000 (22:38 +0100)
As reported in PR libbacktrace/105240, libbacktrace leaks memory when
using malloc for allocations. I originally thought it would be simpler
to just use malloc unconditionally (because it's supported on all
targets) but the leaks make that problematic.

This adds libbacktrace's detection for mmap to the libstdc++
configury, so that we use mmap.c and mmapio.c when possible. This avoids
the leaks seen previously, at least on linux.

libstdc++-v3/ChangeLog:

* acinclude.m4 (GLIBCXX_ENABLE_BACKTRACE): Check for mmap.
* config.h.in: Regenerate.
* configure: Regenerate.

libstdc++-v3/acinclude.m4
libstdc++-v3/config.h.in
libstdc++-v3/configure

index f53461c85a5da493cc142a384e2b7c94e16598e4..eac8aeda48bece69c85fe53ba57b4cb2414aa7b2 100644 (file)
@@ -5003,18 +5003,41 @@ elf64) elfsize=64 ;;
 esac
 BACKTRACE_CPPFLAGS="$BACKTRACE_CPPFLAGS -DBACKTRACE_ELF_SIZE=$elfsize"
 
-  ALLOC_FILE=alloc.lo
-  AC_SUBST(ALLOC_FILE)
-  VIEW_FILE=read.lo
-  AC_SUBST(VIEW_FILE)
-
   AC_MSG_CHECKING([whether to build libbacktrace support])
   if test "$enable_libstdcxx_backtrace" == "auto"; then
     enable_libstdcxx_backtrace=no
   fi
   if test "$enable_libstdcxx_backtrace" == "yes"; then
     BACKTRACE_SUPPORTED=1
-    BACKTRACE_USES_MALLOC=1
+
+    AC_CHECK_HEADERS(sys/mman.h)
+    case "${host}" in
+      *-*-msdosdjgpp) # DJGPP has sys/man.h, but no mmap
+       have_mmap=no ;;
+      *-*-*)
+       have_mmap="$ac_cv_header_sys_mman_h" ;;
+    esac
+
+    if test "$have_mmap" = "no"; then
+      VIEW_FILE=read.lo
+      ALLOC_FILE=alloc.lo
+    else
+      VIEW_FILE=mmapio.lo
+      AC_PREPROC_IFELSE([AC_LANG_SOURCE([
+    #include <sys/mman.h>
+    #if !defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
+      #error no MAP_ANONYMOUS
+    #endif
+    ])], [ALLOC_FILE=mmap.lo], [ALLOC_FILE=alloc.lo])
+    fi
+    AC_SUBST(VIEW_FILE)
+    AC_SUBST(ALLOC_FILE)
+
+    BACKTRACE_USES_MALLOC=0
+    if test "$ALLOC_FILE" = "alloc.lo"; then
+      BACKTRACE_USES_MALLOC=1
+    fi
+
     if test "$ac_has_gthreads" = "yes"; then
       BACKTRACE_SUPPORTS_THREADS=1
     else
index f6212de9268a7dcd67c454dff0e03ae8286b1dc1..f30a8c51c458c86ab0d5d28468d6556799ad9252 100644 (file)
 /* Define to 1 if you have the <sys/machine.h> header file. */
 #undef HAVE_SYS_MACHINE_H
 
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
 /* Define to 1 if you have the <sys/param.h> header file. */
 #undef HAVE_SYS_PARAM_H
 
index ef80912d0b9ea6561f0f2a7fa8016d59d8ff95a5..35dc3f49383abe9633249eaa32d33037ebf936e4 100755 (executable)
@@ -681,8 +681,8 @@ BACKTRACE_SUPPORTS_THREADS
 BACKTRACE_USES_MALLOC
 BACKTRACE_SUPPORTED
 BACKTRACE_CPPFLAGS
-VIEW_FILE
 ALLOC_FILE
+VIEW_FILE
 FORMAT_FILE
 ENABLE_FILESYSTEM_TS_FALSE
 ENABLE_FILESYSTEM_TS_TRUE
@@ -16190,7 +16190,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
     ac_save_CXXFLAGS="$CXXFLAGS"
 
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
     #if ! defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
@@ -77463,11 +77463,6 @@ elf64) elfsize=64 ;;
 esac
 BACKTRACE_CPPFLAGS="$BACKTRACE_CPPFLAGS -DBACKTRACE_ELF_SIZE=$elfsize"
 
-  ALLOC_FILE=alloc.lo
-
-  VIEW_FILE=read.lo
-
-
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build libbacktrace support" >&5
 $as_echo_n "checking whether to build libbacktrace support... " >&6; }
   if test "$enable_libstdcxx_backtrace" == "auto"; then
@@ -77475,7 +77470,55 @@ $as_echo_n "checking whether to build libbacktrace support... " >&6; }
   fi
   if test "$enable_libstdcxx_backtrace" == "yes"; then
     BACKTRACE_SUPPORTED=1
-    BACKTRACE_USES_MALLOC=1
+
+    for ac_header in sys/mman.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mman_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_MMAN_H 1
+_ACEOF
+
+fi
+
+done
+
+    case "${host}" in
+      *-*-msdosdjgpp) # DJGPP has sys/man.h, but no mmap
+       have_mmap=no ;;
+      *-*-*)
+       have_mmap="$ac_cv_header_sys_mman_h" ;;
+    esac
+
+    if test "$have_mmap" = "no"; then
+      VIEW_FILE=read.lo
+      ALLOC_FILE=alloc.lo
+    else
+      VIEW_FILE=mmapio.lo
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+    #include <sys/mman.h>
+    #if !defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
+      #error no MAP_ANONYMOUS
+    #endif
+
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ALLOC_FILE=mmap.lo
+else
+  ALLOC_FILE=alloc.lo
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+    fi
+
+
+
+    BACKTRACE_USES_MALLOC=0
+    if test "$ALLOC_FILE" = "alloc.lo"; then
+      BACKTRACE_USES_MALLOC=1
+    fi
+
     if test "$ac_has_gthreads" = "yes"; then
       BACKTRACE_SUPPORTS_THREADS=1
     else