Ticket #271 (closed defect: fixed)
Broken isinf on Solaris 9
| Reported by: | human | Owned by: | oetiker |
|---|---|---|---|
| Priority: | blocker | Milestone: | |
| Component: | rrd_graph | Version: | 1.4.3 |
| Keywords: | Cc: | dam@… |
Description
The current implementation of isinf on Solaris 9 leads to the problem that valid line numbers are rejected as "out of range" as outlined in this bug reported for Orca:
The error message is
LINE width '1:average1#0000ff:Zero-fill-on-demand' is out of range in line 'LINE1:average1#0000ff:Zero-fill-on-demand'
The code leading to this message is from rrd_graph_helper.c:
case GF_LINE:
if (c1 == ':') {
gdp->linewidth = 1;
dprintf("- using default width of 1\n");
} else {
i = 0;
sscanf(&line[*eaten], "%lf:%n", &gdp->linewidth, &i);
fprintf(stderr,"LF: %lf\n", gdp->linewidth);
fprintf(stderr,"I: %ld %ld %ld\n",fpclass(gdp->linewidth),FP_SNAN,FP_QNAN);
if (!i) {
rrd_set_error("Cannot parse line width '%s' in line '%s'\n",
&line[*eaten], line);
return 1;
} else {
dprintf("- scanned width %f\n", gdp->linewidth);
if (isnan(gdp->linewidth)) {
rrd_set_error
("LINE width '%s' is not a number in line '%s'\n",
&line[*eaten], line);
return 1;
}
if (isinf(gdp->linewidth)) {
rrd_set_error
("LINE width '%s' is out of range in line '%s'\n",
&line[*eaten], line);
return 1;
}
if (gdp->linewidth < 0) {
rrd_set_error
...
The problem is the broken implementation of 'isinf' for Solaris 9 in rrd_config_bottom.h:
/* for Solaris */ #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS)) # define HAVE_ISINF 1 # ifdef isinf # undef isinf # endif # define isinf(a) (!!(fpclass(a) & (FP_SNAN|FP_QNAN))) #endif
The problem is that fpclass(a) does not return a bitmask, but a number indicating the class of the floatingpoint number as documented in fpclass(3c):
The fpclass() function returns one of the following classes
to which dsrc belongs:
These are from /usr/include/ieeefp.h and valid results:
typedef enum fpclass_t { FP_SNAN = 0, /* signaling NaN */ FP_QNAN = 1, /* quiet NaN */ FP_NINF = 2, /* negative infinity */ FP_PINF = 3, /* positive infinity */ FP_NDENORM = 4, /* negative denormalized non-zero */ FP_PDENORM = 5, /* positive denormalized non-zero */ FP_NZERO = 6, /* -0.0 */ FP_PZERO = 7, /* +0.0 */ FP_NNORM = 8, /* negative normalized non-zero */ FP_PNORM = 9 /* positive normalized non-zero */ } fpclass_t;
This alternative implementation for isinf solves the problem:
#define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)



indeed ... bad bug ... a regression introduced by a bad optimization added r1904 ... fixed in r2093 ... thanks