FIXED: PThreads4W exit crash in MSVC Debug builds#1463
FIXED: PThreads4W exit crash in MSVC Debug builds#1463EricGT wants to merge 1 commit intoSWI-Prolog:masterfrom
Conversation
Call pthread_win32_process_detach_np() in PL_cleanup() after all Prolog threads have terminated and memory has been reclaimed. Without this, PThreads4W's DllMain(DLL_PROCESS_DETACH) accesses freed thread data, causing ACCESS_VIOLATION in Debug builds where the CRT fills freed heap with 0xDD. The explicit cleanup makes the subsequent DllMain call a no-op. Fixes crashes in thread-related tests (http, json, pengines, etc.) when built with MSVC in Debug configuration using PThreads4W from vcpkg. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Combined with the test PR. Also moved detection of this function to CMake as the MinGW thread runtime does not define this and this it breaks the build. Finally adjusted the conditions for running this test as the |
|
FYI
Synced code up to
a97b0b1
A release build did not have any build errors, debug now has a build error,
as such the CTest did not run.
…On Sat, Feb 14, 2026 at 11:46 AM Jan Wielemaker ***@***.***> wrote:
*JanWielemaker* left a comment (SWI-Prolog/swipl-devel#1463)
<#1463 (comment)>
Combined with the test PR. Also moved detection of this function to CMake
as the MinGW thread runtime does not define this and this it breaks the
build. Finally adjusted the conditions for running this test as the clib
and http packages need not be there.
—
Reply to this email directly, view it on GitHub
<#1463 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASDDUR5QUTD3ZWB6ENRUND4L5GN7AVCNFSM6AAAAACVELYUNOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSMBSGE2TQMJZGE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
What is the error? I need to check, but traditionally we did not use the generated |
Seems ok. It includes |
|
What is the error?
Claude narrowed it down to the check for PThread4W, the Code is fine.
It suggested a change which worked to build a release and debug version
if(WIN32 AND PThreads4W_FOUND)
set(HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP 1)else()
check_function_exists(pthread_win32_process_detach_np
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)endif()
which I did not like.
In checking CMake documentation this was suggested.
Now testing with
check_symbol_exists(pthread_win32_process_detach_np "pthread.h"
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
…On Sun, Feb 15, 2026 at 3:58 AM Jan Wielemaker ***@***.***> wrote:
*JanWielemaker* left a comment (SWI-Prolog/swipl-devel#1463)
<#1463 (comment)>
debug now has a build error
What is the error? I need to check, but traditionally we did not use the
generated config.h (when we were using GNU autoconf) because Windows
could not run that. With CMake it is generated, but I think we still use
the hand crafted version. I'll have a look.
—
Reply to this email directly, view it on GitHub
<#1463 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASDDUQTF6WYSP3I54WRTVD4MAYK3AVCNFSM6AAAAACVELYUNOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSMBTHAYTSMBSGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Agree
If that works I'm ok with it. |
|
What is the error?
If you need the details
Using
cmake .. -G Visual Studio 18 2026 -A x64
-DCMAKE_TOOLCHAIN_FILE=C:\dev\vcpkg/scripts/buildsystems/vcpkg.cmake
-DPython_ROOT_DIR=C:\Users\Eric\AppData\Local\Programs\Python
-DBDB_LIBRARY=C:\dev\vcpkg/installed/x64-windows/lib/libdb48.lib
cmake --build . --config Debug --verbose
Just this one error
"C:\dev-MSVC-PR\swipl-devel\build\ALL_BUILD.vcxproj" (default target) (1) ->
"C:\dev-MSVC-PR\swipl-devel\build\doc.vcxproj" (default target) (172) ->
"C:\dev-MSVC-PR\swipl-devel\build\man_index.vcxproj" (default target) (320)
->
(CustomBuild target) ->
C:\Program Files\Microsoft Visual
Studio\18\Community\MSBuild\Microsoft\VC\v180\Microsoft.CppCommon.targets(254,5):
error MSB8066: Custom build for
'C:\dev-MSVC-PR\swipl-devel\build\CMakeFiles\ef26a058d73045c5cc7a626820c0b1c6\manindex.db.rule;C:\dev-MSVC-PR\swipl-devel\build\CMakeFiles\3756dba4d1b419f94b58a6a1dab534db\man_index.rule;C:\dev-MSVC-PR\swipl-devel\CMakeLists.txt'
exited with code -1073741819.
[C:\dev-MSVC-PR\swipl-devel\build\man_index.vcxproj]
…On Sun, Feb 15, 2026 at 4:10 AM Jan Wielemaker ***@***.***> wrote:
*JanWielemaker* left a comment (SWI-Prolog/swipl-devel#1463)
<#1463 (comment)>
which I did not like.
Agree
check_symbol_exists
If that works I'm ok with it.
—
Reply to this email directly, view it on GitHub
<#1463 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASDDUUMUXDRPOETYCWZ4SD4MAZXRAVCNFSM6AAAAACVELYUNOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSMBTHA3TANJSHE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
That is merely the resulting crash during process termination. Anyway, do you make a PR or should I simply update the check in Config.cmake as you propose? If that works, I'm ok with it. Normally I'd try to figure out why it does not work to use the function check by examining the CMake error log. The difference is that the symbol exists merely checks (I think) the header and verifies the symbol is there, while the function check writes a minimal program and verifies this can be compiled and linked. |
|
The noted fix is not working as expected.
Currently testing this variation
# PThreads4W from vcpkg needs its include dir for
check_symbol_existsif(TARGET PThreads4W::PThreads4W)
get_target_property(_ptw32_inc PThreads4W::PThreads4W
INTERFACE_INCLUDE_DIRECTORIES)
list(APPEND CMAKE_REQUIRED_INCLUDES ${_ptw32_inc})endif()
check_symbol_exists(pthread_win32_process_detach_np "pthread.h"
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
…On Sun, Feb 15, 2026 at 6:19 AM Jan Wielemaker ***@***.***> wrote:
*JanWielemaker* left a comment (SWI-Prolog/swipl-devel#1463)
<#1463 (comment)>
If you need the details
That is merely the resulting crash during process termination. Anyway, do
you make a PR or should I simply update the check in Config.cmake as you
propose? If that works, I'm ok with it. Normally I'd try to figure out why
it does not work to use the function check by examining the CMake error
log. The difference is that the symbol exists merely checks (I think) the
header and verifies the symbol is there, while the function check writes a
minimal program and verifies this can be compiled and linked.
—
Reply to this email directly, view it on GitHub
<#1463 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASDDUX3UZZKIMKHAK2V6AT4MBI4VAVCNFSM6AAAAACVELYUNOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSMBUGI2DKMJZG4>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
the function check writes a minimal program and verifies this can be
compiled and linked.
That was done at one point by Claude in my research yesterday.
I can note this to Claude and see if that works. Not sure if this will work
with MSYS2 builds.
…On Sun, Feb 15, 2026 at 6:31 AM EricGT ***@***.***> wrote:
The noted fix is not working as expected.
Currently testing this variation
# PThreads4W from vcpkg needs its include dir for check_symbol_existsif(TARGET PThreads4W::PThreads4W)
get_target_property(_ptw32_inc PThreads4W::PThreads4W INTERFACE_INCLUDE_DIRECTORIES)
list(APPEND CMAKE_REQUIRED_INCLUDES ${_ptw32_inc})endif()
check_symbol_exists(pthread_win32_process_detach_np "pthread.h" HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
On Sun, Feb 15, 2026 at 6:19 AM Jan Wielemaker ***@***.***>
wrote:
> *JanWielemaker* left a comment (SWI-Prolog/swipl-devel#1463)
> <#1463 (comment)>
>
> If you need the details
>
> That is merely the resulting crash during process termination. Anyway, do
> you make a PR or should I simply update the check in Config.cmake as you
> propose? If that works, I'm ok with it. Normally I'd try to figure out why
> it does not work to use the function check by examining the CMake error
> log. The difference is that the symbol exists merely checks (I think) the
> header and verifies the symbol is there, while the function check writes a
> minimal program and verifies this can be compiled and linked.
>
> —
> Reply to this email directly, view it on GitHub
> <#1463 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AASDDUX3UZZKIMKHAK2V6AT4MBI4VAVCNFSM6AAAAACVELYUNOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSMBUGI2DKMJZG4>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>
|
|
This did a successful debug build.
# PThreads4W: check_symbol_exists needs both the include dir and library.
# vcpkg's PThreads4W uses imported targets, so CMAKE_REQUIRED_INCLUDES
# and CMAKE_REQUIRED_LIBRARIES don't automatically include them.
if(TARGET PThreads4W::PThreads4W)
set(_ptw32_saved_libs ${CMAKE_REQUIRED_LIBRARIES})
set(_ptw32_saved_incs ${CMAKE_REQUIRED_INCLUDES})
list(APPEND CMAKE_REQUIRED_INCLUDES ${PThreads4W_INCLUDE_DIR})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${PThreads4W_LIBRARY_RELEASE})
check_symbol_exists(pthread_win32_process_detach_np "pthread.h"
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
set(CMAKE_REQUIRED_LIBRARIES ${_ptw32_saved_libs})
set(CMAKE_REQUIRED_INCLUDES ${_ptw32_saved_incs})
else()
check_symbol_exists(pthread_win32_process_detach_np "pthread.h"
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
endif()
Will hold off on sending a PR at this time.
…---
Next I will try doing function check, writing a minimal program and
verifying this can be compiled and linked.
On Sun, Feb 15, 2026 at 6:33 AM EricGT ***@***.***> wrote:
> the function check writes a minimal program and verifies this can be
compiled and linked.
That was done at one point by Claude in my research yesterday.
I can note this to Claude and see if that works. Not sure if this will
work with MSYS2 builds.
On Sun, Feb 15, 2026 at 6:31 AM EricGT ***@***.***> wrote:
> The noted fix is not working as expected.
>
> Currently testing this variation
>
> # PThreads4W from vcpkg needs its include dir for check_symbol_existsif(TARGET PThreads4W::PThreads4W)
> get_target_property(_ptw32_inc PThreads4W::PThreads4W INTERFACE_INCLUDE_DIRECTORIES)
> list(APPEND CMAKE_REQUIRED_INCLUDES ${_ptw32_inc})endif()
> check_symbol_exists(pthread_win32_process_detach_np "pthread.h" HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
>
>
> On Sun, Feb 15, 2026 at 6:19 AM Jan Wielemaker ***@***.***>
> wrote:
>
>> *JanWielemaker* left a comment (SWI-Prolog/swipl-devel#1463)
>> <#1463 (comment)>
>>
>> If you need the details
>>
>> That is merely the resulting crash during process termination. Anyway,
>> do you make a PR or should I simply update the check in Config.cmake as you
>> propose? If that works, I'm ok with it. Normally I'd try to figure out why
>> it does not work to use the function check by examining the CMake error
>> log. The difference is that the symbol exists merely checks (I think) the
>> header and verifies the symbol is there, while the function check writes a
>> minimal program and verifies this can be compiled and linked.
>>
>> —
>> Reply to this email directly, view it on GitHub
>> <#1463 (comment)>,
>> or unsubscribe
>> <https://github.com/notifications/unsubscribe-auth/AASDDUX3UZZKIMKHAK2V6AT4MBI4VAVCNFSM6AAAAACVELYUNOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSMBUGI2DKMJZG4>
>> .
>> You are receiving this because you authored the thread.Message ID:
>> ***@***.***>
>>
>
|
|
This is what Claude created
# PThreads4W: check_function_exists() fails with vcpkg's imported targets
# because the include directory and library are not in CMAKE_REQUIRED_*.
# Use check_c_source_compiles() to verify the function can be compiled and
# linked, which is a stronger guarantee than a symbol-exists check.
if(TARGET PThreads4W::PThreads4W)
set(_ptw32_saved_libs ${CMAKE_REQUIRED_LIBRARIES})
set(_ptw32_saved_incs ${CMAKE_REQUIRED_INCLUDES})
list(APPEND CMAKE_REQUIRED_INCLUDES ${PThreads4W_INCLUDE_DIR})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${PThreads4W_LIBRARY_RELEASE})
check_c_source_compiles(
"#include <pthread.h>
int main(void) { pthread_win32_process_detach_np(); return 0; }"
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
set(CMAKE_REQUIRED_LIBRARIES ${_ptw32_saved_libs})
set(CMAKE_REQUIRED_INCLUDES ${_ptw32_saved_incs})
else()
check_function_exists(pthread_win32_process_detach_np
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
endif()
It is not what I was expecting, is this what you would expect?
…On Sun, Feb 15, 2026 at 7:20 AM EricGT ***@***.***> wrote:
This did a successful debug build.
# PThreads4W: check_symbol_exists needs both the include dir and library.
# vcpkg's PThreads4W uses imported targets, so CMAKE_REQUIRED_INCLUDES
# and CMAKE_REQUIRED_LIBRARIES don't automatically include them.
if(TARGET PThreads4W::PThreads4W)
set(_ptw32_saved_libs ${CMAKE_REQUIRED_LIBRARIES})
set(_ptw32_saved_incs ${CMAKE_REQUIRED_INCLUDES})
list(APPEND CMAKE_REQUIRED_INCLUDES ${PThreads4W_INCLUDE_DIR})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${PThreads4W_LIBRARY_RELEASE})
check_symbol_exists(pthread_win32_process_detach_np "pthread.h"
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
set(CMAKE_REQUIRED_LIBRARIES ${_ptw32_saved_libs})
set(CMAKE_REQUIRED_INCLUDES ${_ptw32_saved_incs})
else()
check_symbol_exists(pthread_win32_process_detach_np "pthread.h"
HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
endif()
Will hold off on sending a PR at this time.
---
Next I will try doing function check, writing a minimal program and
verifying this can be compiled and linked.
On Sun, Feb 15, 2026 at 6:33 AM EricGT ***@***.***> wrote:
> > the function check writes a minimal program and verifies this can be
> compiled and linked.
>
> That was done at one point by Claude in my research yesterday.
>
> I can note this to Claude and see if that works. Not sure if this will
> work with MSYS2 builds.
>
>
>
> On Sun, Feb 15, 2026 at 6:31 AM EricGT ***@***.***> wrote:
>
>> The noted fix is not working as expected.
>>
>> Currently testing this variation
>>
>> # PThreads4W from vcpkg needs its include dir for check_symbol_existsif(TARGET PThreads4W::PThreads4W)
>> get_target_property(_ptw32_inc PThreads4W::PThreads4W INTERFACE_INCLUDE_DIRECTORIES)
>> list(APPEND CMAKE_REQUIRED_INCLUDES ${_ptw32_inc})endif()
>> check_symbol_exists(pthread_win32_process_detach_np "pthread.h" HAVE_PTHREAD_WIN32_PROCESS_DETACH_NP)
>>
>>
>> On Sun, Feb 15, 2026 at 6:19 AM Jan Wielemaker ***@***.***>
>> wrote:
>>
>>> *JanWielemaker* left a comment (SWI-Prolog/swipl-devel#1463)
>>> <#1463 (comment)>
>>>
>>> If you need the details
>>>
>>> That is merely the resulting crash during process termination. Anyway,
>>> do you make a PR or should I simply update the check in Config.cmake as you
>>> propose? If that works, I'm ok with it. Normally I'd try to figure out why
>>> it does not work to use the function check by examining the CMake error
>>> log. The difference is that the symbol exists merely checks (I think) the
>>> header and verifies the symbol is there, while the function check writes a
>>> minimal program and verifies this can be compiled and linked.
>>>
>>> —
>>> Reply to this email directly, view it on GitHub
>>> <#1463 (comment)>,
>>> or unsubscribe
>>> <https://github.com/notifications/unsubscribe-auth/AASDDUX3UZZKIMKHAK2V6AT4MBI4VAVCNFSM6AAAAACVELYUNOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSMBUGI2DKMJZG4>
>>> .
>>> You are receiving this because you authored the thread.Message ID:
>>> ***@***.***>
>>>
>>
|
Prevents DllMain from accessing freed thread state during process exit. Details in commit message.