Recent

Author Topic: TBufferedFileStream crashes in SetSize()  (Read 734 times)

AlexTP

  • Hero Member
  • *****
  • Posts: 2302
    • UVviewsoft
TBufferedFileStream crashes in SetSize()
« on: October 02, 2023, 07:58:52 pm »
I use this code to save some lines to file.

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. {$h+}
  3.  
  4. uses sysutils, classes, bufstream;
  5.  
  6. procedure Save(const filename: string; L: TStringList);
  7. var
  8.   fs: TBufferedFileStream; //improves saving speed a lot
  9.   NMode: word;
  10.   buf: string;
  11.   i: integer;
  12. begin
  13.   NMode:= fmOpenReadWrite or fmShareDenyWrite;
  14.   //don't set fmCreate for existing file, to keep NTFS file streams
  15.   if not FileExists(filename) then
  16.     NMode:= NMode or fmCreate;
  17.  
  18.   fs:= TBufferedFileStream.Create(filename, NMode);
  19.   try
  20.     fs.Size:= 0;
  21.     for i:= 0 to L.Count-1 do
  22.     begin
  23.       buf:= L[i]+#10;
  24.       fs.WriteBuffer(buf[1], length(buf));
  25.     end;
  26.   finally
  27.     FreeAndNil(fs);
  28.   end;
  29. end;
  30.  
  31. var
  32.   L: TStringList;
  33. begin
  34.   L:= TStringList.Create;
  35.   L.Add('line one;');
  36.   L.Add('line two;');
  37.   L.Add('line end;');
  38.   Save('test.log', L);
  39.  
  40.   L.Clear;
  41.   L.Add('line one;');
  42.   Save('test.log', L);
  43.  
  44.   L.Free;
  45.  
  46. end.
  47.  

fs.Size:=0 is nessesary - without it, old contents of the file will be kept and smaller file will be having tail from old content.

But, app now crashes on fs.Size:=0. SIGSEGV.

Quote
BUFSTREAM$_$TBUFFEREDFILESTREAM_$__$$_SETSIZE64$INT64
000000000047EDD0 53                       push rbx
000000000047EDD1 4154                     push r12

With TFileStream, no such error.
Free Pascal Compiler version 3.2.3-772-gd520814adb [2023/09/05] for x86_64

Bart

  • Hero Member
  • *****
  • Posts: 5150
    • Bart en Mariska's Webstek
Re: TBufferedFileStream crashes in SetSize()
« Reply #1 on: October 02, 2023, 10:21:03 pm »
With fpc 3.2.2 on Win32 I get a stack overflow.
TBufferedFileStream.SetSize64(const NewSize: Int64) -> inherited SetSize64(NewSize), which resolves to SetSize, which then calls SetSize64 again ...

And it's the same with fpc main.

Bart
« Last Edit: October 02, 2023, 10:36:17 pm by Bart »

wp

  • Hero Member
  • *****
  • Posts: 11485
Re: TBufferedFileStream crashes in SetSize()
« Reply #2 on: October 02, 2023, 10:31:20 pm »
IIRC, I had problems with the TBufferedFileStream in fpspreadsheet, too, and ended up in writing a TBufFileStream class myself. The init is "fpsStreams" in folder source/common of the fpspreadsheet installation, or separately here: https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fpspreadsheet/source/common/fpsstreams.pas. It is self-contained and does not depend on other fpspreadsheet units.

Bart

  • Hero Member
  • *****
  • Posts: 5150
    • Bart en Mariska's Webstek
Re: TBufferedFileStream crashes in SetSize()
« Reply #3 on: October 02, 2023, 10:35:37 pm »
If I fix the stack overflow (call inherited SetSize, not inherited SetSize64) then later on I get
Code: [Select]
An unhandled exception occurred at $0042B982:
EStreamError: CACHE: Unable to read expected bytes (Open for write only ?). Expected: 30, effective read: 0
  $0042B982  ReadPageBeforeWrite,  line 543 of bufstream.pp

It does not matter if the file exists, or not at program start.

It seems to crash at the second call to Save() though.
If I comment that out, the program runs fine.

[edit]
Investigating this further: the program crashes (already in the first call to Save) if the file exists and the filesize is > 0 bytes.

Bart
« Last Edit: October 02, 2023, 10:43:32 pm by Bart »

TRon

  • Hero Member
  • *****
  • Posts: 1872
Re: TBufferedFileStream crashes in SetSize()
« Reply #4 on: October 03, 2023, 02:33:46 pm »
@AlexTP:
This is keep haunting you, isn't it ?  :)

For me a segmentation fault at setsize.

Strange as one of the arguments for author to write the class in the first place seem to have been to be able to set the size of the file, see https://fpc-devel.freepascal.narkive.com/X1GPyj00/tbufferedfilestream

¯\_(ツ)_/¯

Bart

  • Hero Member
  • *****
  • Posts: 5150
    • Bart en Mariska's Webstek
Re: TBufferedFileStream crashes in SetSize()
« Reply #5 on: October 03, 2023, 04:15:33 pm »
@Alexey: file a bugreport?

Bart

AlexTP

  • Hero Member
  • *****
  • Posts: 2302
    • UVviewsoft
Re: TBufferedFileStream crashes in SetSize()
« Reply #6 on: October 03, 2023, 06:13:54 pm »

 

TinyPortal © 2005-2018