View Issue Details

IDProjectCategoryView StatusLast Update
0000494LDMudLPC Compiler/Preprocessorpublic2018-01-29 21:57
ReporterGnomi Assigned Tolars 
PrioritynormalSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
Platformi686OSDebian GNU/LinuxOS Version3.1
Summary0000494: 'struct abc abc;' in a global context crashes if the structure is undefined
DescriptionJust 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.
TagsNo 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);
             }
         }
     }
idents.diff (3,371 bytes)   
External Data (URL)

Activities

Gnomi

2006-11-15 02:22

manager   ~0000524

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.

lars

2007-10-14 00:22

reporter   ~0000570

I don't see why this approach should cause a problem.

Issue History

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 lars Status new => resolved
2007-10-14 00:22 lars Fixed in Version => 3.3.716
2007-10-14 00:22 lars Resolution open => fixed
2007-10-14 00:22 lars Assigned To => lars
2007-10-14 00:22 lars Note Added: 0000570
2010-11-16 09:42 lars Source_changeset_attached => ldmud.git master d7eca4ae
2018-01-29 18:59 lars Source_changeset_attached => ldmud.git master d7eca4ae
2018-01-29 21:57 lars Source_changeset_attached => ldmud.git master d7eca4ae