Skip to content

clang-cl on Windows incorrectly compiles SEH (structured exception handling) #131691

Description

@chris-eibl

Bug report

Bug description:

clang-cl incorrectly handles SEH exception handling: llvm/llvm-project#62606
E.g. in

int
safe_memcpy(void *dest, const void *src, size_t count)
{
HANDLE_INVALID_MEM(
memcpy(dest, src, count);
);
return 0;
}

where
#define HANDLE_INVALID_MEM(sourcecode) \
do { \
EXCEPTION_RECORD record; \
__try { \
sourcecode \
} \
__except (filter_page_exception(GetExceptionInformation(), &record)) { \
assert(record.ExceptionCode == EXCEPTION_IN_PAGE_ERROR || \
record.ExceptionCode == EXCEPTION_ACCESS_VIOLATION); \
if (record.ExceptionCode == EXCEPTION_IN_PAGE_ERROR) { \
NTSTATUS status = (NTSTATUS) record.ExceptionInformation[2]; \
ULONG code = LsaNtStatusToWinError(status); \
PyErr_SetFromWindowsErr(code); \
} \
else if (record.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { \
PyErr_SetFromWindowsErr(ERROR_NOACCESS); \
} \
return -1; \
} \
} while (0)

This lets test_mmap.MmapTests.test_access_violations fail for clang-cl builds on Windows,
see e.g. https://github.com/python/cpython/actions/runs/14044831663/job/39323183797?pr=131690#step:4:566.

The suggestion in llvm/llvm-project#62606 (comment) is to use EHa,

the problem is that without /EHa, the compiler assumes memory accesses don't trap

which seems wrong, and clearly is a compatibility issue wrt to MSVC.
Since Python code is compiled in C mode, EHa would seem really weird to me. Even more weird workaround: wrap the "body" (here sourcecode) in a separate function and guard that via SEH.

I've tried both workarounds and they would fix the problem.

CPython versions tested on:

3.14

Operating systems tested on:

Windows

Linked PRs

Activity

  1. zooba commented on Mar 24, 2025

    @zooba
    Member

    Even more weird workaround: wrap the "body" (here sourcecode) in a separate function and guard that via SEH.

    I thought we were already doing that? I tried to make sure it was designed that way (e.g. the "safe_*" functions) so that it's clear where the protection starts and ends, and we don't have to worry about any state (e.g. no calls back into Python are possible). The macro should just be to help implement those with less repetition (not my preference, but someone else was doing the PR).

    But looking a little further down the llvm issue, it sounds like they just gave /EHa a slightly different meaning. So if it can be specified for Clang (I assume the ClCompile.ExceptionHandling metadata is interpreted here?) but not MSVC then it seems that should be fine.

  2. changed the title [-]test_mmap.MmapTests.test_access_violations fails for clang-cl builds on Windows[/-] [+]clang-cl on Windows incorrectly handles SEH exception handling[/+] on Mar 25, 2025
  3. chris-eibl commented on Mar 25, 2025

    @chris-eibl
    MemberAuthor

    Yeah, since SEH is also used in sqlite3.c and ctypes (and up to recently for stack checking via _alloca), let's set <ExceptionHandling>Async</ExceptionHandling> in pyproject-clangcl.props so that all source files are compiled with it: #131730

  4. changed the title [-]clang-cl on Windows incorrectly handles SEH exception handling[/-] [+]clang-cl on Windows incorrectly compiles SEH (structuered exception handling)[/+] on Mar 25, 2025
  5. changed the title [-]clang-cl on Windows incorrectly compiles SEH (structuered exception handling)[/-] [+]clang-cl on Windows incorrectly compiles SEH (structured exception handling)[/+] on Mar 25, 2025
  6. added a commit that references this issue on Mar 25, 2025
  7. added a commit that references this issue on Apr 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-windowsextension-modulesC modules in the Modules dirtestsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions