INTERNAL: How to avoid "Floating exception (core dumped)" error in external C code on ALPHA (OSF1, and LINUX)
Anonym
Topic:
Under ALPHA OSF1 and ALPHA LINUX, you may ancounter the above fatal error when calling external C code. This is caused by a divide by zero. Normally a divide by zero should give a valid result such as NaN or +/- Inf. However, on ALPHA hardware the result is a "core dumped" fatal error.Discussion:
When you compile external C code on ALPHA hardware the default is NOT to use IEEE floating point standard. The result is that a divide by zero results in a "core dumped" fatal error.
On ALPHA OSF1 you can avoid this by using the -ieee compiler flag to cc.
On ALPHA LINUX you can avoid this by using the -mieee compiler flag to gcc.
For example using the small dlm example code at the end:
IDL Version 5.4 (OSF alpha). (c) 2000, Research Systems, Inc.
Installation number: 99999-1.
Licensed for use by: RSI IDL floating licenses
IDL> make_dll,'idlcrash','IDL_Load',compile_dir='.'
IDL> print, idlcrash(0,0)
% Loaded DLM: CRASH.
Floating exception (core dumped)
borsholm@beta(52)%
However, if you use the -ieee flag, then you get the expected result:
IDL Version 5.4 (OSF alpha). (c) 2000, Research Systems, Inc.
Installation number: 99999-1.
Licensed for use by: RSI IDL floating licenses
IDL> make_dll,'idlcrash','IDL_Load',compile_dir='.', extra_cflags='-ieee'
IDL> print, idlcrash(0,0)
% Loaded DLM: CRASH.
-NaN
% Program caused arithmetic error: Floating illegal operand
IDL>
Under ALPHA LINUX use -mieee instead of -ieee.Solution:
borsholm@beta(48)% more idlcrash.dlm
MODULE CRASH
FUNCTION IDLCRASH 2 2
borsholm@beta(49)% more idlcrash.c
#include
#include "export.h"
/* Call with IDLCRASH(0.0,0.0) */
IDL_VPTR IDL_crash(int argc, IDL_VPTR argv[])
{
IDL_VPTR a,b,res;
a = IDL_CvtFlt(1,&argv[0]);
b = IDL_CvtFlt(1,&argv[1]);
res = IDL_Gettmp();
res->type = IDL_TYP_FLOAT;
res->value.f = a->value.f / b->value.f;
if (a!=argv[0]) IDL_DELTMP(a);
if (b!=argv[1]) IDL_DELTMP(b);
return res;
}
IDL_SYSFUN_DEF2 main_def[] = {
{(IDL_FUN_RET) IDL_crash,"IDLCRASH", 2, 2, 0, 0}};
int IDL_Load(void)
{
return IDL_SysRtnAdd(main_def,IDL_TRUE,1);
}