top: forest view segmentation fault, the final solution
With forest view mode under procps-ng-3.3.0, top would catch a SEGV and exit. The problem was thought to be related to some linux version 3 anamoly. In procps-ng-3.3.1, top was protected from abnormal exit and would display the offending processes with the special orphan notation '?', instead of the usual artwork. As it turns out, the problem wasn't with linux and could surface under a 2.6.xx kernel, The cause was an occasional abnormal ordering of tid/tgid/ppid which went unresolved due to a progressive proc table scan in the recursive function forest_add(). By default the proc table scan now restarts at the beginning. However, a #define TREE_ONEPASS is provided should one wish to restore the 3.3.1 behavior with its reduced overhead.
This commit is contained in:
parent
242be5194c
commit
cd608f462e
12
top.c
12
top.c
@ -3083,7 +3083,12 @@ static void forest_add (const int self, const int level) {
|
|||||||
|
|
||||||
Tree_ppt[Tree_idx] = Seed_ppt[self]; // add this as root or child
|
Tree_ppt[Tree_idx] = Seed_ppt[self]; // add this as root or child
|
||||||
Tree_ppt[Tree_idx++]->pad_3 = level; // borrow 1 byte, 127 levels
|
Tree_ppt[Tree_idx++]->pad_3 = level; // borrow 1 byte, 127 levels
|
||||||
|
#ifdef TREE_ONEPASS
|
||||||
for (i = self + 1; i < Frame_maxtask; i++) {
|
for (i = self + 1; i < Frame_maxtask; i++) {
|
||||||
|
#else
|
||||||
|
for (i = 0; i < Frame_maxtask; i++) {
|
||||||
|
if (i == self) continue;
|
||||||
|
#endif
|
||||||
if (Seed_ppt[self]->tid == Seed_ppt[i]->tgid
|
if (Seed_ppt[self]->tid == Seed_ppt[i]->tgid
|
||||||
|| (Seed_ppt[self]->tid == Seed_ppt[i]->ppid && Seed_ppt[i]->tid == Seed_ppt[i]->tgid))
|
|| (Seed_ppt[self]->tid == Seed_ppt[i]->ppid && Seed_ppt[i]->tid == Seed_ppt[i]->tgid))
|
||||||
forest_add(i, level + 1); // got one child any others?
|
forest_add(i, level + 1); // got one child any others?
|
||||||
@ -3110,9 +3115,10 @@ static void forest_create (WIN_t *q) {
|
|||||||
}
|
}
|
||||||
while (0 == Seed_ppt[i]->ppid) // identify trees (expect 2)
|
while (0 == Seed_ppt[i]->ppid) // identify trees (expect 2)
|
||||||
forest_add(i++, 1); // add parent plus children
|
forest_add(i++, 1); // add parent plus children
|
||||||
for (i = 0; i < Frame_maxtask; i++) // finally, protect ourselves
|
if (Tree_idx != Frame_maxtask) // this will keep us sane...
|
||||||
if (!Seed_ppt[i]->pad_3) // against any kernel anomaly
|
for (i = 0; i < Frame_maxtask; i++)
|
||||||
Tree_ppt[Tree_idx++] = Seed_ppt[i];
|
if (!Seed_ppt[i]->pad_3)
|
||||||
|
Tree_ppt[Tree_idx++] = Seed_ppt[i];
|
||||||
}
|
}
|
||||||
memcpy(Seed_ppt, Tree_ppt, sizeof(proc_t*) * Frame_maxtask);
|
memcpy(Seed_ppt, Tree_ppt, sizeof(proc_t*) * Frame_maxtask);
|
||||||
} // end: forest_create
|
} // end: forest_create
|
||||||
|
1
top.h
1
top.h
@ -38,6 +38,7 @@
|
|||||||
//#define STRCMPNOCASE /* use strcasecmp vs. strcmp when sorting */
|
//#define STRCMPNOCASE /* use strcasecmp vs. strcmp when sorting */
|
||||||
//#define TERMIOS_ONLY /* just limp along with native input only */
|
//#define TERMIOS_ONLY /* just limp along with native input only */
|
||||||
//#define TREE_NORESET /* sort keys do NOT force forest view OFF */
|
//#define TREE_NORESET /* sort keys do NOT force forest view OFF */
|
||||||
|
//#define TREE_ONEPASS /* for speed, tolerate dangling children */
|
||||||
//#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */
|
//#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user