@cryptotaxi247 / netdata-1 / commits / 5f65e61ef

fixed an infinite loop and a crash

Costa Tsaousis (ktsaou) committed Mar 23, 2014 at 04:02 UTC 5f65e61ef44860c54babddd3c30a435c55a2bab2
1 file changed +14 -12
netdata.c
+14 -12
@@ -59,6 +59,7 @@
59
60 // configuration
61 #define DEBUG (D_WEB_CLIENT_ACCESS|D_LISTENER|D_RRD_STATS)
62 +//#define DEBUG 0xffffffff
63 //#define DEBUG (0)
64
65 #define EXIT_FAILURE 1
@@ -311,7 +312,7 @@ RRD_STATS *rrd_stats_create(const char *name, unsigned long entries)
312
313 debug(D_RRD_STATS, "Creating RRD_STATS for '%s'.", name);
314
314 - st = malloc(sizeof(RRD_STATS));
315 + st = calloc(sizeof(RRD_STATS), 1);
316 if(!st) return NULL;
317
318 st->times = calloc(entries, sizeof(struct timeval));
@@ -325,7 +326,7 @@ RRD_STATS *rrd_stats_create(const char *name, unsigned long entries)
326 st->name[RRD_STATS_NAME_MAX] = '\0';
327
328 st->entries = entries;
328 - st->last_entry = entries;
329 + st->last_entry = 0;
330
331 st->dimensions = NULL;
332 st->next = root;
@@ -340,7 +341,7 @@ RRD_DIMENSION *rrd_stats_dimension_add(RRD_STATS *st, const char *name, size_t b
341
342 debug(D_RRD_STATS, "Adding dimension '%s' to RRD_STATS '%s'.", name, st->name);
343
343 - rd = malloc(sizeof(RRD_DIMENSION));
344 + rd = calloc(sizeof(RRD_DIMENSION), 1);
345 if(!rd) return NULL;
346
347 rd->bytes = bytes;
@@ -389,8 +390,9 @@ void rrd_stats_next(RRD_STATS *st)
390 {
391 struct timeval *now;
392
392 - st->last_entry++;
393 - if(st->last_entry >= st->entries) st->last_entry = 0;
393 + // st->last_entry should never be outside the array
394 + // or, the parallel threads may end up crashing
395 + st->last_entry = ((st->last_entry + 1) >= st->entries) ? 0 : st->last_entry + 1;
396
397 now = &st->times[st->last_entry];
398 gettimeofday(now, NULL);
@@ -450,7 +452,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
452 // keep track of group values and counts
453 long long group_values[dimensions];
454 long long group_counts[dimensions];
453 - for( rd = st->dimensions, c = 0 ; rd ; rd = rd->next, c++)
455 + for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++)
456 group_values[c] = group_counts[c] = 0;
457
458 i += sprintf(&b[i], "{\n \"cols\":\n [\n");
@@ -502,11 +504,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
504 printed++;
505 }
506
505 - for( rd = st->dimensions, c = 0 ; rd ; rd = rd->next, c++) {
506 - // check if new dimensions have been added since we started
507 - if(c >= dimensions)
508 - return sprintf(b, "New dimensions added while we were working on them. Try again later.");
509 -
507 + for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
508 if(rd->bytes == sizeof(unsigned long long)) {
509 long long *dimension = rd->values;
510 value = (dimension[t] - dimension[lt]) * 1000000 * rd->multiplier / usec / rd->divisor;
@@ -841,21 +839,24 @@ void web_client_process(struct web_client *w)
839 int group_method = GROUP_AVERAGE;
840
841 if(url) {
842 + // parse the lines required
843 tok = mystrsep(&url, "/?");
844 if(tok) lines = atoi(tok);
845 if(lines < 5) lines = save_history;
846 }
847 if(url) {
848 + // parse the group count required
849 tok = mystrsep(&url, "/?");
850 if(tok) group_count = atoi(tok);
851 if(group_count < 1) group_count = 1;
852 if(group_count > save_history / 20) group_count = save_history / 20;
853 }
854 if(url) {
855 + // parse the grouping method required
856 tok = mystrsep(&url, "/?");
857 if(strcmp(tok, "max") == 0) group_method = GROUP_MAX;
858 else if(strcmp(tok, "average") == 0) group_method = GROUP_AVERAGE;
858 - else debug(D_WEB_CLIENT, "%llu: Unknown group method '%s'", tok);
859 + else debug(D_WEB_CLIENT, "%llu: Unknown group method '%s'", w->id, tok);
860 }
861
862 debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (%d lines, %d group_count, %d group_method).", w->id, st->name, lines, group_count, group_method);
@@ -1462,6 +1463,7 @@ int main(int argc, char **argv)
1463 r_proc_net_dev = pthread_create(&p_proc_net_dev, NULL, proc_net_dev_main, NULL);
1464
1465 // the main process - the web server listener
1466 + //sleep(1);
1467 socket_listen_main(NULL);
1468
1469 // wait for the childs to finish