Solution for: #32: MenuMeters Memory Meter reports negative page faults

Patch for MenuMeters : MenuMeterMemStats.m

1
Since this thing's GPL, I can patch MenuMeters's source distribution under MenuExtras/MenuMeterMem/MenuMeterMemStats.m

On lines 130 through 139, you'll notice:
[NSNumber numberWithLong:(unsigned long)vmStat.hits], @"hits", [NSNumber numberWithLong:(long)vmStat.lookups], @"lookups", [NSNumber numberWithLong:(long)vmStat.pageins], @"pageins", [NSNumber numberWithLong:(long)vmStat.pageouts], @"pageouts", [NSNumber numberWithLong:(long)vmStat.faults], @"faults", [NSNumber numberWithLong:(long)vmStat.cow_faults], @"cowfaults", [NSNumber numberWithLong:(long)deltapagein], @"deltapageins", [NSNumber numberWithLong:(long)deltapageout], @"deltapageouts", nil];

Not sure why the dev chose to cast to long. Perhaps there were API changes between OS X versions. (I'm on OS X 10.5 on Intel). vmStat is a vm_statistics_data_t struct, defined in /usr/include/mach/vm_statistics.h and its members are natural_t. Tracing that across the include files, it'll end up from vm_types.h
typedef __darwin_natural_t natural_t;
and finally from i386/_types.h:
typedef unsigned int __darwin_natural_t;
So in fact, these things are unsigned ints, not longs, under i386 architecture (and also under ppc). Hence why the system call to create a vm_statistics_data_t handed up a larger integer than a long under 32-bit i386 could handle.

For my solution, I'm assuming these things will stay unsigned int, and compiling exclusively for i386. If in 10.6 it changes to x86_64 and it's built as x86_64, you'd will have to make sure that natural_t hasn't turned into a unsigned long. To do that, use #if !defined(__LP64__) preprocessor checks ... but I'm going to be lazy and just swap all of these to:

[NSNumber numberWithUnsignedInt:(unsigned int)vmStat.hits], @"hits", [NSNumber numberWithUnsignedInt:(unsigned int)vmStat.lookups], @"lookups", [NSNumber numberWithUnsignedInt:(unsigned int)vmStat.pageins], @"pageins", [NSNumber numberWithUnsignedInt:(unsigned int)vmStat.pageouts], @"pageouts", [NSNumber numberWithUnsignedInt:(unsigned int)vmStat.faults], @"faults", [NSNumber numberWithUnsignedInt:(unsigned int)vmStat.cow_faults], @"cowfaults", [NSNumber numberWithUnsignedInt:(unsigned int)deltapagein], @"deltapageins", [NSNumber numberWithUnsignedInt:(unsigned int)deltapageout], @"deltapageouts", nil];

The original dev kindly provided an .xcodeproj for building this. It should compile out of the box, although if the 10.3.9 SDK is missing, that would have to be either installed, or the SDK project setting has to be switched to 10.4 or above.

Recompile and run in the installer from $srcdir/build/Release/MenuMeters Installer.app.

Should work. Hope it doesn't blow up.

References used: