View Issue Details

IDProjectCategoryView StatusLast Update
0000517LDMud 3.3Runtimepublic2018-01-29 22:57
Reporterzesstra Assigned To 
PrioritynormalSeveritycrashReproducibilitysometimes
Status resolvedResolutionfixed 
Product Version3.3 
Fixed in Version3.3.716 
Summary0000517: Crash in remove_mapping()
DescriptionMorgengrauen crashed this afternoon after a nice long uptime with 3.3.714. ;-)
The crash occured in remove_mapping() in mapping.c:1401 by calling fatal() ("Mapping entry didn't hash to the same spot.")
find_map_entry() found an entry in the hash part (searching the hash of the given map_index), but remove_mapping() itself wasn't able to find it using the hash of 'entry' (returned from find_map_entry).

LPC-Stacktrace was:
2007.09.19 15:54:20 Mapping entry didn't hash to the same spot.
2007.09.19 15:54:20 Current object was players/nibel/demon/master/dmaster
2007.09.19 15:54:20 Dump of the call chain:
' ParseLine' in ' obj/tools/MGtool.c' ('obj/tools/MGtool#5887724') line 1509
' CallFunc' in ' obj/tools/MGtool.c' ('obj/tools/MGtool#5887724') line 1617
' Xcall' in 'obj/tools/MGtool.c (/obj/tools/MGtool/toolcmd.c)' ('obj/tools/MGtool
#5887724') line 63
' CATCH' in ('obj/tools/MGtool#5887724')
' eval' in 'players/nibel/.tool.lpc.c' ('players/nibel/.tool.lpc') line 8
' StopPhase5' in 'players/nibel/demon/master/dmaster.c' ('players/nibel/demon/master/dmaster') line 315

StopPhase5() was this code snippet:
public int StopPhase5() {
  if(!Sec()) return -1;
  while(remove_call_out(#'TimerPhase5A) != -1);
  while(remove_call_out(#'TimerPhase5B) != -1);
  filter_objects(m_indices(npcs["worm"] - ([0])), "die");
  npcs["worm"] = ([]);
  return ShoutPlane("Der Strom neuer Wuermer versiegt.\n"),1;
}

Of course, this subtraction of ([0]) is in case of mappings not necessary to remove destructed object(key)s, but it should crash either.
I can reproduce that crash. remove_mapping() crashes sometimes, if you have a mapping with objects as Keys, destruct an object and subtract ([0]) from the mapping (see steps to reproduce).
I am not yet certain, what exactly happens, but hopefully I am able to look into the details soon.
Steps To ReproduceCreate the following program and load it.
Call Stop() until it crashes, e.g. xdo 50#xcall test->Stop().
Repeat if necessary, in rare cases it does not crash in my homemud.

mapping m=([]);

void create() {
    seteuid(getuid());
    foreach(int i: 20) {
      object ob=clone_object("/obj/seil");
      ob->move("/room/void",M_NOCHECK);
      m+=([ob:"bla"]);
    }
}

public int Stop() {
  object *ind;
  ind=m_indices(m);
  destruct(ind[random(sizeof(ind))]);
  m = m - ([0]);
  return 1;
}
Additional InformationStack trace:

#0 fatal (fmt=0x810cb58 "Mapping entry didn't hash to the same spot.\n") at simulate.c:586
0000001 0x080b3c54 in remove_mapping (m=0x207ccf34, map_index=<value optimized out>) at mapping.c:1401
0000002 0x080b28dd in walk_mapping (m=0x16e11bb0, func=0x80b3ca0 <sub_from_mapping_filter>, extra=0x207ccf34) at mapping.c:1971
0000003 0x080b3533 in subtract_mapping (minuend=0x207ccf34, subtrahend=0x16e11bb0) at mapping.c:3422
0000004 0x08095c5b in eval_instruction (first_instruction=0x208904b2 "an\002", initial_sp=0x813eec0) at interpret.c:10247
0000005 0x080a1ea1 in apply_low (fun=0x11e9723c, ob=0x1ac5c570, num_arg=0, b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000006 0x080a280a in int_apply (fun=0x11e9723c, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000007 0x0808fe88 in eval_instruction (first_instruction=0x2242d66e "a\036", initial_sp=0x813eea8) at interpret.c:16159
0000008 0x080a1ea1 in apply_low (fun=0x967150c, ob=0xb5b26bc, num_arg=3, b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000009 0x080a280a in int_apply (fun=0x967150c, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000010 0x0808fe88 in eval_instruction (first_instruction=0x28261e63 "a\036\001\n>\036\002\b\003a\b\003\a\020b»b{\f(´b{\a)\002\f{\n)\036\aj\017a\n=\036\a\020K*nx",
    initial_sp=0x813ee78) at interpret.c:16159
0000011 0x080e7350 in catch_instruction (flags=0, offset=21, i_sp=0x81b4c04,
    i_pc=0x28261e63 "a\036\001\n>\036\002\b\003a\b\003\a\020b»b{\f(´b{\a)\002\f{\n)\036\aj\017a\n=\036\a\020K*nx", i_fp=0x813ee10, reserve_cost=4000, i_context=0x0)
    at simulate.c:447
0000012 0x0808bf35 in eval_instruction (first_instruction=0x28261d3a "`\001\fanN", initial_sp=0x813ee70) at interpret.c:9381
0000013 0x080a1ea1 in apply_low (fun=0xa21bc70, ob=0x1350ed60, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811
#14 0x080a280a in int_apply (fun=0xa21bc70, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
#15 0x0808fe88 in eval_instruction (first_instruction=0x282676be "`\001\003a\ff\036", initial_sp=0x813edd0) at interpret.c:16159
#16 0x080a1ea1 in apply_low (fun=0xa20bc38, ob=0x1350ed60, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811
#17 0x080a280a in int_apply (fun=0xa20bc38, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
#18 0x080a4799 in sapply_int (fun=0xa20bc38, ob=0x1350ed60, num_arg=1, b_find_static=0, b_use_default=1) at interpret.c:17050
#19 0x0804bca9 in parse_command (buff=0xbf8cad66 "xcall dmaster->stopphase5()", from_efun=0) at actions.c:1098
#20 0x0804ddaf in execute_command (str=0xbf8cad66 "xcall dmaster->stopphase5()", ob=0xe79bb10) at actions.c:1258
#21 0x08054612 in backend () at backend.c:671
#22 0x080b2435 in main (argc=Cannot access memory at address 0x0
) at main.c:615

I will attach the full stacktrace. A core dump is available, but I had only time for a short glance yet.
TagsNo tags attached.

Relationships

related to 0000816 resolvedzesstra Crash during compact_mapping() 

Activities

2007-09-19 17:12

 

stack (9,525 bytes)   
#0  fatal (fmt=0x810cb58 "Mapping entry didn't hash to the same spot.\n") at simulate.c:586
	va = 0xbf8c8ff4 ""
	ts = <value optimized out>
#1  0x080b3c54 in remove_mapping (m=0x207ccf34, map_index=<value optimized out>) at mapping.c:1401
	mc2 = (map_chain_t *) 0x1
	idx = 7
	key_ix = -1
	entry = <value optimized out>
	mc = (map_chain_t *) 0x288775a0
	hm = <value optimized out>
	num_values = <value optimized out>
#2  0x080b28dd in walk_mapping (m=0x16e11bb0, func=0x80b3ca0 <sub_from_mapping_filter>, extra=0x207ccf34) at mapping.c:1971
	next = (map_chain_t *) 0x0
	mc = (map_chain_t *) 0x0
	size = 0
	cm = (mapping_cond_t *) 0x0
	hm = (mapping_hash_t *) 0x113d34a8
	key = <value optimized out>
	data = <value optimized out>
	num_values = <value optimized out>
#3  0x080b3533 in subtract_mapping (minuend=0x207ccf34, subtrahend=0x16e11bb0) at mapping.c:3422
No locals.
#4  0x08095c5b in eval_instruction (first_instruction=0x208904b2 "an\002", initial_sp=0x813eec0) at interpret.c:10247
	m = <value optimized out>
	pc = <value optimized out>
	fp = <value optimized out>
	sp = (svalue_t *) 0x813eed0
	num_arg = <value optimized out>
	instruction = 43
	full_instr = <value optimized out>
	expected_stack = (svalue_t *) 0x0
	ap = (svalue_t *) 0x813eed0
	use_ap = 0
	off_tab =   {[0] = 0,
  [1] = 4,
  [2] = 12,
  [3] = 28,
  [4] = 60,
  [5] = 124,
  [6] = 252,
  [7] = 508,
  [8] = 1020,
  [9] = 2044,
  [10] = 4092,
  [11] = 8188,
  [12] = 16380,
  [13] = 32764,
  [14] = 65532,
  [15] = 131068,
  [16] = 262140,
  [17] = 524284,
  [18] = 1048572,
  [19] = 2097148}
#5  0x080a1ea1 in apply_low (fun=0x11e9723c, ob=0x1ac5c570, num_arg=0, b_ign_prot=0, allowRefs=0) at interpret.c:16811
	flags = <value optimized out>
	funstart = (fun_hdr_p) 0x208904b0 ""
	fx = 20
	progp = (program_t *) 0x2088f370
	save_csp = <value optimized out>
	ix = <value optimized out>
#6  0x080a280a in int_apply (fun=0x11e9723c, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
No locals.
#7  0x0808fe88 in eval_instruction (first_instruction=0x2242d66e "a\036", initial_sp=0x813eea8) at interpret.c:16159
	v = <value optimized out>
	size = <value optimized out>
	i1 = <value optimized out>
	i2 = <value optimized out>
	pc = <value optimized out>
	fp = <value optimized out>
	sp = <value optimized out>
	num_arg = <value optimized out>
	instruction = 187
	full_instr = <value optimized out>
	expected_stack = (svalue_t *) 0x0
	ap = (svalue_t *) 0x813eeb8
	use_ap = 0
	off_tab =   {[0] = 0,
  [1] = 4,
  [2] = 12,
  [3] = 28,
  [4] = 60,
  [5] = 124,
  [6] = 252,
  [7] = 508,
  [8] = 1020,
  [9] = 2044,
  [10] = 4092,
  [11] = 8188,
  [12] = 16380,
  [13] = 32764,
  [14] = 65532,
  [15] = 131068,
  [16] = 262140,
  [17] = 524284,
  [18] = 1048572,
  [19] = 2097148}
#8  0x080a1ea1 in apply_low (fun=0x967150c, ob=0xb5b26bc, num_arg=3, b_ign_prot=0, allowRefs=0) at interpret.c:16811
	flags = <value optimized out>
	funstart = (fun_hdr_p) 0x2242d66c "\003"
	fx = 1
	progp = (program_t *) 0x2242d5e8
	save_csp = <value optimized out>
	ix = <value optimized out>
#9  0x080a280a in int_apply (fun=0x967150c, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
No locals.
#10 0x0808fe88 in eval_instruction (first_instruction=0x28261e63 "a\036\001\n>\036\002\b\003a\b\003\a\020b�b{\f(�b{\a)\002\f{\n)\036\aj\017a\n=\036\a\020K*nx", 
    initial_sp=0x813ee78) at interpret.c:16159
	v = <value optimized out>
	size = <value optimized out>
	i1 = <value optimized out>
	i2 = <value optimized out>
	pc = <value optimized out>
	fp = <value optimized out>
	sp = <value optimized out>
	num_arg = <value optimized out>
	instruction = 187
	full_instr = <value optimized out>
	expected_stack = (svalue_t *) 0x0
	ap = (svalue_t *) 0x813ee88
	use_ap = 0
	off_tab =   {[0] = 0,
  [1] = 4,
  [2] = 12,
  [3] = 28,
  [4] = 60,
  [5] = 124,
  [6] = 252,
  [7] = 508,
  [8] = 1020,
  [9] = 2044,
  [10] = 4092,
  [11] = 8188,
  [12] = 16380,
  [13] = 32764,
  [14] = 65532,
  [15] = 131068,
  [16] = 262140,
  [17] = 524284,
  [18] = 1048572,
  [19] = 2097148}
#11 0x080e7350 in catch_instruction (flags=0, offset=21, i_sp=0x81b4c04, 
    i_pc=0x28261e63 "a\036\001\n>\036\002\b\003a\b\003\a\020b�b{\f(�b{\a)\002\f{\n)\036\aj\017a\n=\036\a\020K*nx", i_fp=0x813ee10, reserve_cost=4000, i_context=0x0)
    at simulate.c:447
	rc = <value optimized out>
	old_out_of_memory = 0
#12 0x0808bf35 in eval_instruction (first_instruction=0x28261d3a "`\001\fanN", initial_sp=0x813ee70) at interpret.c:9381
	offset = 0
	flags = 0
	reserve_cost = <value optimized out>
	pc = <value optimized out>
	fp = <value optimized out>
	sp = <value optimized out>
	num_arg = <value optimized out>
	instruction = 31
	full_instr = <value optimized out>
	expected_stack = (svalue_t *) 0x0
	ap = (svalue_t *) 0x813ee80
	use_ap = 0
	off_tab =   {[0] = 0,
  [1] = 4,
  [2] = 12,
  [3] = 28,
  [4] = 60,
  [5] = 124,
  [6] = 252,
  [7] = 508,
  [8] = 1020,
  [9] = 2044,
  [10] = 4092,
  [11] = 8188,
  [12] = 16380,
  [13] = 32764,
  [14] = 65532,
  [15] = 131068,
  [16] = 262140,
  [17] = 524284,
  [18] = 1048572,
  [19] = 2097148}
#13 0x080a1ea1 in apply_low (fun=0xa21bc70, ob=0x1350ed60, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811
	flags = <value optimized out>
	funstart = (fun_hdr_p) 0xc <Address 0xc out of bounds>
	fx = 260010820
	progp = (program_t *) 0x282617c8
	save_csp = <value optimized out>
	ix = <value optimized out>
#14 0x080a280a in int_apply (fun=0xa21bc70, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
No locals.
#15 0x0808fe88 in eval_instruction (first_instruction=0x282676be "`\001\003a\ff\036", initial_sp=0x813edd0) at interpret.c:16159
	v = <value optimized out>
	size = <value optimized out>
	i1 = <value optimized out>
	i2 = <value optimized out>
	pc = <value optimized out>
	fp = <value optimized out>
	sp = <value optimized out>
	num_arg = <value optimized out>
	instruction = 187
	full_instr = <value optimized out>
	expected_stack = (svalue_t *) 0x0
	ap = (svalue_t *) 0x813ee00
	use_ap = 0
	off_tab =   {[0] = 0,
  [1] = 4,
  [2] = 12,
  [3] = 28,
  [4] = 60,
  [5] = 124,
  [6] = 252,
  [7] = 508,
  [8] = 1020,
  [9] = 2044,
  [10] = 4092,
  [11] = 8188,
  [12] = 16380,
  [13] = 32764,
  [14] = 65532,
  [15] = 131068,
  [16] = 262140,
  [17] = 524284,
  [18] = 1048572,
  [19] = 2097148}
#16 0x080a1ea1 in apply_low (fun=0xa20bc38, ob=0x1350ed60, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811
	flags = <value optimized out>
	funstart = (fun_hdr_p) 0x282676bc "\001\005`\001\003a\ff\036"
	fx = 14
	progp = (program_t *) 0x282617c8
	save_csp = <value optimized out>
	ix = <value optimized out>
#17 0x080a280a in int_apply (fun=0xa20bc38, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
No locals.
#18 0x080a4799 in sapply_int (fun=0xa20bc38, ob=0x1350ed60, num_arg=1, b_find_static=0, b_use_default=1) at interpret.c:17050
	expected_sp = <value optimized out>
#19 0x0804bca9 in parse_command (buff=0xbf8cad66 "xcall dmaster->stopphase5()", from_efun=0) at actions.c:1098
	ret = (svalue_t *) 0x811687c
	type = <value optimized out>
	command_object = (object_t *) 0x1350ed60
	next = <value optimized out>
	insert = <value optimized out>
	p = <value optimized out>
	s = (sentence_t *) 0x1b9259dc
	marker_sent = <value optimized out>
	length = 5
	save_current_object = (object_t *) 0x0
	save_command_giver = (object_t *) 0xe79bb10
#20 0x0804ddaf in execute_command (str=0xbf8cad66 "xcall dmaster->stopphase5()", ob=0xe79bb10) at actions.c:1258
	context = {
  rt = {
    last = 0x8170280, 
    type = -1
  }, 
  this_player = 0xe79bb10, 
  mark_player = 0x0, 
  marker = 0x0, 
  cmd = 0x0, 
  verb = 0x0, 
  action_verb = 0x0, 
  errmsg = {
    type = 3, 
    x = {
      exponent = 0, 
      closure_type = 0, 
      quotes = 0, 
      num_arg = 0, 
      extern_args = 0, 
      generic = 0
    }, 
    u = {
      str = 0x9b2e420, 
      charp = 0x9b2e420 "\t", 
      number = 162718752, 
      ob = 0x9b2e420, 
      vec = 0x9b2e420, 
      strct = 0x9b2e420, 
      map = 0x9b2e420, 
      lambda = 0x9b2e420, 
      mantissa = 162718752, 
      cb = 0x9b2e420, 
      generic = 0x9b2e420, 
      lvalue = 0x9b2e420, 
      protected_lvalue = 0x9b2e420, 
      protected_char_lvalue = 0x9b2e420, 
      protected_range_lvalue = 0x9b2e420, 
      error_handler = 0x9b2e420
    }
  }, 
  errobj = 0x14773d8c
}
	res = <value optimized out>
#21 0x08054612 in backend () at backend.c:671
	time_now = 1188167163
	buf =   "2007.08.27 00:26:03 Garbage collection req by allocator (slow_shut to do: 0, time since last gc: 1188167163\n\000\b\b�\214�\v\004\b\b8�"
	buff =   "xcall dmaster->stopphase5()", '\0' <repeats 973 times>, "wait;no;wait;n;wait;no;wait;no;wait;o;wait;no;wait;no;wait;no;wait;no;wait;o;wait;o;wait;o;wait;s;wait;so;wait;so;wait;o;wait;o;wait;n;wait;n;wait;n;wait;n;wait;n;"...
	prevent_object_cleanup = 0
#22 0x080b2435 in main (argc=Cannot access memory at address 0x0
) at main.c:615
	path =   "/home/mud/mudlib", '\0' <repeats 1609 times>, "�w�\f�\214�i��\223\212ַ�w��O��Q�\000\000\000\000\214�\214�\234V�", '\0' <repeats 24 times>, "\223\212ַ\000\000\000\000 P�", '\0' <repeats 12 times>, "8u�", '\0' <repeats 20 times>, ".��", '\0' <repeats 16 times>, "xw�\220�\214�i��\205\227�\204w��O�8u�L\225�\020�\214�\234V�\205\227�\217\227�", '\0' <repeats 16 times>, "\205\227�\000\000\000\000 P�", '\0' <repeats 12 times>...
	i = 5
	set = {
  __val =     {[0] = 8192,
    [1] = 0 <repeats 31 times>}
}
	rc = 0
stack (9,525 bytes)   

2007-09-19 20:21

 

destructedkeys.diff (3,310 bytes)   
Index: trunk/src/mapping.c
===================================================================
--- trunk/src/mapping.c	(Revision 2314)
+++ trunk/src/mapping.c	(Arbeitskopie)
@@ -1450,6 +1450,7 @@
     mapping_hash_t * hm, *hm2 = NULL;
     mapping_cond_t * cm, *cm2 = NULL;
     mp_int common_width;  /* == min(num_values, new_width) */
+    p_int  num_entries;
 
     /* Set the width variables */
     if (m->num_values >= new_width)
@@ -1475,6 +1476,8 @@
         }
 
     }
+    
+    num_entries = m->num_entries;
 
     /* Get the target mapping without a hash, but with a condensed block
      * big enough to hold all entries.
@@ -1531,39 +1534,42 @@
             map_chain_t *last = NULL, *mc, *mc2;
 
             for (mc = *mcp++; mc; mc = mc->next)
-            {
-                svalue_t *src, *dest;
-                p_int i;
-
-                mc2 = new_map_chain(m2);
-                if (!mc2)
+                if(destructed_object_ref(&(mc->data[0])))
+                    num_entries--;
+                else
                 {
-                    xfree(hm2);
-                    outofmem(SIZEOF_MCH(mc, new_width), "hash link");
-                    /* NOTREACHED */
-                    return NULL;
-                }
+                    svalue_t *src, *dest;
+                    p_int i;
 
-                /* Copy the key and the common values */
-                for (src = &(mc->data[0]), dest = &(mc2->data[0]), i = common_width
-                    ; i >= 0
-                    ; --i, src++, dest++)
-                {
-                    assign_svalue_no_free(dest, src);
-                }
+                    mc2 = new_map_chain(m2);
+                    if (!mc2)
+                    {
+                        xfree(hm2);
+                        outofmem(SIZEOF_MCH(mc, new_width), "hash link");
+                        /* NOTREACHED */
+                        return NULL;
+                    }
 
-                /* Zero out any extraneous values */
-                for (dest = &(mc2->data[common_width+1]), i = new_width - common_width
-                    ; i > 0
-                    ; --i, dest++)
-                {
-                    put_number(dest, 0);
-                }
+                    /* Copy the key and the common values */
+                    for (src = &(mc->data[0]), dest = &(mc2->data[0]), i = common_width
+                        ; i >= 0
+                        ; --i, src++, dest++)
+                    {
+                        assign_svalue_no_free(dest, src);
+                    }
 
+                    /* Zero out any extraneous values */
+                    for (dest = &(mc2->data[common_width+1]), i = new_width - common_width
+                        ; i > 0
+                        ; --i, dest++)
+                    {
+                        put_number(dest, 0);
+                    }
 
-                mc2->next = last;
-                last = mc2;
-            }
+
+                    mc2->next = last;
+                    last = mc2;
+                }
             *mcp2++ = last;
         } while (--size);
 
@@ -1616,7 +1622,7 @@
     /* --- Finalize the basis structure ---
      */
 
-    m2->num_entries = m->num_entries;
+    m2->num_entries = num_entries;
 
     /* That's it. */
     return m2;
destructedkeys.diff (3,310 bytes)   

2007-09-19 20:46

 

destructedkeys_v2.diff (4,169 bytes)   
Index: trunk/src/mapping.c
===================================================================
--- trunk/src/mapping.c	(Revision 2314)
+++ trunk/src/mapping.c	(Arbeitskopie)
@@ -1450,6 +1450,7 @@
     mapping_hash_t * hm, *hm2 = NULL;
     mapping_cond_t * cm, *cm2 = NULL;
     mp_int common_width;  /* == min(num_values, new_width) */
+    p_int  num_entries;
 
     /* Set the width variables */
     if (m->num_values >= new_width)
@@ -1475,6 +1476,8 @@
         }
 
     }
+    
+    num_entries = m->num_entries;
 
     /* Get the target mapping without a hash, but with a condensed block
      * big enough to hold all entries.
@@ -1531,39 +1534,42 @@
             map_chain_t *last = NULL, *mc, *mc2;
 
             for (mc = *mcp++; mc; mc = mc->next)
-            {
-                svalue_t *src, *dest;
-                p_int i;
-
-                mc2 = new_map_chain(m2);
-                if (!mc2)
+                if(destructed_object_ref(&(mc->data[0])))
+                    num_entries--;
+                else
                 {
-                    xfree(hm2);
-                    outofmem(SIZEOF_MCH(mc, new_width), "hash link");
-                    /* NOTREACHED */
-                    return NULL;
-                }
+                    svalue_t *src, *dest;
+                    p_int i;
 
-                /* Copy the key and the common values */
-                for (src = &(mc->data[0]), dest = &(mc2->data[0]), i = common_width
-                    ; i >= 0
-                    ; --i, src++, dest++)
-                {
-                    assign_svalue_no_free(dest, src);
-                }
+                    mc2 = new_map_chain(m2);
+                    if (!mc2)
+                    {
+                        xfree(hm2);
+                        outofmem(SIZEOF_MCH(mc, new_width), "hash link");
+                        /* NOTREACHED */
+                        return NULL;
+                    }
 
-                /* Zero out any extraneous values */
-                for (dest = &(mc2->data[common_width+1]), i = new_width - common_width
-                    ; i > 0
-                    ; --i, dest++)
-                {
-                    put_number(dest, 0);
-                }
+                    /* Copy the key and the common values */
+                    for (src = &(mc->data[0]), dest = &(mc2->data[0]), i = common_width
+                        ; i >= 0
+                        ; --i, src++, dest++)
+                    {
+                        assign_svalue_no_free(dest, src);
+                    }
 
+                    /* Zero out any extraneous values */
+                    for (dest = &(mc2->data[common_width+1]), i = new_width - common_width
+                        ; i > 0
+                        ; --i, dest++)
+                    {
+                        put_number(dest, 0);
+                    }
 
-                mc2->next = last;
-                last = mc2;
-            }
+
+                    mc2->next = last;
+                    last = mc2;
+                }
             *mcp2++ = last;
         } while (--size);
 
@@ -1595,10 +1601,26 @@
             ; src_ix < cm->size
             ; src_ix++, src_key++)
         {
-            if (src_key->type != T_INVALID)
+            if (src_key->type == T_INVALID)
+                ; // Do nothing
+            else if (destructed_object_ref(src_key))
             {
+                // We have to fill the space.
+                // (Alternatively we could decrease m->cond->size.)
                 p_int i;
 
+                num_entries--;
+
+                dest_key->type = T_INVALID;
+                dest_key++;
+
+                for (i = new_width; i > 0; i--, dest_data++)
+                    put_number(dest_data, 0);
+            }
+            else
+            {
+                p_int i;
+
                 src_data = COND_DATA(cm, src_ix, m->num_values);
 
                 /* Copy the key and the common data */
@@ -1616,7 +1638,7 @@
     /* --- Finalize the basis structure ---
      */
 
-    m2->num_entries = m->num_entries;
+    m2->num_entries = num_entries;
 
     /* That's it. */
     return m2;
destructedkeys_v2.diff (4,169 bytes)   

Gnomi

2007-09-19 20:54

manager   ~0000543

m = m - ([0]) creates a shallow copy of the mapping (via copy_mapping as an alias for resize_mapping()). But resize_mapping() requires that check_map_for_destr() is called before, because otherwise assign_svalue_no_free would zero out destructed objects even if they are a key in the mapping. Two uses of copy_mapping() don't do this (inl_copy_svalue_no_free and subtract_mapping) and that's why the number 0 shows up in a hash chain where it doesn't belong.

I attached a patch to make resize_mapping aware of destructed object references as keys, alternatively you could just call check_map_for_destr() in inl_copy_svlaue_no_free and subtract_mapping.

Greetings,
Gnomi.

lars

2007-10-01 02:14

reporter   ~0000546

Resolved with Gnomi's v2 patch.

Issue History

Date Modified Username Field Change
2007-09-19 15:10 zesstra New Issue
2007-09-19 17:12 zesstra File Added: stack
2007-09-19 20:21 Gnomi File Added: destructedkeys.diff
2007-09-19 20:46 Gnomi File Added: destructedkeys_v2.diff
2007-09-19 20:54 Gnomi Note Added: 0000543
2007-10-01 02:14 lars Note Added: 0000546
2007-10-01 02:14 lars Status new => resolved
2007-10-01 02:21 lars Resolution open => fixed
2007-10-01 02:21 lars Fixed in Version => 3.3.716
2010-11-16 10:42 lars Source_changeset_attached => ldmud.git master a9a0af7a
2013-02-24 01:05 zesstra Relationship added related to 0000816
2018-01-29 19:59 lars Source_changeset_attached => ldmud.git master a9a0af7a
2018-01-29 22:57 lars Source_changeset_attached => ldmud.git master a9a0af7a