[1212] in Coldmud discussion meeting
[COLD] patch: *the* corruption bug
daemon@ATHENA.MIT.EDU (Wed Jan 15 06:27:14 1997
)
Date: Wed, 15 Jan 1997 12:19:27 +0100 (MET)
From: Miroslav Silovic <silovic@public.srce.hr>
To: coldstuff@cold.org
Okay, I finally found the damn thing. And it was in my code. Jeffk, feel
free to ignore my request, I figured it out (and purify prolly wouldn't
have helped, either. :) )
The problem was in scatter assignment, when you used @ to assign the
tail, it left references to freed memory (due to a bug in refcounting).
This caused memory corruption later in the execution. Notably,
@add-shorthand, CML compiler and debugger were hit by this bug,
and so was everything that used $list.sum.
I also fixed missing check_stack in op_scatter_start and another memory
leak in scatter assignment.
The patch:
*** Genesis-1.0p21/src/ops/operators.c Sun Dec 15 00:05:53 1996
--- Genesis-1.0p21-new/src/ops/operators.c Wed Jan 15 12:04:14 1997
***************
*** 1926,1944 ****
break;
}
case SPLICE: {
Int len=list_length(l);
if (list_index >= len)
/* Sorry, we're out of data. Empty list. */
list_index = len;
/* Don't anticipate if we're not at the top level */
if (stack[stack_pos-3].type == INTEGER)
anticipate_assignment();
c = ++cur_frame->pc;
! push_list(list_sublist(l, list_index, len-list_index));
(*op_table[opcodes[c-1]].func)();
if (cur_frame->pc != c+1)
return;
pop(1);
break;
--- 1926,1947 ----
break;
}
case SPLICE: {
Int len=list_length(l);
+ cList *sublist;
if (list_index >= len)
/* Sorry, we're out of data. Empty list. */
list_index = len;
/* Don't anticipate if we're not at the top level */
if (stack[stack_pos-3].type == INTEGER)
anticipate_assignment();
c = ++cur_frame->pc;
! sublist = list_sublist(list_dup(l), list_index, len-list_index);
! push_list(sublist);
! list_discard(sublist);
(*op_table[opcodes[c-1]].func)();
if (cur_frame->pc != c+1)
return;
pop(1);
break;
***************
*** 1954,1963 ****
--- 1957,1967 ----
cthrow (type_id, "Attempting to scatter non-list (%D)",
&stack[stack_pos-1]);
return;
}
+ check_stack(2);
stack[stack_pos+1]=stack[stack_pos-1];
stack[stack_pos-1].type=INTEGER;
stack[stack_pos-1].u.val=0;
stack[stack_pos]=stack[stack_pos-1];
stack_pos+=2;