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