Skip to content

signal SIGFPE during garbage collecting  #76257

Closed

Description

@grospelliergilles

Description

I have an application which use coreclr embedded in a C++ program.
In this application, I need to activate floating point exception to detected invalid mathematical operations (for example calling log with a negative argument). I use the C feenableexcept function to enable exceptions:

#include <fenv.h>
feenableexcept(FE_DIVBYZERO|FE_INVALID)

After calling this method, I receive a SIGFPE when executing C# code when the garbage collector is running.

Reproduction Steps

I can not provide a small case to reproduce the problem because my project is too big.

Expected behavior

Not throwing signal SIGFPE

Actual behavior

The application sends a SIGFPE signal.
The debugger give me the following stack trace:

WKS::gc_heap::dt_high_frag_p(WKS::gc_tuning_point, int, int) at /__w/1/s/src/coreclr/gc/gc.cpp:3174:101
WKS::gc_heap::generation_to_condemn(int, int*, int*, int) at /__w/1/s/src/coreclr/gc/gc.cpp:0:13
WKS::gc_heap::garbage_collect(int) at /__w/1/s/src/coreclr/gc/gc.cpp:22458:39
WKS::GCHeap::GarbageCollectGeneration(unsigned int, gc_reason) at /__w/1/s/src/coreclr/gc/gc.cpp:46902:13
WKS::GCHeap::GarbageCollect(int, bool, int) at /__w/1/s/src/coreclr/gc/gc.cpp:46080:52
Volatile<unsigned int>::LoadWithoutBarrier() const at /__w/1/s/src/coreclr/inc/volatile.h:383:31
  (inlined by) Thread::PreemptiveGCDisabled() at /__w/1/s/src/coreclr/vm/threads.h:1837:40
  (inlined by) void GCHolderBase::PopInternal<1>() at /__w/1/s/src/coreclr/vm/threads.h:0:0
  (inlined by) GCCoop::~GCCoop() at /__w/1/s/src/coreclr/vm/threads.h:5363:15
  (inlined by) GCInterface_Collect at /__w/1/s/src/coreclr/vm/comutilnative.cpp:894:5

and the corresponding line in the source file gc.cpp is:

    float frag_ratio = (float)(dd_fragmentation (dynamic_data_of (max_generation))) / (float)generation_size (max_generation);

Regression?

It works with .Net 6 and .Net 3.1

Known Workarounds

Disabling signaling floating point exception.

Configuration

The dotnet version is Net 7 RC1. Previous versions of .Net 7 have the same behavior.
The distro is Linux Ubuntu 20.04 or Ubuntu 22.04 or RHEL8.
The architecture is x64.

Other information

No response

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Sep 27, 2022
  2. jkotas commented on Sep 28, 2022

    @jkotas
    Member

    .NET runtime and libraries are not compatible with enabled floating point exceptions. If you need floating point exceptions enabled for your C/C++ library, you need to disable around them around the calls to .NET runtime.

  3. grospelliergilles commented on Sep 28, 2022

    @grospelliergilles
    ContributorAuthor

    Thanks for your quick response.

    I agree with you about floating point exceptions in general but division by zero is a special case because it may be undefined behavior in c++ on some architectures (see cppreference).

    So I think it is good development practice to avoid division by zero in possible. In the current case, it is very easy to fix because you only need to add a if to check if generation_size is not zero or you can divide by generation_size()+1 because the accuracy of the result is not that important.

    Also, it is not easy to disable floating point exception around garbage collector because it may be called everywhere. Net 6 and older versions (and the mono runtime) don't need such a workaround. In the HPC world it is a common practice to trap FPE to detect false numerical results. I agree that some .Net libraries may not support that but if the runtime doesn't have this new limitation it is better.

  4. Maoni0 commented on Sep 28, 2022

    @Maoni0
    Member

    hi @grospelliergilles, thanks for reporting this. I just submitted a fix.

  5. grospelliergilles commented on Sep 28, 2022

    @grospelliergilles
    ContributorAuthor

    Thank you very much ! Have a nice day.

  6. removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 28, 2022
  7. added this to the 8.0.0 milestone on Sep 28, 2022
  8. added a commit that references this issue on Sep 28, 2022
    8022961
  9. Maoni0 commented on Sep 29, 2022

    @Maoni0
    Member

    hi @grospelliergilles this was just backported to .net 7.0.

  10. grospelliergilles commented on Sep 29, 2022

    @grospelliergilles
    ContributorAuthor

    Thank you very much.
    I have a similar problem in the file src/coreclr/jit/fgopt.cpp at line 4991:

    double totalCount = takenCount + notTakenCount;
    double takenRatio = takenCount / totalCount; // < POTENTIAL DIVIDE BY ZERO
    

    Version 6.0.104 also have this this behavior.

    Do you want me to open an issue on this problem ?

  11. Maoni0 commented on Sep 29, 2022

    @Maoni0
    Member

    that'd be a question for @dotnet/jit-contrib :)

  12. kunalspathak commented on Sep 29, 2022

    @kunalspathak
    Contributor

    Feel free to open an issue or a PR to address it @grospelliergilles .

  13. grospelliergilles commented on Sep 29, 2022

    @grospelliergilles
    ContributorAuthor

    Thanks I will provide a fix and do a PR.

  14. ghost locked as resolved and limited conversation to collaborators on Oct 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions