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).
--- 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;