Monday, September 21, 2009

Run-time errors in Free Pascal: Too Many Open FIles

Error ini membuat aku pusing tujuh keliling. Program yang aku buat adalah sebuah program SMS Gateway dengan basic Socket Programming yang menggunakan Free Pascal 2.2.2 dengan target operating system Linux i386 Fedora 10. Function yang menghasilkan error "Too Many Open Files" ini adalah sebagi berikut :

function RunCMD(Script: string; var RetMsg: TStringList): boolean;
var
M: TMemoryStream;
P: TProcess;
n: LongInt;
BytesRead: LongInt;

begin
Result := False;
try
// We cannot use poWaitOnExit here since we don't
// know the size of the output. On Linux the size of the
// output pipe is 2 kB. If the output data is more, we
// need to read the data. This isn't possible since we are
// waiting. So we get a deadlock here.
//
// A temp Memorystream is used to buffer the output

M := TMemoryStream.Create;
BytesRead := 0;

P := TProcess.Create(nil);
P.CommandLine := Script;
P.Options := [poUsePipes];

P.Execute;
while P.Running do
begin
// make sure we have room
M.SetSize(BytesRead + CMD_BUFFER_SIZE);

// try reading it
n := P.Output.Read((M.Memory + BytesRead)^, CMD_BUFFER_SIZE);
if n > 0 then
inc(BytesRead, n)
else
Sleep(GetDelay); //no data, wait a few delay
end;

// read last part
repeat
// make sure we have room
M.SetSize(BytesRead + CMD_BUFFER_SIZE);
// try reading it
n := P.Output.Read((M.Memory + BytesRead)^, CMD_BUFFER_SIZE);
if n > 0 then
inc(BytesRead, n);
until n <= 0;

//if BytesRead > 0 then writeLn;

M.SetSize(BytesRead);
RetMsg.LoadFromStream(M);
Result := True;

except on E:Exception do
RetMsg.Append('RunCMD->'+E.Message);
end;

P.Free;
M.Free;
end;


Setelah aku gogling akhirnya aku dapatkan penjelasan dari error ini yaitu seperti di bawah ini.

Run-time errors

Applications generated by Free Pascal might generate run-time errors when certain abnormal conditions are detected in the application. This appendix lists the possible run-time errors and gives information on why they might be produced.

1 Invalid function number
An invalid operating system call was attempted.
2 File not found
Reported when trying to erase, rename or open a non-existent file.
3 Path not found
Reported by the directory handling routines when a path does not exist or is invalid. Also reported when trying to access a non-existent file.
4 Too many open files
The maximum number of files currently opened by your process has been reached. Certain operating systems limit the number of files which can be opened concurrently, and this error can occur when this limit has been reached.
5 File access denied
Permission to access the file is denied. This error might be caused by one of several reasons:
  • Trying to open for writing a file which is read-only, or which is actually a directory.
  • File is currently locked or used by another process.
  • Trying to create a new file, or directory while a file or directory of the same name already exists.
  • Trying to read from a file which was opened in write-only mode.
  • Trying to write from a file which was opened in read-only mode.
  • Trying to remove a directory or file while it is not possible.
  • No permission to access the file or directory.
6 Invalid file handle
If this happens, the file variable you are using is trashed; it indicates that your memory is corrupted.
12 Invalid file access code
Reported when a reset or rewrite is called with an invalid FileMode value.
15 Invalid drive number
The number given to the Getdir or ChDir function specifies a non-existent disk.
16 Cannot remove current directory
Reported when trying to remove the currently active directory.
17 Cannot rename across drives
You cannot rename a file such that it would end up on another disk or partition.
100 Disk read error
An error occurred when reading from disk. Typically happens when you try to read past the end of a file.
101 Disk write error
Reported when the disk is full, and you're trying to write to it.
102 File not assigned
This is reported by Reset, Rewrite, Append, Rename and Erase, if you call them with an unassigned file as a parameter.
103 File not open
Reported by the following functions : Close, Read, Write, Seek, EOf, FilePos, FileSize, Flush, BlockRead, and BlockWrite if the file is not open.
104 File not open for input
Reported by Read, BlockRead, Eof, Eoln, SeekEof or SeekEoln if the file is not opened with Reset.
105 File not open for output
Reported by write if a text file isn't opened with Rewrite.
106 Invalid numeric format
Reported when a non-numeric value is read from a text file, and a numeric value was expected.
150 Disk is write-protected
(Critical error)
151 Bad drive request struct length
(Critical error)
152 Drive not ready
(Critical error)
154 CRC error in data
(Critical error)
156 Disk seek error
(Critical error)
157 Unknown media type
(Critical error)
158 Sector Not Found
(Critical error)
159 Printer out of paper
(Critical error)
160 Device write fault
(Critical error)
161 Device read fault
(Critical error)
162 Hardware failure
(Critical error)
200 Division by zero
The application attempted to divide a number by zero.
201 Range check error
If you compiled your program with range checking on, then you can get this error in the following cases:
  1. An array was accessed with an index outside its declared range.
  2. Trying to assign a value to a variable outside its range (for instance an enumerated type).
202 Stack overflow error
The stack has grown beyond its maximum size (in which case the size of local variables should be reduced to avoid this error), or the stack has become corrupt. This error is only reported when stack checking is enabled.
203 Heap overflow error
The heap has grown beyond its boundaries. This is caused when trying to allocate memory explicitly with New, GetMem or ReallocMem, or when a class or object instance is created and no memory is left. Please note that, by default, Free Pascal provides a growing heap, i.e. the heap will try to allocate more memory if needed. However, if the heap has reached the maximum size allowed by the operating system or hardware, then you will get this error.
204 Invalid pointer operation
You will get this if you call Dispose or Freemem with an invalid pointer (notably, Nil).
205 Floating point overflow
You are trying to use or produce real numbers that are too large.
206 Floating point underflow
You are trying to use or produce real numbers that are too small.
207 Invalid floating point operation
Can occur if you try to calculate the square root or logarithm of a negative number.
210 Object not initialized
When compiled with range checking on, a program will report this error if you call a virtual method without having called its object's constructor.
211 Call to abstract method
Your program tried to execute an abstract virtual method. Abstract methods should be overridden, and the overriding method should be called.
212 Stream registration error
This occurs when an invalid type is registered in the objects unit.
213 Collection index out of range
You are trying to access a collection item with an invalid index (objects unit).
214 Collection overflow error
The collection has reached its maximal size, and you are trying to add another element (objects unit).
215 Arithmetic overflow error
This error is reported when the result of an arithmetic operation is outside of its supported range. Contrary to Turbo Pascal, this error is only reported for 32-bit or 64-bit arithmetic overflows. This is due to the fact that everything is converted to 32-bit or 64-bit before doing the actual arithmetic operation.
216 General Protection fault
The application tried to access invalid memory space. This can be caused by several problems:
  1. Dereferencing a nil pointer.
  2. Trying to access memory which is out of bounds (for example, calling move with an invalid length).
217 Unhandled exception occurred
An exception occurred, and there was no exception handler present. The sysutils unit installs a default exception handler which catches all exceptions and exits gracefully.
219 Invalid typecast

Thrown when an invalid typecast is attempted on a class using the as operator. This error is also thrown when an object or class is typecast to an invalid class or object and a virtual method of that class or object is called. This last error is only detected if the -CR compiler option is used.

222 Variant dispatch error
No dispatch method to call from variant.
223 Variant array create
The variant array creation failed. Usually when there is not enough memory.
224 Variant is not an array
This error occurs when a variant array operation is attempted on a variant which is not an array.
225 Var Array Bounds check error
This error occurs when a variant array index is out of bounds.
227 Assertion failed error
An assertion failed, and no AssertErrorProc procedural variable was installed.
229 Safecall error check
This error occurs is a safecall check fails, and no handler routine is available.
231 Exception stack corrupted
This error occurs when the exception object is retrieved and none is available.
232 Threads not supported
Thread management relies on a separate driver on some operating systems (notably, Unixes). The unit with this driver needs to be specified on the uses clause of the program, preferably as the first unit (cthreads on unix)
Solusi yang sudah pernah aku tempuh adalah seperti di bawah ini:
1. Dengan menggunakan user aplikasi ybs, naikkan open files dengan
perintah sbb:
ulimit -n 1024

2. Tambahkan perintah sbb (bisa juga ditambahkan dibaris terakhir pada
file /etc/rc.d/rc.local):
  echo 8192 > /proc/sys/fs/file-max
echo 32768 > /proc/sys/fs/inode-max

Nilai inode-max didapat minimal 4x dari nila file-max

3.Edit file /etc/security/limits.conf, tambahkan sesuai format
dan aturan yang ada dalam penjelasan di dalam file tsb.

TAMBAHAN

There are multiple places where Linux can have limits on the number of file descriptors you are allowed to open.

You can check the following:

cat /proc/sys/fs/file-max

That will give you the system wide limits of file descriptors.

On the shell level, this will tell you your personal limit:

ulimit -n

This can be changed in /etc/security/limits.conf - it's the nofile param.

However, if you're closing your sockets correctly, you shouldn't receive this unless you're opening a lot of simulataneous connections. It sounds like something is preventing your sockets from being closed appropriately. I would verify that they are being handled properly

When system performance on Linux is affected by using too many file descriptors, usually an error can be seen in the log file '(Too many open files)'. Although this affects the entire system, it is a fairly common problem.

Confluence 2.3 was released and the issue with using too many file handles was resolved via utilisation of compound indexing.

To obtain the current maximum number of file descriptors, use 'cat /proc/sys/fs/file-max'. For comparison, an out-the-box ubuntu system has file-max set to 205290.

Increase Total File Descriptors For System

To prevent Confluence from running out of filehandles you need to make sure that there are enough file handles available at the system level, and that the user you are running Confluence as is allowed to use enough file handles:

Run the command sysctl -a. If this is less than 200000, increase the number of file handles by editing /etc/sysctl.conf and changing the property fs.file-max to 200000. If there isn't a value set already for this property, you need to add the line fs.file-max=200000.

Then run sysctl -p to apply your changes to your system.

Increase Total File Descriptors For User

Linux also limits the number of files that can be open per login shell. To change this limit for the user that runs the Confluence service you will need to adjust the user limit configuration.

For PAM enabled systems

For Linux systems running PAM you will need to adjust /etc/security/limits.conf

The format of this file is .

For example to set the limit for the user confservice the following line would be used:

1.confservice hard nofile 5000

Other systems

For other Linux systems the file responsible for setting limits is /etc/limits

To replicate the setting given in the previous example the line would be:

1.confservice N 5000

To Count Total File Descriptors Used By Confluence

To get the total number of handles that are used by Confluence:

  1. Locate the Confluence ProcId by identifying the Java process with{{'ps axwwwu | grep java'}}
  2. Either run ls -la /proc//fd, or use the lsof (LiSt Open Files) command lsof -p . For a Confluence ProcID of 460, use:
    1.$ lsof -p 460 | wc -l

When getting support for this error

If you are encountering the Too many open files error within Confluence and this advice does not help, please accompany any support request with the output of lsof -p , taken at the time of the error, so that the support engineer can determine precisely which file descriptors are being held open.


Mudah-mudahan solusi ini bisa membantu.
Thanks and Wassalam


Lebih Bersih, Lebih Baik, Lebih Cepat - Rasakan Yahoo! Mail baru yang Lebih Cepat hari ini!

0 Comments: