Skip to content

Destructors are not called during unwinding of SEH exceptions for Windows x86 binaries with /EHa #90946

@momo5502

Description

@momo5502

Building sample below with cl.exe (both x64 and x86) using cl.exe /EHa a.cpp yields the following expected output:

Destructor called
Exception thrown

Building it with clang-cl.exe for x86 using clang-cl.exe -m32 /EHa a.cpp yields the following output:

Destructor NOT called
Exception thrown

As one can see, the destructor is not being called when unwinding.
Note that compiling that sample using clang-cl for x64 works completely fine. This is only an issue with x86.

Another thing worth mentioning is that taking the code from HandleDestructorCallWithException and putting it directly within CatchNativeExceptions causes the x86 binary to crash, while x64 works fine.

The sample:

#include <cstdio>


struct Destructor {
  Destructor(bool* destructorCalled) : mDestructorCalled(destructorCalled) {}
  ~Destructor() { *mDestructorCalled = true; }
  bool* mDestructorCalled;
};


void HandleDestructorCallWithException(bool* destructorCalled)
{
  Destructor x(destructorCalled);
  *reinterpret_cast<int*>(1) = 1;
}


void CatchNativeExceptions(bool* destructorCalled, bool* exceptionThrown)
{
  try {
    HandleDestructorCallWithException(destructorCalled);
  }
  catch(...) {
    *exceptionThrown = true;
  }
}


int main()
{
  bool destructorCalled = false;
  bool exceptionThrown = false;

  CatchNativeExceptions(&destructorCalled, &exceptionThrown);

  puts(destructorCalled ? "Destructor called" : "Destructor NOT called");
  puts(exceptionThrown ? "Exception thrown" : "Exception NOT thrown");

  return destructorCalled && exceptionThrown ? 0 : 1;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions