Recent

Author Topic: Tstringlist Segfault  (Read 4107 times)

liewald

  • Full Member
  • ***
  • Posts: 142
Tstringlist Segfault
« on: September 26, 2017, 11:14:02 am »
Lazarus 1.6.4 rUnknown FPC 3.0.0 x86_64-linux-gtk 2
Opensuse Leap 42.3

I'm suddenly getting a segfault when assigning a value to a stringlist, I'm not doing anything particularity complex

initialising stringlist with

for I := 0 to indata.count-1 do
  begin
    outstring := ' ';
    outdata.Add(outstring);
  end;

and then assigning a value  using

outdata.strings[offset] := outstring;  in another procedure

where offset is passed into the procedure from a loop

outdata.strings[0]'th entry is replaced fine but fails on outdata.strings[1] entry fails with a segfault

outdata.count is returning the correct number of strings available within the stringlist.

Driving me nuts

the reason for doing it this way is to create an output object for running the process multithreaded, was working perfectly but suddenly crashed out and now I cant get it to run ( ?? linux update))

Dave




marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Tstringlist Segfault
« Reply #1 on: September 26, 2017, 11:40:28 am »
You are showing only partial code, so we can't see anything, how do you .create the class?

liewald

  • Full Member
  • ***
  • Posts: 142
Re: Tstringlist Segfault
« Reply #2 on: September 26, 2017, 11:43:33 am »
yup

Sorry there is masses of code involved. as I mentioned everything was running fine then collapsed with no real code change

procedure TForm1.FormCreate(Sender: TObject);
begin
  indata := tstringlist.create;
  outdata := tstringlist.Create;
  dosepositions := tthreadstringlist.create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  indata.destroy;
  outdata.destroy;
  dosepositions.destroy;
end; 

Dave

liewald

  • Full Member
  • ***
  • Posts: 142
Re: Tstringlist Segfault
« Reply #3 on: September 26, 2017, 11:45:32 am »
here's the procedure

procedure TForm1.process_string(Index: integer);

const delims = [#9];

var I,hpos: integer;
     datastring, outstring : ansistring ;
     doseoffsets : array of integer;
     offset : integer;

begin
  offset := index;
  outstring := '';
  datastring := indata[index];
  setlength(doseoffsets,dosepositions.Count-1);

  hpos := wordposition(3,datastring,delims);

  for i := 0 to dosepositions.count -1 do
  doseoffsets :=  hpos + ((strtoint(dosepositions)) * 6);

  outstring := extractword(1,datastring,delims) + #9 + extractword(2,datastring,delims) ;

  for i := 0 to dosepositions.count-1 do
  begin
    outstring := outstring + #9 + copy(datastring,doseoffsets,5);
  end;
  outdata.strings[offset] := outstring;
end;       

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: Tstringlist Segfault
« Reply #4 on: September 26, 2017, 11:55:05 am »
Please always put code between the code-tags
[code]your code[/code]
(otherwise it will not be formatted correctly and parts will be invisible, like [i] which is italic-font switch)

Or select your code and press the #-button above the editor (it will insert [code=pascal]yourcode[/code] automatically).

I've done it in your quote below.

here's the procedure

Code: Pascal  [Select][+][-]
  1. procedure TForm1.process_string(Index: integer);
  2.  
  3. const delims = [#9];
  4.  
  5. var I,hpos: integer;
  6.      datastring, outstring : ansistring ;
  7.      doseoffsets : array of integer;
  8.      offset : integer;
  9.  
  10. begin
  11.   offset := index;
  12.   outstring := '';
  13.   datastring := indata[index];
  14.   setlength(doseoffsets,dosepositions.Count-1);
  15.  
  16.   hpos := wordposition(3,datastring,delims);
  17.  
  18.   for i := 0 to dosepositions.count -1 do
  19.   doseoffsets[i] :=  hpos + ((strtoint(dosepositions[i])) * 6);
  20.  
  21.   outstring := extractword(1,datastring,delims) + #9 + extractword(2,datastring,delims) ;
  22.  
  23.   for i := 0 to dosepositions.count-1 do
  24.   begin
  25.     outstring := outstring + #9 + copy(datastring,doseoffsets[i],5);
  26.   end;
  27.   outdata.strings[offset] := outstring;
  28. end;      

liewald

  • Full Member
  • ***
  • Posts: 142
Re: Tstringlist Segfault
« Reply #5 on: September 26, 2017, 11:57:18 am »
willdo

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Tstringlist Segfault
« Reply #6 on: September 26, 2017, 12:59:31 pm »
Just check if the index is in the correct range before you use it, e.g.

Code: Pascal  [Select][+][-]
  1. if Not ( (index>=0) and (index<indata.count)) then
  2.    showmessage('out of bounds access in indata');
  3.  datastring := indata[index];

etc for places.

liewald

  • Full Member
  • ***
  • Posts: 142
Re: Tstringlist Segfault
« Reply #7 on: September 26, 2017, 02:13:04 pm »
OK I've sort of got it working.

All a bit strange!!!

because of the size of the data ( Multi-Terrabye Genetics, typical file 16-18GB text file) with wide strings I have typically loaded the strings as ansistrings and then added those to the stringlist. Up till now this has never been an issue (and on the file load and save) it still isn't. However in this routine for some reason trying to add, set or append an ansistring to the stringlist causes it to commit suicide! However if I use strings rather than ansistrings within the procedure it seems to work, even when it's multi-threaded. So my guess is it's probably something in the ansistring copy routine that's causing the segfault.

Dave

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: Tstringlist Segfault
« Reply #8 on: September 26, 2017, 04:11:46 pm »
We can not do it  because outdata.strins[offset] is empty with a null value
(outstring is a null value and outdata is empt yet)
Code: Pascal  [Select][+][-]
  1. outdata.strings[offset] := outstring;  in another procedure
  2.  
CSV Comp DB Developer {Pascal Lover}

liewald

  • Full Member
  • ***
  • Posts: 142
Re: Tstringlist Segfault
« Reply #9 on: October 02, 2017, 03:55:06 pm »
We can not do it  because outdata.strins[offset] is empty with a null value
(outstring is a null value and outdata is empt yet)
Code: Pascal  [Select][+][-]
  1. outdata.strings[offset] := outstring;  in another procedure
  2.  
 

the outdata is actually not empty it is set to valid strings elsewhere in the program before this routine. Also this procedure actually works on the initial 2 or three passes then fails.

it is really strange and seems to be data dependent. it will work on one file perfectly but on another file with a slightly different dataset it fails, although the data looks valid and has been used in different programs.

I have also tried using an array of strings rather than a stringlist and the same problem occurs

 

TinyPortal © 2005-2018