<div dir="ltr"><div>I am debugging an issue with FPC 3.0 on Linux x86_64 which I believe I have tracked down to Fpopendir rtl/linux/ossysc.inc:</div><div><br></div><div>-----------------------------------------------------------</div><div>function Fpopendir(dirname : pchar): pdir;  [public, alias : 'FPC_SYSC_OPENDIR'];</div><div><br></div><div>var</div><div>  fd:integer;</div><div>  st:stat;</div><div>  ptr:pdir;</div><div><br></div><div>begin</div><div>  Fpopendir:=nil;</div><div>  if Fpstat(dirname,st)<0 then</div><div>   exit;</div><div>{ Is it a dir ? }</div><div>  if not((st.st_mode and $f000)=$4000)then</div><div>   begin</div><div>     errno:=ESysENOTDIR;</div><div>     exit</div><div>   end;</div><div>{ Open it}</div><div>  fd:=Fpopen(dirname,O_RDONLY,438);</div><div>  if fd<0 then</div><div>   exit;</div><div>  new(ptr);</div><div>  if ptr=nil then</div><div>   exit;</div><div>  new(ptr^.dd_buf);</div><div>  if ptr^.dd_buf=nil then</div><div>   exit;</div><div>  ptr^.dd_fd:=fd;</div><div>  ptr^.dd_loc:=0;</div><div>  ptr^.dd_size:=0;</div><div>  ptr^.dd_nextoff:=0;</div><div>  ptr^.dd_max:=sizeof(ptr^.dd_buf^);</div><div>  Fpopendir:=ptr;</div><div>end;</div><div>-----------------------------------------------------------</div><div><br></div><div>In this process I have a LOT of open file handles. The system on which it runs uses "ulimit -n 64000" to set the maximum number of open descriptors to 64,000. However, once I get above 32768 file handles Fpopendir starts failing, and causing me to leak directory descriptors. I didn't have debug compiled down into the RTL, but looking at the machine code I can see what's happening:</div><div><br></div><div>Fpopen is returning a good directory descriptor, for example, 51345. However, the comparison "fd<0" is evaluating to true, which causes the routine to error out.</div><div><br></div><div>Looking at the machine code:</div><div><br></div><div>   0x00007ffff7038106 <+118>:   callq  0x7ffff7037ee0 <SYSTEM_$$_FPOPEN$PCHAR$LONGINT$LONGINT$$LONGINT></div><div>   0x00007ffff703810b <+123>:   mov    %eax,%ebx</div><div>   0x00007ffff703810d <+125>:   cmp    $0x0,%bx</div><div>   0x00007ffff7038112 <+130>:   jl     0x7ffff703816b <SYSTEM_$$_FPOPENDIR$PCHAR$$PDIR+219></div><div><br></div><div>At +123 I can see that $eax/$ebx contains the correct descriptor, 51345. However, when I print $bx in the debugger, it looks like a negative number, as if it had overflowed a signed 2-byte integer, so the function errors out. This causes the file descriptor to be leaked as well, since no reference to is is retained in the pdir record.</div><div><br></div><div>I'm a little bit confused at this, as fd is defined as an "integer," which I thought was going to always be a 32-bit signed value on this system. However, the FPC documentation tells me that this can be changed based on compiler switches, so maybe somewhere up in one of the other .inc files there is some flag making "integer" behave as a signed 16-byte number?</div><div><br></div><div>I am inclined just to patch my copy of the FPC rtl and change the definition of fd from "integer" to "longint," but I wanted to get your take on it first.</div><div><br></div><div>Thanks,</div><div><br></div><div>SG</div><div><br></div><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr">--<br>Seth Grover<br><br>
Be kind to all of your neighbors<br>
Because they're just like you.<br>
And you're nothing special<br>
Unless they are too.<br></div></div></div></div></div>
</div>