Bug 1399679 - Avoid differences in pm_linux.cpp draft
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 26 Dec 2017 19:57:19 +0900
changeset 722001 3be7f290323aa68ca430853158e13657e38e7e4b
parent 722000 5658d031ae17cc44820bf6b24b25c2727847bad7
child 722002 0b0bd86eac97de9a428b144abaaec70cee0cdf4c
push id96025
push userbmo:mh+mozilla@glandium.org
push dateThu, 18 Jan 2018 09:37:19 +0000
bugs1399679
milestone59.0a1
Bug 1399679 - Avoid differences in pm_linux.cpp struct perf_event_attr is larger(!) in the older(!) kernel headers (2.6.32) on CentOS 6, because they backported features from kernels (3.7 and 3.19) newer than the one in Debian wheezy (3.2) or wheezy-backports (3.14).
js/src/perf/pm_linux.cpp
--- a/js/src/perf/pm_linux.cpp
+++ b/js/src/perf/pm_linux.cpp
@@ -134,23 +134,26 @@ Impl::~Impl()
 EventMask
 Impl::init(EventMask toMeasure)
 {
     MOZ_ASSERT(group_leader == -1);
     if (!toMeasure)
         return EventMask(0);
 
     EventMask measured = EventMask(0);
-    struct perf_event_attr attr;
+    union {
+      struct perf_event_attr attr;
+      char dummy[256];
+    };
     for (const auto& slot : kSlots) {
         if (!(toMeasure & slot.bit))
             continue;
 
-        memset(&attr, 0, sizeof(attr));
-        attr.size = sizeof(attr);
+        memset(&dummy, 0, sizeof(dummy));
+        attr.size = sizeof(dummy);
 
         // Set the type and config fields to indicate the counter we
         // want to enable.  We want read format 0, and we're not using
         // sampling, so leave those fields unset.
         attr.type = slot.type;
         attr.config = slot.config;
 
         // If this will be the group leader it should start off
@@ -288,19 +291,22 @@ PerfMeasurement::canMeasureSomething()
     // API.  If it doesn't, syscall(__NR_perf_event_open, ...) is
     // guaranteed to return -1 and set errno to ENOSYS.
     //
     // We set up input parameters that should provoke an EINVAL error
     // from a kernel that does implement perf_event_open, but we can't
     // be sure it will (newer kernels might add more event types), so
     // we have to take care to close any valid fd it might return.
 
-    struct perf_event_attr attr;
-    memset(&attr, 0, sizeof(attr));
-    attr.size = sizeof(attr);
+    union {
+      struct perf_event_attr attr;
+      char dummy[256];
+    };
+    memset(&dummy, 0, sizeof(dummy));
+    attr.size = sizeof(dummy);
     attr.type = PERF_TYPE_MAX;
 
     int fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
     if (fd >= 0) {
         close(fd);
         return true;
     }
     return errno != ENOSYS;