Commit f38a36f1 authored by Jon Haslam's avatar Jon Haslam

Fix problems with zero()'ing maps

This change ensures that any maps using the count(), sum(), avg(),
min(), max(), stats(), hist() or lhist() builtins can be zero'd without
hanging the bpftrace process or with generating garbage data in the map.

Special attention is drawn to the changes here in the min_value()
function. I have changed it so that it what you'd expect with signed
quantities. However, I feel the propoer fix would be to change the BPF
generation for the min() function so that it works with 64 bit values
correctly and remove the need for conversion of the stored value.
parent 26ec5378
......@@ -1154,16 +1154,30 @@ uint64_t BPFtrace::max_value(const std::vector<uint8_t> &value, int ncpus)
return max;
}
uint64_t BPFtrace::min_value(const std::vector<uint8_t> &value, int ncpus)
int64_t BPFtrace::min_value(const std::vector<uint8_t> &value, int ncpus)
{
uint64_t val, max = 0;
int64_t val, max = 0, retval;
for (int i=0; i<ncpus; i++)
{
val = *(uint64_t*)(value.data() + i*sizeof(uint64_t*));
val = *(int64_t*)(value.data() + i*sizeof(int64_t*));
if (val > max)
max = val;
}
return (0xffffffff - max);
/*
* This is a hack really until the code generation for the min() function
* is sorted out. The way it is currently implemented doesn't allow >
* 32 bit quantities and also means we have to do gymnastics with the return
* value owing to the way it is stored (i.e., 0xffffffff - val).
*/
if (max == 0) /* If we have applied the zero() function */
retval = max;
else if ((0xffffffff - max) <= 0) /* A negative 32 bit value */
retval = 0 - (max - 0xffffffff);
else
retval = 0xffffffff - max; /* A positive 32 bit value */
return retval;
}
std::vector<uint8_t> BPFtrace::find_empty_key(IMap &map, size_t size) const
......
......@@ -109,7 +109,7 @@ private:
int print_hist(const std::vector<uint64_t> &values, uint32_t div) const;
int print_lhist(const std::vector<uint64_t> &values, int min, int max, int step) const;
static uint64_t reduce_value(const std::vector<uint8_t> &value, int ncpus);
static uint64_t min_value(const std::vector<uint8_t> &value, int ncpus);
static int64_t min_value(const std::vector<uint8_t> &value, int ncpus);
static uint64_t max_value(const std::vector<uint8_t> &value, int ncpus);
static uint64_t read_address_from_output(std::string output);
static std::string exec_system(const char* cmd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment