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 |