diff --git a/CHANGES b/CHANGES index 0649a5307..655d78fb1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ CHANGES FROM 3.7b TO 3.7c +* Build with jemalloc on macOS to avoid what appears to be a bug in calloc + (issue 5385). + * Fix scrollbar initial state so they appear on new windows (issue 5339). * Check time periodically in loops rather than every one (issue 5367). diff --git a/configure.ac b/configure.ac index d2b61376b..56cef0848 100644 --- a/configure.ac +++ b/configure.ac @@ -76,9 +76,7 @@ AM_CONDITIONAL(IS_OPTIMIZED, test "x$enable_optimizations" = xyes) # Is this --enable-asan? AC_ARG_ENABLE( asan, - AS_HELP_STRING(--enable-asan, enable ASAN build flags), - , - enable_asan=no + AS_HELP_STRING(--enable-asan, enable ASAN build flags) ) AM_CONDITIONAL(IS_ASAN, test "x$enable_asan" = xyes) @@ -241,6 +239,7 @@ AC_LIBOBJ(getopt_long) # Look for libevent. Try libevent_core or libevent with pkg-config first then # look for the library. +libevent_version=off PKG_CHECK_MODULES( LIBEVENT_CORE, [libevent_core >= 2], @@ -249,6 +248,8 @@ PKG_CHECK_MODULES( CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" LIBS="$LIBEVENT_CORE_LIBS $LIBS" found_libevent=yes + libevent_version=`$PKG_CONFIG --modversion libevent_core 2>/dev/null` + test "x$libevent_version" = x && libevent_version=on ], found_libevent=no ) @@ -261,6 +262,8 @@ if test x$found_libevent = xno; then CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" LIBS="$LIBEVENT_LIBS $LIBS" found_libevent=yes + libevent_version=`$PKG_CONFIG --modversion libevent 2>/dev/null` + test "x$libevent_version" = x && libevent_version=on ], found_libevent=no ) @@ -269,7 +272,8 @@ if test x$found_libevent = xno; then AC_SEARCH_LIBS( event_init, [event_core event event-1.4], - found_libevent=yes, + [found_libevent=yes + libevent_version=on], found_libevent=no ) fi @@ -296,6 +300,7 @@ fi # Look for ncurses or curses. Try pkg-config first then directly for the # library. +ncurses_version=off PKG_CHECK_MODULES( LIBTINFOW, tinfow, @@ -304,6 +309,8 @@ PKG_CHECK_MODULES( CPPFLAGS="$LIBTINFOW_CFLAGS $SAVED_CPPFLAGS" LIBS="$LIBTINFOW_LIBS $LIBS" found_ncurses=yes + ncurses_version=`$PKG_CONFIG --modversion tinfow 2>/dev/null` + test "x$ncurses_version" = x && ncurses_version=on ], found_ncurses=no ) @@ -316,6 +323,8 @@ if test "x$found_ncurses" = xno; then CPPFLAGS="$LIBTINFO_CFLAGS $SAVED_CPPFLAGS" LIBS="$LIBTINFO_LIBS $LIBS" found_ncurses=yes + ncurses_version=`$PKG_CONFIG --modversion tinfo 2>/dev/null` + test "x$ncurses_version" = x && ncurses_version=on ], found_ncurses=no ) @@ -329,6 +338,8 @@ if test "x$found_ncurses" = xno; then CPPFLAGS="$LIBNCURSESW_CFLAGS $SAVED_CPPFLAGS" LIBS="$LIBNCURSESW_LIBS $LIBS" found_ncurses=yes + ncurses_version=`$PKG_CONFIG --modversion ncursesw 2>/dev/null` + test "x$ncurses_version" = x && ncurses_version=on ], found_ncurses=no ) @@ -342,6 +353,8 @@ if test "x$found_ncurses" = xno; then CPPFLAGS="$LIBNCURSES_CFLAGS $SAVED_CPPFLAGS" LIBS="$LIBNCURSES_LIBS $LIBS" found_ncurses=yes + ncurses_version=`$PKG_CONFIG --modversion ncurses 2>/dev/null` + test "x$ncurses_version" = x && ncurses_version=on ], found_ncurses=no ) @@ -350,7 +363,8 @@ if test "x$found_ncurses" = xno; then AC_SEARCH_LIBS( setupterm, [tinfow tinfo terminfo ncursesw ncurses], - found_ncurses=yes, + [found_ncurses=yes + ncurses_version=on], found_ncurses=no ) if test "x$found_ncurses" = xyes; then @@ -380,6 +394,7 @@ else LIBS="$LIBS -lcurses" CPPFLAGS="$CPPFLAGS -DHAVE_CURSES_H" AC_DEFINE(HAVE_CURSES_H) + ncurses_version=on else AC_MSG_ERROR("curses not found") fi @@ -390,6 +405,7 @@ AC_CHECK_FUNCS([ \ ]) # Look for utempter. +utempter_version=off AC_ARG_ENABLE( utempter, AS_HELP_STRING(--enable-utempter, use utempter if it is installed) @@ -406,17 +422,34 @@ if test "x$enable_utempter" = xyes; then fi if test "x$enable_utempter" = xyes; then AC_DEFINE(HAVE_UTEMPTER) + utempter_version=on else AC_MSG_ERROR("utempter not found") fi fi # Look for utf8proc. +utf8proc_version=off AC_ARG_ENABLE( utf8proc, AS_HELP_STRING(--enable-utf8proc, use utf8proc if it is installed) ) +try_utf8proc=no +require_utf8proc=no if test "x$enable_utf8proc" = xyes; then + try_utf8proc=yes +elif test "x$enable_utf8proc" = x; then + case "$host_os" in + *darwin*) + try_utf8proc=yes + require_utf8proc=yes + ;; + esac +fi +if test "x$try_utf8proc" = xyes; then + SAVED_AM_CPPFLAGS="$AM_CPPFLAGS" + SAVED_OLD_CPPFLAGS="$CPPFLAGS" + SAVED_LIBS="$LIBS" PKG_CHECK_MODULES( LIBUTF8PROC, libutf8proc, @@ -424,7 +457,10 @@ if test "x$enable_utf8proc" = xyes; then AM_CPPFLAGS="$LIBUTF8PROC_CFLAGS $AM_CPPFLAGS" CPPFLAGS="$LIBUTF8PROC_CFLAGS $SAVED_CPPFLAGS" LIBS="$LIBUTF8PROC_LIBS $LIBS" - ] + utf8proc_version=`$PKG_CONFIG --modversion libutf8proc 2>/dev/null` + test "x$utf8proc_version" = x && utf8proc_version=on + ], + [:] ) AC_CHECK_HEADER(utf8proc.h, enable_utf8proc=yes, enable_utf8proc=no) if test "x$enable_utf8proc" = xyes; then @@ -437,13 +473,23 @@ if test "x$enable_utf8proc" = xyes; then fi if test "x$enable_utf8proc" = xyes; then AC_DEFINE(HAVE_UTF8PROC) + test "x$utf8proc_version" = xoff && utf8proc_version=on else - AC_MSG_ERROR("utf8proc not found") + AM_CPPFLAGS="$SAVED_AM_CPPFLAGS" + CPPFLAGS="$SAVED_OLD_CPPFLAGS" + LIBS="$SAVED_LIBS" + utf8proc_version=off + if test "x$require_utf8proc" = xyes; then + enable_utf8proc= + else + AC_MSG_ERROR("utf8proc not found") + fi fi fi AM_CONDITIONAL(HAVE_UTF8PROC, [test "x$enable_utf8proc" = xyes]) # Check for systemd support. +systemd_version=off AC_ARG_ENABLE( systemd, AS_HELP_STRING(--enable-systemd, enable systemd integration) @@ -457,6 +503,8 @@ if test x"$enable_systemd" = xyes; then CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" LIBS="$SYSTEMD_LIBS $LIBS" found_systemd=yes + systemd_version=`$PKG_CONFIG --modversion libsystemd 2>/dev/null` + test "x$systemd_version" = x && systemd_version=on ], found_systemd=no ) @@ -581,11 +629,27 @@ if test "x$found_malloc_trim" = xyes; then fi # Build against jemalloc if requested. +jemalloc_version=off AC_ARG_ENABLE( jemalloc, AS_HELP_STRING(--enable-jemalloc, use jemalloc if it is installed) ) +try_jemalloc=no +require_jemalloc=no if test "x$enable_jemalloc" = xyes; then + try_jemalloc=yes +elif test "x$enable_jemalloc" = x; then + case "$host_os" in + *darwin*) + try_jemalloc=yes + require_jemalloc=yes + ;; + esac +fi +if test "x$try_jemalloc" = xyes; then + SAVED_AM_CPPFLAGS="$AM_CPPFLAGS" + SAVED_OLD_CPPFLAGS="$CPPFLAGS" + SAVED_LIBS="$LIBS" PKG_CHECK_MODULES( JEMALLOC, jemalloc, @@ -593,9 +657,26 @@ if test "x$enable_jemalloc" = xyes; then AM_CPPFLAGS="$JEMALLOC_CFLAGS $AM_CPPFLAGS" CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS" LIBS="$LIBS $JEMALLOC_LIBS" + jemalloc_version=`$PKG_CONFIG --modversion jemalloc 2>/dev/null` + test "x$jemalloc_version" = x && jemalloc_version=on ], - AC_MSG_ERROR("jemalloc not found") + enable_jemalloc=no ) + if test "x$enable_jemalloc" = xno; then + AM_CPPFLAGS="$SAVED_AM_CPPFLAGS" + CPPFLAGS="$SAVED_OLD_CPPFLAGS" + LIBS="$SAVED_LIBS" + jemalloc_version=off + if test "x$require_jemalloc" = xyes; then + enable_jemalloc= + else + AC_MSG_ERROR("jemalloc not found") + fi + else + enable_jemalloc=yes + AC_DEFINE(HAVE_JEMALLOC) + test "x$jemalloc_version" = xoff && jemalloc_version=on + fi fi # Check for CMSG_DATA. On some platforms like HP-UX this requires UNIX 95 @@ -942,6 +1023,20 @@ case "$host_os" in AC_MSG_NOTICE([]) AC_MSG_ERROR([must give --enable-utf8proc or --disable-utf8proc]) fi + # + # macOS calloc(3) does not appear to always zero memory correctly, + # so complain and suggest using jemalloc instead. + # + if test "x$enable_jemalloc" = x; then + AC_MSG_NOTICE([]) + AC_MSG_NOTICE([ macOS calloc(3) appears not to correctly]) + AC_MSG_NOTICE([ zero allocations in some circumstances;]) + AC_MSG_NOTICE([ to avoid this, configuring with]) + AC_MSG_NOTICE([ --enable-jemalloc is recommended. To build]) + AC_MSG_NOTICE([ without anyway, use --disable-jemalloc]) + AC_MSG_NOTICE([]) + AC_MSG_ERROR([must give --enable-jemalloc or --disable-jemalloc]) + fi ;; *dragonfly*) AC_MSG_RESULT(dragonfly) @@ -1029,6 +1124,26 @@ AC_MSG_CHECKING(lock-command) AC_MSG_RESULT($DEFAULT_LOCK_CMD) AC_SUBST(DEFAULT_LOCK_CMD) +# Print a summary. +AC_MSG_NOTICE([]) +if test "x$enable_asan" = xyes; then + AC_MSG_NOTICE([ASAN: on]) +else + AC_MSG_NOTICE([ASAN: off]) +fi +if test "x$enable_debug" = xyes; then + AC_MSG_NOTICE([debug: on]) +else + AC_MSG_NOTICE([debug: off]) +fi +AC_MSG_NOTICE([jemalloc: $jemalloc_version]) +AC_MSG_NOTICE([libevent: $libevent_version]) +AC_MSG_NOTICE([ncurses: $ncurses_version]) +AC_MSG_NOTICE([systemd: $systemd_version]) +AC_MSG_NOTICE([utempter: $utempter_version]) +AC_MSG_NOTICE([utf8proc: $utf8proc_version]) +AC_MSG_NOTICE([]) + # Save our CFLAGS/CPPFLAGS/LDFLAGS for the Makefile and restore the old user # variables. AC_SUBST(AM_CPPFLAGS) diff --git a/proc.c b/proc.c index 01281d023..16e0a2ccd 100644 --- a/proc.c +++ b/proc.c @@ -31,6 +31,10 @@ #include #endif +#ifdef HAVE_JEMALLOC +#include +#endif + #include "tmux.h" struct tmuxproc { @@ -180,6 +184,10 @@ proc_start(const char *name) { struct tmuxproc *tp; struct utsname u; +#ifdef HAVE_JEMALLOC + const char *version; + size_t size = sizeof version; +#endif log_open(name); setproctitle("%s (%s)", name, socket_path); @@ -194,6 +202,11 @@ proc_start(const char *name) #ifdef HAVE_UTF8PROC log_debug("using utf8proc %s", utf8proc_version()); #endif +#ifdef HAVE_JEMALLOC + if (mallctl("version", &version, &size, NULL, 0) != 0) + version = "(unknown version)"; + log_debug("using jemalloc %s", version); +#endif #ifdef NCURSES_VERSION log_debug("using ncurses %s %06u", NCURSES_VERSION, NCURSES_VERSION_PATCH); #endif