X
29 Rate this article:
No rating

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);
}