View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update | 
|---|---|---|---|---|---|
| 0000494 | LDMud | LPC Compiler/Preprocessor | public | 2006-11-14 06:50 | 2018-01-29 21:57 | 
| Reporter | Gnomi | Assigned To | |||
| Priority | normal | Severity | crash | Reproducibility | always | 
| Status | resolved | Resolution | fixed | ||
| Platform | i686 | OS | Debian GNU/Linux | OS Version | 3.1 | 
| Summary | 0000494: 'struct abc abc;' in a global context crashes if the structure is undefined | ||||
| Description | Just a file s.c with the line struct abc abc; crashes the driver. 2006.11.14 13:30:57 w/gnomi/s.c line 1: Unknown struct 'abc' before ';'. 2006.11.14 13:30:57 w/gnomi/s.c line 1: Missing type before end of line. Program terminated with signal 11, Segmentation fault. #0 0x080df975 in define_variable (name=0x8feedf0, type= {typeflags = 335544320, t_struct = 0x0}) at prolang.y:3302 3302 dummy.name = ref_mstring(name->name); (gdb) bt #0 0x080df975 in define_variable (name=0x8feedf0, type= {typeflags = 335544320, t_struct = 0x0}) at prolang.y:3302 0000001 0x080dfe2f in define_global_variable (name=0x8feedf0, actual_type= {typeflags = 335544320, t_struct = 0x0}, opt_star=0, with_init=0) at prolang.y:3446 0000002 0x080e4f7b in yyparse () at prolang.y:6787 0000003 0x080fa195 in compile_file (fd=11, fname=0xbff0e120 "w/gnomi/s.c", isMasterObj=0) at prolang.y:16713 0000004 0x0810b217 in load_object (lname=0x81f9400 "apps/goetter_register", create_super=0, depth=0, isMasterObj=0, chain=0x0) at simulate.c:1955 0000005 0x0810c0f3 in lookfor_object (str=0x923de3c, bLoad=1) at simulate.c:2397 0000006 0x0810fa0c in f_load_object (sp=0x8173e90) at simulate.c:4466 0000007 0x08093fd2 in eval_instruction ( first_instruction=0x8b4af5e "\036\001\003P\036", initial_sp=0x8173e88) at interpret.c:7974 0000008 0x080af2f7 in int_call_lambda (lsvp=0x8173e78, num_arg=2, allowRefs=0) at interpret.c:17772 0000009 0x080b3c3a in v_funcall (sp=0x8173e88, num_arg=3) at interpret.c:20261 0000010 0x0809517d in eval_instruction ( first_instruction=0x8b4af76 "`\002\005\036", initial_sp=0x8173e68) at interpret.c:8173 0000011 0x080a5fde in eval_instruction ( first_instruction=0x92bd4aa "a\017\003@\036", initial_sp=0x8173e28) at interpret.c:14664 0000012 0x080ada1d in apply_low (fun=0x925189c, ob=0x92a7644, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811 0000013 0x080adc14 in int_apply (fun=0x925189c, ob=0x92a7644, num_arg=1, b_ign_prot=0, b_use_default=1) at interpret.c:16889 #14 0x080ae07e in sapply_int (fun=0x925189c, ob=0x92a7644, num_arg=1, b_find_static=0, b_use_default=1) at interpret.c:17050 #15 0x0804c9ce in parse_command (buff=0xbff105d0 "lade s", from_efun=0) at actions.c:1094 #16 0x0804cf41 in execute_command (str=0xbff105d0 "lade s", ob=0x9094c48) at actions.c:1258 #17 0x08054999 in backend () at backend.c:671 #18 0x080c0079 in main (argc=16, argv=0xbff11f84) at main.c:615 (gdb) The reason is, that the identifier 'abc' from the lexer (with I_TYPE_UNKNOWN) is freed too early. The following happens: The parser asks the lexer for two tokens, it gets L_STRUCT and L_IDENTIFIER. The later has an ident_t for "abc" with I_TYPE_UNKNOWN as the semantic value attached. This is not enough for the parser to decide between shift or reduce, so it requests another token as a look-ahead symbol which is again an L_IDENTIFIER with the same ident_t structure for "abc" as the semantic value (still I_TYPE_UNKNOWN). Now the parser reduces using the rule 'identifier: L_IDENTIFIER'. This rule just takes the name and frees the corresponding ident_t structure, because it is I_TYPE_UNKNOWN. But this structure is still used as the semantic value of the look-ahead L_IDENTIFIER token. So when this token is used later in the 'name_list: type optional_star L_IDENTIFIER' rule, the semantic value is overwritten with some other garbage leading to a crash. I would recommend not to free any shared_identifier during parsing because of these look-ahead symbols. Do they hurt? Greetings, Gnomi.  | ||||
| Tags | No tags attached. | ||||
| Attached Files |  idents.diff (3,371 bytes)   
 
Index: trunk.structs/src/prolang.y
===================================================================
--- trunk.structs/src/prolang.y	(Revision 2314)
+++ trunk.structs/src/prolang.y	(Arbeitskopie)
@@ -6085,7 +6085,6 @@
           {
               /* Identifier -> no such struct encountered yet */
               yyerrorf("Unknown base struct '%s'", get_txt($2->name));
-              free_shared_identifier($2);
           }
           else
           {
@@ -6155,8 +6154,6 @@
           
           assign_full_to_vartype(&type, actual_type);
           add_struct_member($3->name, type, NULL);
-          if ($3->type == I_TYPE_UNKNOWN)
-              free_shared_identifier($3);
             
           $$ = $1;
       }
@@ -6169,8 +6166,6 @@
           
           assign_full_to_vartype(&type, actual_type);
           add_struct_member($4->name, type, NULL);
-          if ($4->type == I_TYPE_UNKNOWN)
-              free_shared_identifier($4);
             
           $$ = $1;
       }
@@ -6533,10 +6528,6 @@
                       , get_txt(last_identifier->name));
               $$[0] = $$[1] = 0;
           }
-
-          /* Free the identifier again if this statement generated it */
-          if (last_identifier->type == I_TYPE_UNKNOWN)
-                free_shared_identifier(last_identifier);
       }
 ; /* inheritance_qualifier */
 
@@ -6690,8 +6681,6 @@
 
           /* Extract the string from the ident structure */
           p = ref_mstring($1->name);
-          if ($1->type == I_TYPE_UNKNOWN)
-              free_shared_identifier($1);
           $$ = p;
       }
 
@@ -12283,11 +12272,6 @@
                                            , $4, (bytecode_p)__PREPARE_INSERT__p
                                            );
 
-                      if ($1.real->type == I_TYPE_UNKNOWN)
-                      {
-                          free_shared_identifier($1.real);
-                      }
-
                       if (ix < 0)
                       {
                           switch(ix) {
@@ -13143,8 +13127,6 @@
       L_IDENTIFIER
       {
           $$ = ystring_copy(get_txt($1->name));
-          if ($1->type == I_TYPE_UNKNOWN)
-              free_shared_identifier($1);
       }
 
     | L_STRING L_STRING
@@ -15954,13 +15936,8 @@
         if (!id)
             fatal("Out of memory: identifier '%s'.\n", get_txt(STR_CALL_OTHER));
 
-        if (id->type == I_TYPE_UNKNOWN)
+        if (id->type != I_TYPE_UNKNOWN)
         {
-            /* No such identifier, therefor no such sefun */
-            free_shared_identifier(id);
-        }
-        else
-        {
             /* This shouldn't be necessary, but just in case... */
             while (id && id->type > I_TYPE_GLOBAL)
                 id = id->inferior;
@@ -16350,6 +16327,8 @@
     }
 
     all_globals = NULL;
+    
+    remove_unknown_identifier();
 
     /* Now create the program structure */
     switch (0) { default:
Index: trunk.structs/src/lex.c
===================================================================
--- trunk.structs/src/lex.c	(Revision 2312)
+++ trunk.structs/src/lex.c	(Arbeitskopie)
@@ -7793,7 +7793,7 @@
             count_ident_refs(id);
             for (id2 = id->inferior; id2 != NULL; id2 = id2->next)
             {
-                count_ident_refs(id);
+                count_ident_refs(id2);
             }
         }
     }
 | ||||
| External Data (URL) | |||||
| 
		 | 
	
	I have uploaded a patch that I'll use in the meanwhile in our test MUD (and later in UNItopia). I have removed every free_shared_identifier in parsing rules and put a remove_unknown_identifier in the epilog instead. I think the above case is the now the only one where an L_IDENTIFIER is processed while another one is saved as a look-ahead token, so strictly speaking only the free_shared_indentifier in the 'identifier: L_IDENTIFIER' rule needs to be removed. But this can change as rules change and then this problem may not be obvious, so I removed all free_shared_identifier calls.  | 
| 
		 | 
	I don't see why this approach should cause a problem. | 
| Date Modified | Username | Field | Change | 
|---|---|---|---|
| 2006-11-14 06:50 | Gnomi | New Issue | |
| 2006-11-15 02:15 | Gnomi | File Added: idents.diff | |
| 2006-11-15 02:22 | Gnomi | Note Added: 0000524 | |
| 2007-10-14 00:22 | 
					 | 
				Status | new => resolved | 
| 2007-10-14 00:22 | 
					 | 
				Fixed in Version | => 3.3.716 | 
| 2007-10-14 00:22 | 
					 | 
				Resolution | open => fixed | 
| 2007-10-14 00:22 | 
					 | 
				Assigned To | => lars | 
| 2007-10-14 00:22 | 
					 | 
				Note Added: 0000570 | |
| 2010-11-16 09:42 | 
					 | 
				Source_changeset_attached | => ldmud.git master d7eca4ae | 
| 2018-01-29 18:59 | 
					 | 
				Source_changeset_attached | => ldmud.git master d7eca4ae | 
| 2018-01-29 21:57 | 
					 | 
				Source_changeset_attached | => ldmud.git master d7eca4ae |