Patch gperftools to be able to work on macOS Sierra/XCode 8

Apparently gperftools needs to be patched for tcmalloc to work
with the new clang version that ships with XCode 8, but the fix
hasn't landed yet.

This patch fixes that and was copied verbatim from:
https://github.com/gperftools/gperftools/issues/827

Note that this fix is virtually identical to the one merged into
jemalloc, which had the same problem:
https://github.com/jemalloc/jemalloc/pull/427/commits/19c9a3e828ed46f1576521c264640e60bd0cb01f

Finally it's noteworthy that this is an macOS/OS X only
fix and, as such, doesn't affect released binaries.

Change-Id: Ie00d9fad36d1746aa94da3b1711353110da42d95
Reviewed-on: http://gerrit.cloudera.org:8080/4495
Reviewed-by: Adar Dembo <a...@cloudera.com>
Tested-by: Kudu Jenkins


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/80923d69
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/80923d69
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/80923d69

Branch: refs/heads/master
Commit: 80923d6904f80d8e7d56cc7eee2c11e88b9329bd
Parents: bc14b2f
Author: David Alves <dral...@apache.org>
Authored: Wed Sep 21 10:30:46 2016 -0700
Committer: David Ribeiro Alves <dral...@apache.org>
Committed: Wed Sep 21 20:01:00 2016 +0000

----------------------------------------------------------------------
 thirdparty/download-thirdparty.sh               |  3 +-
 ..._get_default_zone_to_osx_libc_override.patch | 48 ++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/80923d69/thirdparty/download-thirdparty.sh
----------------------------------------------------------------------
diff --git a/thirdparty/download-thirdparty.sh 
b/thirdparty/download-thirdparty.sh
index c3b4f63..2f4c244 100755
--- a/thirdparty/download-thirdparty.sh
+++ b/thirdparty/download-thirdparty.sh
@@ -124,7 +124,7 @@ fi
 # Check that the gperftools patch has been applied.
 # If you add or remove patches, bump the patchlevel below to ensure
 # that any new Jenkins builds pick up your patches.
-GPERFTOOLS_PATCHLEVEL=2
+GPERFTOOLS_PATCHLEVEL=3
 delete_if_wrong_patchlevel $GPERFTOOLS_DIR $GPERFTOOLS_PATCHLEVEL
 if [ ! -d $GPERFTOOLS_DIR ]; then
   fetch_and_expand gperftools-${GPERFTOOLS_VERSION}.tar.gz
@@ -132,6 +132,7 @@ if [ ! -d $GPERFTOOLS_DIR ]; then
   pushd $GPERFTOOLS_DIR
   patch -p1 < 
$TP_DIR/patches/gperftools-Change-default-TCMALLOC_TRANSFER_NUM_OBJ-to-40.patch
   patch -p1 < 
$TP_DIR/patches/gperftools-hook-mi_force_unlock-on-OSX-instead-of-pthread_atfork.patch
+  patch -p1 < 
$TP_DIR/patches/gperftools-issue-827-add_get_default_zone_to_osx_libc_override.patch
   touch patchlevel-$GPERFTOOLS_PATCHLEVEL
   autoreconf -fvi
   popd

http://git-wip-us.apache.org/repos/asf/kudu/blob/80923d69/thirdparty/patches/gperftools-issue-827-add_get_default_zone_to_osx_libc_override.patch
----------------------------------------------------------------------
diff --git 
a/thirdparty/patches/gperftools-issue-827-add_get_default_zone_to_osx_libc_override.patch
 
b/thirdparty/patches/gperftools-issue-827-add_get_default_zone_to_osx_libc_override.patch
new file mode 100644
index 0000000..5c3061a
--- /dev/null
+++ 
b/thirdparty/patches/gperftools-issue-827-add_get_default_zone_to_osx_libc_override.patch
@@ -0,0 +1,48 @@
+diff --git a/src/libc_override_osx.h b/src/libc_override_osx.h
+index b801f22..37c96c6 100644
+--- a/src/libc_override_osx.h
++++ b/src/libc_override_osx.h
+@@ -211,6 +211,34 @@ extern "C" {
+   size_t malloc_usable_size(void* p)     { return tc_malloc_size(p); }
+ }  // extern "C"
+
++static malloc_zone_t *get_default_zone()
++{
++   malloc_zone_t **zones = NULL;
++   unsigned int num_zones = 0;
++
++   /*
++    * On OSX 10.12, malloc_default_zone returns a special zone that is not
++    * present in the list of registered zones. That zone uses a "lite zone"
++    * if one is present (apparently enabled when malloc stack logging is
++    * enabled), or the first registered zone otherwise. In practice this
++    * means unless malloc stack logging is enabled, the first registered
++    * zone is the default.
++    * So get the list of zones to get the first one, instead of relying on
++    * malloc_default_zone.
++    */
++        if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) 
&zones,
++                                            &num_zones)) {
++       /* Reset the value in case the failure happened after it was set. */
++       num_zones = 0;
++   }
++
++   if (num_zones)
++       return zones[0];
++
++   return malloc_default_zone();
++}
++
++
+ static void ReplaceSystemAlloc() {
+   static malloc_introspection_t tcmalloc_introspection;
+   memset(&tcmalloc_introspection, 0, sizeof(tcmalloc_introspection));
+@@ -273,7 +301,7 @@ static void ReplaceSystemAlloc() {
+   // zone.  The default zone is then re-registered to ensure that
+   // allocations made from it earlier will be handled correctly.
+   // Things are not guaranteed to work that way, but it's how they work now.
+-  malloc_zone_t *default_zone = malloc_default_zone();
++  malloc_zone_t *default_zone = get_default_zone();
+   malloc_zone_unregister(default_zone);
+   malloc_zone_register(default_zone);
+ }

Reply via email to