Recent

Author Topic: Range Check Error is raised on FindFirst ($FFFFFFFF)  (Read 2820 times)

Awesome Programmer

  • Sr. Member
  • ****
  • Posts: 451
  • Programming is FUN only when it works :)
    • Cool Technology
Range Check Error is raised on FindFirst ($FFFFFFFF)
« on: March 19, 2018, 09:52:49 pm »
I've been having issues debugging my program on Lazarus. Every time I try to debug my program files and I get External: SIGILL error and debugging stops with Assembly code being displayed right after. However, my program runs with no problem if I run the executable outside of Lazarus compiler. So, I enabled Range Check Error option under Debugging in the Project Option.

When I tried to debug, Lazarus immediately took me to Synaser file:

Code: Pascal  [Select][+][-]
  1.   procedure ScanForPorts( const ThisRootStr : string); // added by PDF
  2.   var theDevice : String;
  3.   var FD : Cint;
  4.   var Ser : TSerialStruct;
  5.   begin
  6.     if FindFirst( ThisRootStr, $FFFFFFFF, sr) = 0 then <<<<<<<<<<<<<<<<<<< Raised Range Check Error here.
  7.     begin
  8.       repeat
  9.         if (sr.Attr and $FFFFFFFF) = Sr.Attr then
  10.         begin

So, my question is this. Is this a real bug in Synaser? if so, how do you go about fixing it. I think, Lazarus is complaining about $FFFFFFFF.

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Range Check Error is raised on FindFirst ($FFFFFFFF)
« Reply #1 on: March 19, 2018, 10:07:59 pm »
Code: Pascal  [Select][+][-]
  1. Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TRawByteSearchRec) : Longint;
  2.  

Attr is declared as LongInt, so $FFFFFFFF will be out of range?

Bart

devEric69

  • Hero Member
  • *****
  • Posts: 648
Re: Range Check Error is raised on FindFirst ($FFFFFFFF)
« Reply #2 on: September 23, 2021, 04:44:17 pm »
So, the typecast of the const $FFFFFFFF, must be Longint($FFFFFFFF) i.e. always like this:

Code: Pascal  [Select][+][-]
  1. if FindFirst('/dev/ttyS*', Longint($FFFFFFFF), sr) = 0 then
  2.     repeat
  3.       if (sr.Attr and Longint($FFFFFFFF)) = Sr.Attr then
  4. ...\...

For information, I've just made a bug report about this range check error in synaser.pas, function GetSerialPortNames there (in Synapse 40.1.0.0).
« Last Edit: September 23, 2021, 04:47:32 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

Graham1

  • Jr. Member
  • **
  • Posts: 57
Re: Range Check Error is raised on FindFirst ($FFFFFFFF)
« Reply #3 on: September 26, 2021, 04:13:01 am »
Where does the $FFFFFFFF requirement come from anyway? In the FILUTILH.INC file the file attributes are listed as:

Code: Pascal  [Select][+][-]
  1. Const
  2.   { File attributes }
  3.   faReadOnly   = $00000001;
  4.   faHidden     = $00000002 platform;
  5.   faSysFile    = $00000004 platform;
  6.   faVolumeId   = $00000008 platform deprecated;
  7.   faDirectory  = $00000010;
  8.   faArchive    = $00000020;
  9.   faNormal     = $00000080;
  10.   faTemporary  = $00000100 platform;
  11.   faSymLink    = $00000400 platform;
  12.   faCompressed = $00000800 platform;
  13.   faEncrypted  = $00004000 platform;
  14.   faVirtual    = $00010000 platform;
  15.   faAnyFile    = $000001FF;

Even if you AND all of these to see every possible file type you don't get to $FFFFFFFF. I find these flags work fine in my version of the search for ports routine:

Code: Pascal  [Select][+][-]
  1. function GetSerialPortNames: string;
  2. var
  3.   ports : string;
  4.   flags : Longint;
  5.   rec   : TSearchRec;
  6.      
  7.    procedure ScanForPorts(const ThisRootStr:string; ValidateIO:boolean=false);
  8.    var
  9.       devnam : string;
  10.       FD     : cInt;
  11.       ser    : TSerialStruct;
  12.       usedev : boolean;
  13.    begin
  14.       if FindFirst(ThisRootStr, flags, rec) = 0 then begin
  15.          repeat
  16.             if (rec.Attr and flags) = rec.Attr then begin
  17.                devnam := '/dev/' + rec.Name;
  18.                FD := fpopen(devnam, O_RdWr or O_NonBlock or O_NoCtty);
  19.                if FD > 0 then begin
  20.                   if not ValidateIO then
  21.                      usedev:=true
  22.                   else begin
  23.                      usedev:=false;
  24.                      if fpioctl(FD, TIOCGSERIAL, @ser) <> -1 then
  25.                         if ser.typ <> 0  then
  26.                            usedev:=true;
  27.                   end;
  28.                   if usedev then begin
  29.                      if ports <> '' then
  30.                         ports := ports + ',' + rec.Name
  31.                      else
  32.                         ports := rec.Name;
  33.                   end;
  34.                   fpclose(FD);
  35.                end;
  36.             end;
  37.          until FindNext(rec) <> 0;
  38.       end;
  39.    end;
  40.      
  41. begin
  42.    ports := '';
  43.    flags := faAnyFile AND (NOT faDirectory);
  44.    try
  45.       ScanForPorts('/dev/ttyS*',true);
  46.       ScanForPorts('/dev/rfcomm*');
  47.       ScanForPorts('/dev/ttyUSB*');
  48.       ScanForPorts('/dev/ttyACM*');
  49.       FindClose(rec);
  50.    finally
  51.       result := ports;
  52.    end;
  53. end;

where:

Code: Pascal  [Select][+][-]
  1. uses   termio, baseunix, classes, sysutils;
  2.  
  3. type   TSerialStruct = packed record
  4.          typ             : Integer;
  5.          line            : Integer;
  6.          port            : Cardinal;
  7.          irq             : Integer;
  8.          flags           : Integer;
  9.          xmit_fifo_size  : Integer;
  10.          custom_divisor  : Integer;
  11.          baud_base       : Integer;
  12.          close_delay     : Word;
  13.          io_type         : Char;
  14.          reserved_char   : Char;
  15.          hub6            : Integer;
  16.          closing_wait    : Word; // time to wait before closing
  17.          closing_wait2   : Word; // no longer used...
  18.          iomem_base      : ^Char;
  19.          iomem_reg_shift : Word;
  20.          port_high       : Cardinal;
  21.          iomap_base      : LongWord; // cookie passed into ioremap
  22.        end;
Windows 10/11 Home 64-bit (and Linux because I have to)
Lazarus 2.0.12 / FPC 3.2.0 (because libQt5pas 1.2.6)
Linux Mint 20 (because GLIBC_2.31)

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: Range Check Error is raised on FindFirst ($FFFFFFFF)
« Reply #4 on: November 10, 2022, 07:17:21 am »
Hello,
So, the typecast of the const $FFFFFFFF, must be Longint($FFFFFFFF) i.e. always like this:

Code: Pascal  [Select][+][-]
  1. if FindFirst('/dev/ttyS*', Longint($FFFFFFFF), sr) = 0 then
  2.     repeat
  3.       if (sr.Attr and Longint($FFFFFFFF)) = Sr.Attr then
  4. ...\...

For information, I've just made a bug report about this range check error in synaser.pas, function GetSerialPortNames there (in Synapse 40.1.0.0).

and why not using -1  ? :
Code: Pascal  [Select][+][-]
  1. if FindFirst('/dev/ttyS*', -1, sr) = 0 then
  2.     repeat
  3.       if (sr.Attr and  -1) = Sr.Attr then
  4. ...\...

but the Graham1's code seems more logical. I have tried his code in the lazsynaser.pas file of the Lazserial package. OK on Ubuntu 20.04 Lazarus 2.2 with two USB serial ports.

Friendly, J.P
« Last Edit: November 10, 2022, 08:07:21 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

jamie

  • Hero Member
  • *****
  • Posts: 6077
Re: Range Check Error is raised on FindFirst ($FFFFFFFF)
« Reply #5 on: November 11, 2022, 12:16:16 am »
Hello,
So, the typecast of the const $FFFFFFFF, must be Longint($FFFFFFFF) i.e. always like this:

Code: Pascal  [Select][+][-]
  1. if FindFirst('/dev/ttyS*', Longint($FFFFFFFF), sr) = 0 then
  2.     repeat
  3.       if (sr.Attr and Longint($FFFFFFFF)) = Sr.Attr then
  4. ...\...

For information, I've just made a bug report about this range check error in synaser.pas, function GetSerialPortNames there (in Synapse 40.1.0.0).

and why not using -1  ? :
Code: Pascal  [Select][+][-]
  1. if FindFirst('/dev/ttyS*', -1, sr) = 0 then
  2.     repeat
  3.       if (sr.Attr and  -1) = Sr.Attr then
  4. ...\...

but the Graham1's code seems more logical. I have tried his code in the lazsynaser.pas file of the Lazserial package. OK on Ubuntu 20.04 Lazarus 2.2 with two USB serial ports.

Friendly, J.P

Good One J.P.

 I was reading this, and I said come on, I want to answer this one, but J.P. beat me to it! :o

The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018