@cryptotaxi247 / netdata-1 / commits / 00799ba6d

fix for infinite loop

Costa Tsaousis (ktsaou) committed Mar 23, 2014 at 05:06 UTC 00799ba6de99a5ebe24ec89321bc2c3aecf9f459
1 file changed +31 -12
netdata.c
+31 -12
@@ -434,13 +434,26 @@ void rrd_stats_dimension_set(RRD_STATS *st, const char *dimension, void *data)
434
435 size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_show, size_t group_count, int group_method)
436 {
437 - size_t i = 0, c, t, lt, printed = 0, dimensions = 0, last_entry = st->last_entry;
438 - int pad = 0;
439 - long count = st->entries;
437 + // check the options
438 + if(entries_to_show <= 0) entries_to_show = 1;
439 + if(group_count <= 0) group_count = 1;
440 + if(group_count > st->entries / 20) group_count = st->entries / 20;
441 +
442 + size_t i = 0; // the bytes of JSON output we have generated so far
443 + size_t printed = 0; // the lines of JSON data we have generated so far
444 +
445 + size_t last_entry = st->last_entry;
446 + size_t t, lt; // t = the current entry, lt = the lest entry of data
447 + long count = st->entries; // count down of the entries examined so far
448 + int pad = 0; // align the entries when grouping values together
449 +
450 RRD_DIMENSION *rd;
441 - unsigned long long usec = 0;
442 - long long value;
443 - char dtm[1025];
451 + size_t c = 0; // counter for dimension loops
452 + size_t dimensions = 0; // the total number of dimensions present
453 +
454 + unsigned long long usec = 0;// usec between the entries
455 + long long value; // temp variable for storing data values
456 + char dtm[201]; // temp variable for storing dates
457
458 // find how many dimensions we have
459 for( rd = st->dimensions ; rd ; rd = rd->next)
@@ -449,7 +462,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
462 if(!dimensions)
463 return sprintf(b, "No dimensions yet.");
464
452 - // keep track of group values and counts
465 + // temporary storage to keep track of group values and counts
466 long long group_values[dimensions];
467 long long group_counts[dimensions];
468 for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++)
@@ -458,7 +471,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
471 i += sprintf(&b[i], "{\n \"cols\":\n [\n");
472 i += sprintf(&b[i], " {\"id\":\"\",\"label\":\"time\",\"pattern\":\"\",\"type\":\"timeofday\"},\n");
473
461 - for( rd = st->dimensions ; rd ; rd = rd->next)
474 + for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++)
475 i += sprintf(&b[i], " {\"id\":\"\",\"label\":\"%s\",\"pattern\":\"\",\"type\":\"number\"}%s\n", rd->name, rd->next?",":"");
476
477 i += sprintf(&b[i], " ],\n \"rows\":\n [\n");
@@ -466,6 +479,9 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
479 // to allow grouping on the same values, we need a pad
480 pad = last_entry % group_count;
481
482 + // make sure last_entry is within limits
483 + if(last_entry < 0 || last_entry >= st->entries) last_entry = 0;
484 +
485 // find the old entry of the round-robin
486 t = last_entry + 1;
487 if(t >= st->entries) t = 0;
@@ -477,8 +493,8 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
493
494 // the loop in dimension data
495 count -= 2;
480 - for ( ; t != last_entry ; lt = t++, count--) {
481 - if(t >= st->entries) t = 0;
496 + for ( ; t != last_entry && count >= 0 ; lt = t++, count--) {
497 + if(t >= st->entries) t = 0;
498
499 // if the last is empty, loop again
500 if(!st->times[lt].tv_sec) continue;
@@ -486,9 +502,13 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
502 // check if we may exceed the buffer provided
503 if((length - i) < 1024) break;
504
505 + // prefer the most recent last entries
506 if(((count-pad) / group_count) > entries_to_show) continue;
507
508 +
509 + // ok. we will use this entry!
510 // find how much usec since the previous entry
511 +
512 usec = usecdiff(&st->times[t], &st->times[lt]);
513
514 if(((count-pad) % group_count) == 0) {
@@ -498,7 +518,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
518 struct tm *tm = localtime(&st->times[t].tv_sec);
519 if(!tm) { error("localtime() failed."); continue; }
520
501 - strftime(dtm, 1024, "[%H, %M, %S, 0]", tm);
521 + strftime(dtm, 200, "[%H, %M, %S, 0]", tm);
522 i += sprintf(&b[i], "%s {\"c\":[{\"v\":%s},", printed?"]},\n":"", dtm);
523
524 printed++;
@@ -547,7 +567,6 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
567 if(printed) i += sprintf(&b[i], "]}");
568 i += sprintf(&b[i], "\n ]\n}\n");
569
550 - if(count != 0) error("RRD count should be zero, but found to be %d.", count);
570 return(i);
571 }
572