Manage stack usage
To avoid stack overflow, follow these design restrictions in your
UDR:
- Do not use large automatic arrays.
- Avoid excessively deep calling sequences.
- Use mi_call() within a UDR to manage recursive calls.
By default, when a thread of a virtual processor executes a UDR,
the database server uses a thread-stack size that the STACKSIZE configuration
parameter specifies (32 KB, if STACKSIZE is not set). To determine
how much stack space a UDR requires, monitor the UDR from the system
prompt with the following onstat command:
onstat -g sts
The -g sts option prints the maximum and current stack usage per thread. For more information about the onstat utility and its -g sts option, see the HCL Informix® Administrator's Reference.
You must ensure that your UDR has sufficient stack space for its
execution. That is, the UDR must have enough stack space to hold all
local variables of the routine. If you see errors in the message log
file of the following format when you try to allocate a large block
of memory, your stack space is being overrun:
Assert Failed: Condition Failed (Bad pool pointer 0xe2fe018),
in (mt_shm_free)
Assert Failed: Memory block header corruption detected in mt_shm_free
To determine if there is enough stack space for your UDR, use the mi_stack_limit() function. This function checks if the space available on the stack exceeds the sum of the stack margin and the specified stack size.
To override the stack size for a particular UDR, use the STACK
routine modifier of the CREATE FUNCTION or CREATE PROCEDURE statement
when you register your UDR. For example, the following CREATE FUNCTION
statement specifies a stack size of 64 kilobytes for the func1() UDR:
CREATE FUNCTION func1(INTEGER)
RETURNS INTEGER
WITH (STACK=65536)
EXTERNAL NAME '/usr/srv_routs/funcs.so'
LANGUAGE C;
When the UDR completes, the database server allocates thread stacks for subsequent UDRs based on the STACKSIZE parameter (unless these subsequent UDRs have also specified the STACK routine modifier).