[DTrace-devel] [PATCH 07/13] No data is reported for quantize() when it's all in the last bin

eugene.loh at oracle.com eugene.loh at oracle.com
Wed Dec 2 10:54:52 PST 2020


From: Eugene Loh <eugene.loh at oracle.com>

The search for a nonzero bin is broken for quantize(), causing
no data to be reported when it's all in the last bin.

Fix the search for the "first bin".  Make a few other small
changes so that the three *quantize() functions are more similar
and such coding errors are more apparent.

Add a test to catch this error.  The test is XFAIL for now,
because we do not have a consumer yet.

Orabug: 32148161
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_consume.c             | 16 +++++++---------
 test/unittest/aggs/tst.quantlast.d | 24 ++++++++++++++++++++++++
 test/unittest/aggs/tst.quantlast.r |  6 ++++++
 3 files changed, 37 insertions(+), 9 deletions(-)
 create mode 100644 test/unittest/aggs/tst.quantlast.d
 create mode 100644 test/unittest/aggs/tst.quantlast.r

diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
index a2dffc5c..63e1f65e 100644
--- a/libdtrace/dt_consume.c
+++ b/libdtrace/dt_consume.c
@@ -528,10 +528,10 @@ dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
 	if (size != DTRACE_QUANTIZE_NBUCKETS * sizeof (uint64_t))
 		return (dt_set_errno(dtp, EDT_DMISMATCH));
 
-	while (first_bin < DTRACE_QUANTIZE_NBUCKETS - 1 && data[first_bin] == 0)
+	while (first_bin <= last_bin && data[first_bin] == 0)
 		first_bin++;
 
-	if (first_bin == DTRACE_QUANTIZE_NBUCKETS - 1) {
+	if (first_bin > last_bin) {
 		/*
 		 * There isn't any data.  This is possible if (and only if)
 		 * negative increment values have been used.  In this case,
@@ -578,7 +578,7 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
     size_t size, uint64_t normal)
 {
 	const int64_t *data = addr;
-	int i, first_bin, last_bin, base;
+	int i, first_bin = 0, last_bin, base;
 	uint64_t arg;
 	long double total = 0;
 	uint16_t step, levels;
@@ -594,16 +594,15 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
 	step = DTRACE_LQUANTIZE_STEP(arg);
 	levels = DTRACE_LQUANTIZE_LEVELS(arg);
 
-	first_bin = 0;
 	last_bin = levels + 1;
 
 	if (size != sizeof (uint64_t) * (levels + 2))
 		return (dt_set_errno(dtp, EDT_DMISMATCH));
 
-	while (first_bin <= levels + 1 && data[first_bin] == 0)
+	while (first_bin <= last_bin && data[first_bin] == 0)
 		first_bin++;
 
-	if (first_bin > levels + 1) {
+	if (first_bin > last_bin) {
 		first_bin = 0;
 		last_bin = 2;
 	} else {
@@ -658,7 +657,7 @@ dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
 {
 	const int64_t *data = addr;
 	int factor, lmag, hmag, steps, steps_factor, step, bin0;
-	int first_bin, last_bin, nbins, err, i, mag;
+	int first_bin = 0, last_bin, nbins, err, i, mag;
 	int cwidth = 16, pad = 0;
 	char *c;
 	uint64_t scale;
@@ -677,7 +676,7 @@ dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
 	hmag = DTRACE_LLQUANTIZE_HMAG(arg);
 	steps = DTRACE_LLQUANTIZE_STEPS(arg);
 	steps_factor = steps / factor;
-	bin0 = 1 + (hmag-lmag+1) * (steps-steps/factor);
+	bin0 = 1 + (hmag-lmag+1) * (steps-steps_factor);
 
 	/*
 	 * The rest of the buffer contains:
@@ -697,7 +696,6 @@ dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
 		return (dt_set_errno(dtp, EDT_DMISMATCH));
 
 	/* look for first and last bins with data */
-	first_bin = 0;
 	last_bin = nbins - 1;
 	while (first_bin <= last_bin && data[first_bin] == 0)
 		first_bin++;
diff --git a/test/unittest/aggs/tst.quantlast.d b/test/unittest/aggs/tst.quantlast.d
new file mode 100644
index 00000000..ae74f1a9
--- /dev/null
+++ b/test/unittest/aggs/tst.quantlast.d
@@ -0,0 +1,24 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+/* @@xfail: dtv2 */
+
+/*
+ * ASSERTION:
+ * 	Data exclusively in the last bin is correctly reported.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	x = 0x4000000000000000;
+	@ = quantize(x, 1234);
+	exit(0);
+}
diff --git a/test/unittest/aggs/tst.quantlast.r b/test/unittest/aggs/tst.quantlast.r
new file mode 100644
index 00000000..5284bc8d
--- /dev/null
+++ b/test/unittest/aggs/tst.quantlast.r
@@ -0,0 +1,6 @@
+
+
+           value  ------------- Distribution ------------- count    
+2305843009213693952 |                                         0        
+4611686018427387904 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1234     
+
-- 
2.18.4




More information about the DTrace-devel mailing list