@cryptotaxi247 / netdata-1 / commits / 884d7b38d

prevent a crash when the ARL is empty; fixes #1700

Costa Tsaousis (ktsaou) committed Feb 1, 2017 at 21:27 UTC 884d7b38d87443b477a710bed6b2c15137a1e0f5
2 files changed +30 -6
src/adaptive_resortable_list.c
+27 -4
@@ -52,7 +52,6 @@ void arl_free(ARL_BASE *arl_base) {
52 }
53
54 void arl_begin(ARL_BASE *base) {
55 - ARL_ENTRY *e;
55
56 #ifdef NETDATA_INTERNAL_CHECKS
57 if(likely(base->iteration > 10)) {
@@ -89,7 +88,8 @@ void arl_begin(ARL_BASE *base) {
88 if(unlikely(base->added || base->iteration % base->rechecks) == 1) {
89 base->added = 0;
90 base->wanted = 0;
92 - for(e = base->head; e ; e = e->next) {
91 + ARL_ENTRY *e = base->head;
92 + while(e) {
93 if(e->flags & ARL_ENTRY_FLAG_FOUND) {
94
95 // remove the found flag
@@ -98,25 +98,48 @@ void arl_begin(ARL_BASE *base) {
98 // count it in wanted
99 if(e->flags & ARL_ENTRY_FLAG_EXPECTED)
100 base->wanted++;
101 +
102 }
102 - else if(e->flags & ARL_ENTRY_FLAG_DYNAMIC) {
103 + else if(e->flags & ARL_ENTRY_FLAG_DYNAMIC && !(base->head == e && !e->next)) { // not last entry
104 // we can remove this entry
105 // it is not found, and it was created because
106 // it was found in the source file
107 +
108 + // remember the next one
109 + ARL_ENTRY *t = e->next;
110 +
111 + // remove it from the list
112 if(e->next) e->next->prev = e->prev;
113 if(e->prev) e->prev->next = e->next;
114 if(base->head == e) base->head = e->next;
115 +
116 + // free it
117 freez(e->name);
118 freez(e);
119
120 + // count it
121 base->fred++;
122 +
123 + // continue
124 + e = t;
125 + continue;
126 }
127 +
128 + e = e->next;
129 }
130 }
131
132 + if(unlikely(!base->head)) {
133 + // hm... no nodes at all in the list #1700
134 + // add a fake one to prevent a crash
135 + // this is better than checking for the existence of nodes all the time
136 + arl_expect(base, "a-really-not-existing-source-keyword", NULL);
137 + }
138 +
139 base->iteration++;
140 base->next_keyword = base->head;
141 base->found = 0;
142 +
143 }
144
145 // register an expected keyword to the ARL
@@ -153,7 +176,7 @@ int arl_find_or_create_and_relink(ARL_BASE *base, const char *s, const char *val
176 break;
177
178 #ifdef NETDATA_INTERNAL_CHECKS
156 - if(unlikely(e == base->next_keyword))
179 + if(unlikely(base->next_keyword && e == base->next_keyword))
180 fatal("Internal Error: e == base->last");
181 #endif
182
src/proc_net_netstat.c
+3 -2
@@ -206,6 +206,9 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
206 size_t lines = procfile_lines(ff), l;
207 size_t words;
208
209 + arl_begin(arl_ipext);
210 + arl_begin(arl_tcpext);
211 +
212 for(l = 0; l < lines ;l++) {
213 char *key = procfile_lineword(ff, l, 0);
214 uint32_t hash = simple_hash(key);
@@ -219,7 +222,6 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
222 continue;
223 }
224
222 - arl_begin(arl_ipext);
225 parse_line_pair(ff, arl_ipext, h, l);
226
227 RRDSET *st;
@@ -371,7 +373,6 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
373 continue;
374 }
375
374 - arl_begin(arl_tcpext);
376 parse_line_pair(ff, arl_tcpext, h, l);
377
378 RRDSET *st;