Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Floating-point exception trapping not working #3657

Closed
letmaik opened this issue Nov 11, 2018 · 3 comments
Closed

Floating-point exception trapping not working #3657

letmaik opened this issue Nov 11, 2018 · 3 comments
Labels

Comments

@letmaik
Copy link
Member

letmaik commented Nov 11, 2018

Please fill out the below information:

  • Your Windows build number: 10.0.17134.345

  • What you're doing and what's happening:

The following code has floating-point exception trapping enabled for divide-by-zero, however in WSL it does not raise a SIGFPE. It still exits with a non-zero exit code though.

#define _GNU_SOURCE
#include <fenv.h>

int main (void) {
  feenableexcept(FE_DIVBYZERO);
  double b = 1.0;
  double c = 0.0;
  double d = b/c;
  return 0;
}

WSL output:

$ gcc-8 --version
gcc-8 (Ubuntu 8.2.0-1ubuntu2~18.04) 8.2.0
$ gcc-8 -g test.c -lm
$ ./a.out 
$ echo $?
142
  • What's wrong / what should be happening instead:

The code should raise a SIGFPE and print "Floating point exception (core dumped)". This works on native Linux:

Ubuntu VM output:

$ gcc-8 --version
gcc-8 (Ubuntu 8.2.0-1ubuntu2~18.04) 8.2.0
$ gcc-8 -g test.c -lm
$ ./a.out 
Floating point exception (core dumped)
$ echo $?
136

Note also the different exit code compared to WSL.

@therealkenc
Copy link
Collaborator

therealkenc commented Nov 11, 2018

This is (non-intuitively) the same as #1262. Easier repro is:

int main() { *(int*)0; return 0; }

...which also exits silently.

Your code raises a different signal (SIGFPE instead of SIGSEGV), but ends up in a default handler that is unhappy for the same reasons. If you are handy with an assembler you can get it to do the same with SIGILL. If you have a motivational use case for divide-by-zero with the default handler it would be worth adding a comment over in #1262. Also nod to tangentially related #2555 which I'd sure like to see addressed.

[late edit for pedantry]

however in WSL it does not raise a SIGFPE

Nah it's raised alright. It just isn't handled the way you'd expect.

@therealkenc
Copy link
Collaborator

therealkenc commented Nov 11, 2018

Nah it's raised alright. It just isn't handled the way you'd expect.

Dove a bit because curious. This is novel enough to have its own home, so retracting the premature dupe. In the OP test case an exception is raised aight. The code doesn't make it to return 0. And the default handler still isn't going to get you a core per #1262. But regardless, it doesn't appear FE_DIVBYZERO is being respected with the correct semantics. Below is a merge with #2555. On Real Linux you'll get SIGFPE fpregs 0x7ffceef0b540 (with some address). On WSL silence, but nevertheless return 0 is not reached.

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/ucontext.h>
#include <signal.h>
#include <fenv.h>
#include <errno.h>

static void segv(int sig, siginfo_t *info, void *context)
{
	ucontext_t *c = context;
	mcontext_t m = c->uc_mcontext;
	void *fault_addr = (void *)m.gregs[REG_CR2];
	printf("SIGSEGV at 0x%lx\n", (unsigned long)fault_addr);
	exit(1);
}

static void fpe(int sig, siginfo_t *info, void *context)
{
	ucontext_t *c = context;
	mcontext_t m = c->uc_mcontext;
	fpregset_t fpregs = m.fpregs;
	printf("SIGFPE fpregs 0x%lx\n", (unsigned long)fpregs);
	exit(1);
}

static void install_handlers(void)
{
	struct sigaction sa;
	sa.sa_sigaction = segv;
	sa.sa_flags = SA_SIGINFO;
	sigaction(SIGSEGV, &sa, NULL);
	sa.sa_sigaction = fpe;
	sa.sa_flags = SA_SIGINFO;
	sigaction(SIGFPE, &sa, NULL);
}

int main(int argc, const char *argv[])
{
	feenableexcept(FE_DIVBYZERO);
	install_handlers();
	//*(int*)0;
	printf("result: %f\n", 1.0/0.0);
	return 0;
}

Copy link
Contributor

This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants