Next: Notes, Previous: Logging and Debugging, Up: Tutorial [Contents][Index]
A runtime error is a special condition encountered during
execution of the filter program, that makes further execution of
the program impossible. There are two kinds of runtime errors: fatal
errors, and uncaught exceptions. Whenever a runtime error occurs,
mailfromd
writes into the log file the following message:
RUNTIME ERROR near file:line: text
where file:line indicates approximate source file location where the error occurred and text gives the textual description of the error.
Fatal runtime errors are caused by a condition that is impossible to fix at run time. For version 9.0 these are:
There is not enough memory for the execution of the program. Try to
make more memory available for mailfromd
or to reduce
its memory requirements by rewriting your filter script.
These errors are reported when there is not enough space left on
stack to perform the requested operation, and the attempt to resize the stack
has failed. Usually mailfromd
expands the stack when the need
arises (see automatic stack resizing). This runtime error
indicates that there were no more memory available for stack
expansion. Try to make more memory available for mailfromd
or to reduce its memory requirements by rewriting your filter script.
Program attempted to pop a value off the stack but the stack was
already empty. This indicates an internal error in the
MFL compiler or mailfromd
runtime engine. If you
ever encounter this error,
please report it to bug-mailfromd@gnu.org.ua. Include
the log fragment (about 10-15 lines before and after this log message)
and your filter script. See Reporting Bugs, for more
information about bug reporting.
The program counter is out of allowed range. This is a severe
error, indicating an internal inconsistency in mailfromd
runtime engine. If you encounter it, please report it to
bug-mailfromd@gnu.org.ua. Include the log fragment (about
10-15 lines before and after this log message) and your filter script.
See Reporting Bugs, for more information about how to report a
bug.
These indicate a programmatic error in your filter script, which the MFL compiler was unable to discover at compilation stage:
The throw
statement used a not existent exception number n.
Fix the statement and restart mailfromd
. See throw, for
the information about throw
statement and see Exceptions,
for the list of available exception codes.
You have used a back-reference (see Back references), where there is no previous regular expression to refer to. Fix this line in your code and restart the program.
You have used a back-reference (see Back references), with a number greater than the number of available groups in the previous regular expression. For example:
if $f matches "(.*)@gnu.org"
# Wrong: there is only one group in the regexp above!
set x \2
…
Fix your code and restart the daemon.
Another kind of runtime errors are uncaught exceptions, i.e. exceptional conditions for which no handler was installed (See Exceptions, for information on exceptions and on how to handle them). These errors mean that the programmer (i.e. you), made no provision for some specific condition. For example, consider the following code:
prog envfrom do if $f mx matches "yahoo.com" foo() fi done
It is syntactically correct, but it overlooks the fact that mx
matches
may generate e_temp_failure
exception, if the underlying
DNS query has timed out (see Special comparisons). If
this happens, mailfromd
has no instructions on what to do
next and reports an error. This can easily be fixed using a
try
/catch
(see Catch and Throw) statement, e.g.:
prog envfrom do try do if $f mx matches "yahoo.com" foo() fi done # Catch DNS errors catch e_temp_failure or e_failure do tempfail 451 4.1.1 "MX verification failed" done done
Another common case are undefined Sendmail macros. In this case the
e_macroundef
exception is generated:
RUNTIME ERROR near foo.c:34: Macro not defined: {client_adr}
These can be caused either by misspelling the macro name (as in the example message above) or by failing to export the required name in Sendmail milter configuration (see exporting macros). This error should be fixed either in your source code or in sendmail.cf file, but if you wish to provide a special handling for it, you can use the following catch statement:
catch e_macroundef do … done
Sometimes the location indicated with the runtime error message is
not enough to trace the origin of the error. For example, an error
can be generated explicitly with throw
statement
(see throw):
RUNTIME ERROR near match_cidr.mfl:30: invalid CIDR (text)
If you look in module match_cidr.mfl, you will see the following code (line numbers added for reference):
23 func match_cidr(string ipstr, string cidr) 24 returns number 25 do 26 number netmask 27 28 if cidr matches '^(([0-9]{1,3}\.){3}[0-9]{1,3})/([0-9][0-9]?)' 29 return inet_aton(ipstr) & len_to_netmask(\3) = inet_aton(\1) 30 else 31 throw invcidr "invalid CIDR (%cidr)" 32 fi 33 return 0 34 done
Now, it is obvious that the value of cidr
argument to
match_cidr
was wrong, but how to find the caller that passed
the wrong value to it? The special command line option
--stack-trace is provided for this. This option enables
dumping stack traces when a fatal error occurs. Traces
contain information about function calls. Continuing our example,
using the --stack-trace option you will see the following diagnostics:
RUNTIME ERROR near match_cidr.mfl:30: invalid CIDR (127%) mailfromd: Stack trace: mailfromd: 0077: match_cidr.mfl:31: match_cidr mailfromd: 0096: test.mfl:13: bar mailfromd: 0110: mailfromd.mfl:18: foo mailfromd: Stack trace finishes mailfromd: Execution of the configuration program was not finished
Each trace line describes one stack frame. The lines appear in the order of most recently called to least recently called. Each frame consists of:
Thus, the example above can be read as: “the function
match_cidr
was called by the function bar
in file
test.mfl at line 13. This function was called from
the function bar
, in file test.mfl at line 13. In its turn,
bar
was called by the function foo
, in file
mailfromd.mfl at line 18”.
Examining caller functions will help you localize the source of the error and fix it.
You can also request a stack trace any place in your code, by
calling the stack_trace
function. This can be useful for
debugging.
Next: Notes, Previous: Logging and Debugging, Up: Tutorial [Contents][Index]