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;