diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2020-05-08 21:34:45 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2020-05-08 21:42:55 -0700 |
commit | 4f9e3f857e3e0a6d9f02e577a30f35c318388e05 (patch) | |
tree | 8b276e70941e55007b06b583d41bb9a0b4b86b85 | |
parent | 4c9a16f4efe7fe2af2f418f8c668e51626eaf702 (diff) |
libvmon: fix bug in proc_follow_children()
There's an optimization where the search start pointer is
advanced on matches, to resume searching from the last matched
position. The assumption is that the in-memory list order and
the order coming out of the proc file will align.
Except using the standard list iterator, this would treat the
list head @ &proc->children as just another node in the list.
In the unlikely case where &proc->children treated as a siblings
member in a vmon_proc_t actually resulted in contents lining up
as a match, the generation update would scribble over part of
the parent pointer member, making things crashy when the parent
was dereferenced later in the fuction.
This commit just makes it skip over the &proc->children node if
encountered, just like in proc_follow_threads().
Hopefully this eliminates the remaining very rare vwm crashes
that occur during big parallel builds of the kernel or systemd.
-rw-r--r-- | src/libvmon/vmon.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/src/libvmon/vmon.c b/src/libvmon/vmon.c index 54d55ef..eb79bbb 100644 --- a/src/libvmon/vmon.c +++ b/src/libvmon/vmon.c @@ -412,6 +412,9 @@ static int proc_follow_children(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follo /* separator, terminates a PID, search for it in the childrens list */ found = 0; list_for_each(cur, start) { + if (cur == &proc->children) /* take care to skip the head node */ + continue; + if (list_entry(cur, vmon_proc_t, siblings)->pid == child_pid) { /* found the child already monitored, update its generation number and stop searching */ tmp = list_entry(cur, vmon_proc_t, siblings); @@ -1515,7 +1518,7 @@ int vmon_sample(vmon_t *vmon) if (vmon->sample_cb) vmon->sample_cb(vmon, vmon->sample_cb_arg); - /* then the per-process samplers */ + /* then the per-process samplers */ if ((vmon->flags & VMON_FLAG_PROC_ARRAY)) { int j; /* TODO: determine if this really makes sense, if we always maintain a heirarchy even in array mode, then we |