Al T 12 Posted August 16, 2022 (edited) [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 August 16, 2022 by Al T Share this post Link to post
Al T 12 Posted August 16, 2022 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
Dave Nottage 557 Posted August 16, 2022 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
Rollo62 536 Posted August 17, 2022 (edited) 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 August 17, 2022 by Rollo62 Share this post Link to post
Al T 12 Posted August 17, 2022 (edited) 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 August 17, 2022 by Al T Share this post Link to post
Dave Nottage 557 Posted August 17, 2022 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