libsysprof-capture: Clean ring buffer memory for counters
Apps using the collector API use sysprof_collector_set_counters() to report values of previously defined counters. The collector implements this report by populating a SysprofCaptureCounterSet struct.
However, sometimes we can observe completely random values in these counters. These random values are so wildly different that they make e.g. the charts in the Sysprof UI useless!
The SysprofCaptureCounterSet struct is rather interesting. It extends SysprofCaptureFrame, has a n_values counter, some extra padding, and the tail is 1+ SysprofCaptureCounterValues. Each SysprofCaptureCounterValues can contain up to 8 counter values.
Therefore when using sysprof_collector_set_counters(), the counters are grouped in packets of 8 id+value pairs. Let's look at a real example from a capture file generated from WebKit:
CTRSET frame at 520713
group 0
setting id 4 to 25,000000
setting id 5 to 79,076893
setting id 6 to 20,000000
setting id 7 to 79,207139
setting id 8 to 15,789474
setting id 9 to 79,080517
setting id 10 to 20,000000
setting id 11 to 79,246893
group 1
setting id 12 to 25,000000
setting id 13 to 79,091038
setting id 14 to 23,809524
setting id 15 to 79,123830
setting id 16 to 21,052632
setting id 17 to 79,189787
setting id 18 to 20,000000
setting id 19 to 79,234681
group 2
setting id 20 to 23,809524
setting id 21 to 79,120228
setting id 22 to 21,052632
setting id 23 to 79,229608
setting id 24 to 21,052632
(empty)
(empty)
(empty)
Notice how, in the last group, the 3 last elements are empty.
Or at least, they were supposed to be empty. In my raw file, these last elements actually contain the following:
[...]
group 2
setting id 20 to 23,809524
setting id 21 to 79,120228
setting id 22 to 21,052632
setting id 23 to 79,229608
setting id 24 to 21,052632
setting id 87955554 to 20445420015746541324787,0
setting id 7479777 to 94327513216873524,054651321
setting id 877 to 7213274321290062100443215432135745313213274321301700,01239997
That's because, in sysprof_collector_set_counters(), after requesting memory from the ring buffer, it merely copies the passed counter values to the groups. The function doesn't zero the remaining values. Thus what we see is previously written memory from the ring buffer.
Normally these bogus values are so bogus that their ids don't match any of the registered counter ids. In those cases Sysprof just ignores the values. However in some circumstances the ids can randomly match previously defined counter ids! This is when Sysprof accidentally shows the crazy values.
Fix that by memset()ing the groups to zero before copying the counters and values into them.