MINOR: pools: automatically disable malloc_trim() with external allocators

Pierre Cheynier reported some occasional crashes in malloc_trim() on a
recent glibc when running with jemalloc(). While in theory there should
not be any link between the two, it remains plausible that something
allocated early with one is tentatively freed with the other and that
attempts to trim end up badly. There's no point calling the glibc specific
malloc_trim() with external allocators anyway. However these ones are often
enabled at link time or even at run time with LD_PRELOAD, so we cannot rely
on build options for this.

This patch implements runtime detection for the allocator in use by checking
with mallinfo() that a malloc() call is properly accounted for in glibc's
malloc. It only enables malloc_trim() in this case, and ignores it for
other cases. It's fine to proceed like this because mallinfo() is provided
by a wider range of glibcs than malloc_trim().

This could be backported to 2.4 and 2.3. If so, it will also need previous
patch "CLEANUP: pools: factor all malloc_trim() calls into trim_all_pools()".

(cherry picked from commit 157e393039966fa9a1b4f9a5ca964ec56f28204b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/pool.c b/src/pool.c
index 5afeb97..3c2e4a4 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -41,6 +41,8 @@
 #endif
 
 #if defined(HA_HAVE_MALLOC_TRIM)
+static int using_libc_allocator = 0;
+
 /* ask the allocator to trim memory pools */
 static void trim_all_pools(void)
 {
@@ -48,11 +50,33 @@
 		malloc_trim(0);
 }
 
+/* check if we're using the same allocator as the one that provides
+ * malloc_trim() and mallinfo(). The principle is that on glibc, both
+ * malloc_trim() and mallinfo() are provided, and using mallinfo() we
+ * can check if malloc() is performed through glibc or any other one
+ * the executable was linked against (e.g. jemalloc).
+ */
+static void detect_allocator(void)
+{
+	struct mallinfo mi1, mi2;
+	void *ptr;
+
+	mi1 = mallinfo();
+	ptr = DISGUISE(malloc(1));
+	mi2 = mallinfo();
+	free(DISGUISE(ptr));
+
+	using_libc_allocator = !!memcmp(&mi1, &mi2, sizeof(mi1));
+}
 #else
 
 static void trim_all_pools(void)
 {
 }
+
+static void detect_allocator(void)
+{
+}
 #endif
 
 /* Try to find an existing shared pool with the same characteristics and
@@ -553,6 +577,7 @@
 		LIST_INIT(&ha_thread_info[thr].pool_lru_head);
 	}
 #endif
+	detect_allocator();
 }
 
 INITCALL0(STG_PREPARE, init_pools);