Jump to content
Sign in to follow this  
Al T

[Solved](Delphi 11) (Android 12) 32-bit Debug Segment Fault 11 (TFile.Copy?)

Recommended Posts

[See 2nd Post on Solution]

 

I keep hitting this road-block.  There no source code it's pointing to.  It's just pointing to CPU assembly code.  It's always the same segment fault.  How do I trace it down?

 

The segment fault happens when it gets around 33 or 34 files of ran*.txt.  There's plenty of space left to create hundreds more files, but it likes to stop around 33 or 34 on the ran*.txt Tfile.copy?  I added true to the end of it... but the overwrite parameter didn't help.

 

Error:

BFD: C:/Users/alt/Documents/Embarcadero/Studio/Projects/Filler/Android/Debug/FSP/debug/linker: don't know how to handle section `.relr.dyn' [0x      13]

Process FSP.apk (4871)
[Switching to Thread 5055]  Process FSP.apk (4871)

 

First chance exception at $BD9F069E. Exception class Segmentation fault (11). Process FSP.apk (4871)

 

BD9F069E F8525023         ldr.w r5, [r2, r3, lsl #2]
BD9F06A2 BF08             it eq
BD9F06A4 2608             moveq r6, #8
BD9F06A6 4281             cmp r1, r0
BD9F06A8 EA460605         orr.w r6, r6, r5
BD9F06AC F8426023         str.w r6, [r2, r3, lsl #2]
BD9F06B0 D1EE             bne.n 0xbd9f0690

 

call stack thread

--> :BD9F069E ??()
:BD9A21A6 ??()
:BD9A21A6 ??()

 

it doesn't tell me where the error is... but I suspect it to be in this procedure because it's in the middle of creating the ran*.txt files:

 

Global variables:

var
  Form1: TForm1;
  FileDirectory, RandomFileToCopy: String;
  FilePermissions, DeleteFiles, DeleteInProgress: boolean;
  DeleteDirectoryList: TArray<system.string>;
  MaxFreeSpace: Int64;
  debugLines: TStrings;
  dButtonPreviousIsPressed: boolean;
  breakit: boolean;
  copydataActive: boolean;

const
  FillerDiectoryNameConst = 'FILLER';

Procedure that I believe to be causing the segment fault:
 

procedure TForm1.CopyData();
var
  DriveStr : String;
  FileNameCounter : integer;
  FolderCounter : integer;
  FolderName : string;
  FolderArea : string;
  RandomFileName : String;
begin
  copydataActive := true;
  RandomFileToCopy := '';

  FileNameCounter := 0;
  FolderCounter := 0;

  DriveStr := FileDirectory + TPath.DirectorySeparatorChar;

  RandomFileToCopy := DriveStr + 'random.txt';

  // create random file
  //CreateNewRandFile(64000000); //64 mb file
  CreateNewRandFile(640); //640 file for testing purposes

  inc(FolderCounter);
  FolderName := 'rand' + IntToStr(FolderCounter);

  FolderArea := FileDirectory + TPath.DirectorySeparatorChar + FolderName;

  LabelLine2.Text := '';

  while DirectoryExists(FolderArea) = true do
  begin
    inc(FolderCounter);
    FolderName := 'rand' + IntToStr(FolderCounter);
    FolderArea := FileDirectory + TPath.DirectorySeparatorChar + FolderName;

    LabelLine1.Text := 'Folder: ' + FolderName;

    if breakit = true then exit;
  end;

  try
    TDirectory.CreateDirectory(FolderArea);
    dString('CreateDirectory:'+FolderArea);
  except
    on E : Exception do
      begin
        dString('CreateDirectory(FolderArea):'+E.ClassName+' error: '+E.Message);
        copydataActive := false;
        exit;
      end;
  end;

  while CheckDiskSize(FolderArea) > 0 do
  begin
    if breakit = true then exit;

    RandomFileName := FolderArea + 'ran' + IntToStr(FileNameCounter) + '.txt';

    FileNameCounter := 0;

    while FileNameCounter<126 do
    begin
      inc(FileNameCounter);

      RandomFileName := FolderArea + TPath.DirectorySeparatorChar + 'ran' + IntToStr(FileNameCounter) + '.txt';

      try
        //if FileExists(RandomFileName) = true then DeleteFile(RandomFileName);
        LabelLine1.Text := 'Creating: ran' + IntToStr(FileNameCounter) + '.txt';
        dString('Create RandomFile:'+RandomFileName);
        sleep(50); //dString writes to a file log file.
        TFile.Copy(RandomFileToCopy, RandomFileName, true);
      Except
        On E: Exception Do
        begin
          dString('TFile.Copy(RandomFileToCopy, RandomFileName):'+E.ClassName + ' ERROR: ' + E.Message);
          breakit := true; //break on error
        end;
      end;

      if breakit = true then exit;

    end;

    while DirectoryExists(FolderArea) = true do
    begin
      inc(FolderCounter);
      FolderName := 'rand' + IntToStr(FolderCounter);
      FolderArea := FileDirectory + TPath.DirectorySeparatorChar + FolderName;

      LabelLine1.Text := 'Folder: ' + FolderName;

      if breakit = true then exit;
    end;

    // all else fails... and it still is true... exit
    if DirectoryExists(FolderArea) = true then
    begin
      copydataActive := false;
      exit;
    end;

    try
      TDirectory.CreateDirectory(FolderArea);
      dString('CreateDirectory:'+FolderArea);
    except
      on E : Exception do
        begin
          dString('CreateDirectory(FolderArea):'+E.ClassName+' error: '+E.Message);
          copydataActive := false;
          exit;
        end;
    end;

  end;

  copydataActive := false;
end;

 

Edited by Al T

Share this post


Link to post

Solved the issue:

For some reason Delphi 11 and Android 9 & 12 do not like refreshing LabelLine1.Text ... it will cause a segment fault refreshing it.  I don't understand... but after commenting that line out just before the copying of a file makes it run perfectly!   Even though memo1.lines is in dString... the LabelLine1.Text was the issue!  This is the DEFAULT Label component that comes with Delphi 11 Enterprise!  I wonder if Skia Label will handle better?

 

      try
        //if FileExists(RandomFileName) = true then DeleteFile(RandomFileName);
------->LabelLine1.Text := 'Creating: ran' + IntToStr(FileNameCounter) + '.txt';
        dString('Create RandomFile:'+RandomFileName);
        sleep(50); //dString writes to a file log file.
        TFile.Copy(RandomFileToCopy, RandomFileName, true);
      Except
        On E: Exception Do
        begin
          dString('TFile.Copy(RandomFileToCopy, RandomFileName):'+E.ClassName + ' ERROR: ' + E.Message);
          breakit := true; //break on error
        end;
      end;

Share this post


Link to post

I'd expect that behaviour if CopyData was running in a separate thread. It would not normally be an issue, otherwise.

Share this post


Link to post

If you really need to run this in a thread, which I doubt, then you could syncronize the UI accesses, like this:

var
    LFileNamrCounterDisplay : Integer;

  ...

  LFileNamrCounterDisplay := FileNamrCounter;  // This is not really necessary, but additional safety measure to decouple variables

  TThread.ForceQueue(
      nil,
      procedure
      begin
          LabelLine1.Text := 'Creating: ran' + IntToStr( LFileNamrCounterDisplay ) + '.txt';
      end );

  ...

 

Edited by Rollo62

Share this post


Link to post
15 hours ago, Dave Nottage said:

I'd expect that behaviour if CopyData was running in a separate thread. It would not normally be an issue, otherwise.

CopyDate is called by a thread component (which is on a constant loop until the stop button is pressed or the program stops the thread):

 

procedure TForm1.IdThreadComponent1Run(Sender: TIdThreadComponent);
begin
  if ((OptionsUnit.OptionsForm.CleanUpBox.IsChecked = true)
  and (DeleteFiles = true) and (breakit=true)
  and (copydataActive = false)
  and (DeleteInProgress = false)) then
  begin
    AniIndicator1.Enabled := true;
    DeleteData();
  end;

  if ((copydataActive = false) and (breakit = false) and (DeleteFiles = false) and (DeleteInProgress = false)) then  //breakit = true don't create files
  begin
    AniIndicator1.Enabled := true;
    CopyData();
  end;

sleep(250);
end;

 

I think I understand... the label and copydata need to be in separate threads?

 

Edited by Al T

Share this post


Link to post
6 hours ago, Al T said:

I think I understand... the label and copydata need to be in separate threads?

More to it than that: Updating the label (or anything UI related) needs to happen in the main thread - see Rollo62's answer

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×