Question

I can't seem to produce a core dump file from an intentionally added arithmetic error in my code, that is:

float x;

x = 0.0/0.0;

It seems to work when I created a small experimental program to test the floating point exception, but when I implemented it in the real application, it fails to produce the core dump.

Basicly, I am trying to produce a debuggable release version where I link in another file (debuggable.c) containing a function that uses GCC's constructor attribute to call feenableexcept which enables the fpe exceptions at pre-main initialisation.

debuggable.c:

void main_init(void) __attribute__((constructor));

void main_init(void)
{
    printf("Enabling arithmetic exceptions\n");
    feenableexcept(fegetexcept()|FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
};

Then in the real application code, I added in the intentional arithmetic error to force a core dump but it does not seem to work. I have verified that feenableexcept is indeed being called and that it returns 0 to indicate success based on printf statements I added in. Furthermore, a core dump is produced if I use the abort() function.

It seems that I have configured Linux correctly to produce core dump files, but there is something about the way the application is written or ran that is not producing the core dumps.

I was wondering if I may get suggestions at what to check to fix this problem.

This is the version of Red Hat Linux I am using:

Red Hat Enterprise Linux Client release 5.4 (Tikanga)
5.4 RedHawk Linux (Lima)

Here is my GCC version:

gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
Copyright (C) 2006 Free Software Foundation, Inc.

Yes, I know its old but I am working with a legacy system.

Update 1

It seems that when I place the intentional arithmetic error in the main() function of the real app, it actually bombs and produces the core dump. It is not doing this in a callee function of the main() function unless you put the call to feenableexcept() in the callee function itself.

The constructor attribute technique seems to work without the need to make a call to feenableexcept() in the callee function when I tested it out in a simple application. I'm wondering what could cause it to do this in the real application?

Update 2

I called fegetexcept() in my real application at several places and found out it returns 0 immediately after the call to setjmp(). It seems that setjmp() is part of the C standard library and is used with longjmp() to perform "non-local jumps".

I'm not sure why it is resetting the exception flags to zero though. I initially thought that I should be using sigsetjmp()/siglongjmp() to preserve the signals and have adapted the application to do so but it did not helped either. Furthermore, I tested this out in my little proof-of-concept app and it did not reset the exception flags to zero after the call to setjmp()/sigsetjmp(). I'm stumped at why setjmp() is doing this.

Was it helpful?

Solution 2

I can't seem to find the information to indicate why the exception flags are being reset to zero when setjmp() and longjmp() are called. It does not do this in my little proof-of-concept program.

A work around that I came up with was to use feholdexcept() to store the flags before the setjmp() call, and then call fesetenv() afterwards to restore the flags. This allowed the program to throw the exception and produce the core dumps as normal. I'm still curious as to why setjmp()/longjmp() is resetting the exception flags. If anyone knows please post the answer.

OTHER TIPS

I did not test it, but I would assume this most likely doesn't work since gcc realizes your calculation is a constant expression at compile time and just assigns NaN to x which won't trigger an exception.

In other (IEEE) words: the constant is a quiet NaN as opposed to a signaling NaN

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top