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 |