Forum > General
Access violation on Free
(1/1)
Leledumbo:
NOTE: please download the attached source and compile (requires fpc version with TFPGObjectList in fgl unit)
I'd like to improve my compiler so that it could process incorrect source as well (no crash, no leaks). So I try removing one closing block symbol and raise an exception in some parsing routines. Here's a little look:
--- Code: ---function TEMLParser.Parse: TEMLERD;
begin
try
Result := ParseERD;
except
on e: EEndOfFile do
with FLexer.CurrentToken do
FErrorList.Add(TParseError.Create(Line,Col,e.Message));
end;
end;
...
function TEMLParser.ParseEntities: TEMLEntities;
begin
Result := TEMLEntities.Create;
Expected(tkEntities);
Expected(tkOpenBlock);
while not Accepted(tkCloseBlock) and not Accepted(tkEOF) do
Result.AddEntity(ParseEntity);
if FLexer.CurrentToken.Kind = tkEOF then
raise EEndOfFile.Create;
end;
--- End code ---
Here's how Parse gets called in the program:
--- Code: ---Parser := TEMLParser.Create(TEMLLexer.Create(InputStream));
with Parser do
try
AST := Parser.Parse;
if Errors.Count > 0 then
for i := 0 to Errors.Count - 1 do
WriteLn(StdErr,{ParamStr(1) + ' ' + }TParseError(Errors[i]).Message)
else begin
try
CodeLines := TStringList.Create;
AST.GetCode(CodeLines);
WriteLn(CodeLines.Text);
finally
CodeLines.Free;
end;
end;
AST.Free;
finally
Parser.Free;
end;
--- End code ---
Compiled with -glh, I got access violation on Parser.Free, and many unfreed blocks.
--- Quote ---(7,3): tkIdentifier expected, but tkRelationships(relationships) found
(10,3): tkOpenBlock expected, but tkCloseBlock(}) found
(10,3): tkIdentifier expected, but tkCloseBlock(}) found
(12,1): End of file encountered in the middle of parsing
Access violation
Heap dump by heaptrc unit
376 memory blocks allocated : 11706/13880
350 memory blocks freed : 8037/10120
26 unfreed memory blocks : 3669
True heap size : 360448 (128 used in System startup)
True free heap : 354640
Should be : 354896
Call trace for block $0008E540 size 264
$00424A56 TEMLPARSER__PARSEENTITY, line 116 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $000601B0 size 20
$004095B8
$00424BAF TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008E3F0 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BA5 TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0006D8D8 size 25
$00424B9A TEMLPARSER__PARSEFIELDS, line 135 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008E2A0 size 264
$00424A56 TEMLPARSER__PARSEENTITY, line 116 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008E150 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BBC TEMLPARSER__PARSEFIELDS, line 139 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0005FEB0 size 20
$004095B8
$00424BAF TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008E000 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BA5 TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0006D868 size 25
$00424B9A TEMLPARSER__PARSEFIELDS, line 135 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008DEB0 size 264
$00424A56 TEMLPARSER__PARSEENTITY, line 116 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008DD60 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BBC TEMLPARSER__PARSEFIELDS, line 139 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008DC10 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BBC TEMLPARSER__PARSEFIELDS, line 139 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0005F790 size 20
$004095B8
$00424BAF TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008DAC0 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BA5 TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0006D7F8 size 25
$00424B9A TEMLPARSER__PARSEFIELDS, line 135 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0005F3D0 size 20
$004095B8
$0042611F TEMLENTITIES__ADDENTITY, line 208 of emlast.pp
$0042493A TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
$0040CDB1
Call trace for block $0008D970 size 264
$00424A56 TEMLPARSER__PARSEENTITY, line 116 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008D820 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BBC TEMLPARSER__PARSEFIELDS, line 139 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008D6D0 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BBC TEMLPARSER__PARSEFIELDS, line 139 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0005F010 size 20
$004095B8
$00424BAF TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0008D580 size 261
$00424B4E TEMLPARSER__PARSEFIELD, line 130 of emlparser.pas
$00424BA5 TEMLPARSER__PARSEFIELDS, line 137 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0006D718 size 25
$00424B9A TEMLPARSER__PARSEFIELDS, line 135 of emlparser.pas
$00424A1B TEMLPARSER__PARSEENTITY, line 113 of emlparser.pas
$00424930 TEMLPARSER__PARSEENTITIES, line 100 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0006D6A8 size 25
$00425FE5 TEMLENTITIES__CREATE, line 197 of emlast.pp
$00424908 TEMLPARSER__PARSEENTITIES, line 95 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $00075658 size 8
$00424908 TEMLPARSER__PARSEENTITIES, line 95 of emlparser.pas
$00424872 TEMLPARSER__PARSEERD, line 86 of emlparser.pas
$00425301 TEMLPARSER__PARSE, line 238 of emlparser.pas
$00401653 main, line 25 of emlc.lpr
$0040CDB1
Call trace for block $0005E5F0 size 12
$004015DF main, line 17 of emlc.lpr
$0040CDB1
Call trace for block $0005E590 size 19
$004015CD main, line 17 of emlc.lpr
$0040CDB1
--- End quote ---
Could anyone help me?
bobc:
Clearly a function which raises an exception does not return the result you are expecting, in my tests it appears to return 0 or nil depending on type.
I don't know what the language spec says, I could not find a reference to this.
In general I would not expect that after an exception any results from an inner function or procedure could be relied on (i.e. result or var parameters).
On a style note, it could be considered debatable whether end of file is an unexpected condition. Sure its an error condition, just maybe not an exception?
Either way, I would prefer to deallocate resources closer to where they are allocated, especially in an exception condition.
In a recursive descent parser, an end of file condition could be handled by ending the current block normally. This would leave a sane parse tree even if not syntactically valid.
Leledumbo:
--- Quote ---On a style note, it could be considered debatable whether end of file is an unexpected condition. Sure its an error condition, just maybe not an exception?
Either way, I would prefer to deallocate resources closer to where they are allocated, especially in an exception condition.
In a recursive descent parser, an end of file condition could be handled by ending the current block normally. This would leave a sane parse tree even if not syntactically valid.
--- End quote ---
After re-thinking, I thought the use of exception is indeed overkill. All methods would automatically stop when it encounters unexpected token, in this case the end of file. I'll try removing the exception to see whether it could cause infinite loop or not.
Navigation
[0] Message Index