Examination with gdb traced the segfault to line 374 of
dotneato/dotgen/cluster.c, in which the variable "e" is dereferenced
in the condition of a while() loop even if it's null. I modified the
loop condition to terminate the loop if e is null, before derefencencing
it, and then the same problem showed up in line 402. I made the same
change there and dot now produces apparently-correct output on the
sample file I attach below. I have not yet established whether this
fix really solves the problem for all similar files, whether it has
unintended consequences, etc. I don't understand the significance of
the variable e or the data structure it points into, so I don't know
that terminating the loop when e==NULL is really the right thing to
do. It does seem to work so far, however.
Input file: b71.dot
Fix:
This patch is to be applied to dotneato/dotgen/cluster.c. It's meant
for demonstration purposes only - it cleans up the problem I noted, but
may well create some other, worse, problem, because I don't really
understand what's going on in these loops. Also, it's not written
in good style (should have more parentheses and use e==NULL instead of
just e).
*** old-cluster.c Sat Jan 12 11:34:49 2002
--- cluster.c Sat Jan 12 11:22:34 2002
***************
*** 371,377 ****
n->u.clust = NULL;
for (orig = agfstout(root,n); orig; orig = agnxtout(root,orig)) {
if ((e = orig->u.to_virt)) {
! while ((vn = e->head)->u.node_type == VIRTUAL) {
vn->u.clust = NULL;
e = e->head->u.out.list[0];
}
--- 371,377 ----
n->u.clust = NULL;
for (orig = agfstout(root,n); orig; orig = agnxtout(root,orig)) {
if ((e = orig->u.to_virt)) {
! while (e && (vn = e->head)->u.node_type == VIRTUAL) {
vn->u.clust = NULL;
e = e->head->u.out.list[0];
}
***************
*** 399,405 ****
if (n->u.clust == NULL) n->u.clust = g;
for (orig = agfstout(g,n); orig; orig = agnxtout(g,orig)) {
if ((e = orig->u.to_virt)) {
! while ((vn = e->head)->u.node_type == VIRTUAL) {
if (vn->u.clust == NULL) vn->u.clust = g;
e = e->head->u.out.list[0];
}
--- 399,405 ----
if (n->u.clust == NULL) n->u.clust = g;
for (orig = agfstout(g,n); orig; orig = agnxtout(g,orig)) {
if ((e = orig->u.to_virt)) {
! while (e && (vn = e->head)->u.node_type == VIRTUAL) {
if (vn->u.clust == NULL) vn->u.clust = g;
e = e->head->u.out.list[0];
}