Skip to content

Help diagnosing crash from MSYS2 build pthreads?

Matthew edited this page Oct 3, 2021 · 15 revisions

I am have had another attempt at compiling Simutrans-Extended in MSYS2/mingw64 with make (without using CMake).

The program compiles and runs, but crashes. I would appreciate knowing whether my diagnosis of the problem is at least plausible.

Trace and logfile

DrMinGW gives the following trace from a level 1 debug build: DrMinGW says: "Simutrans-Extended-uoM-debug1.exe!path_explorer_threaded  [D:/msys64/home/Admin/simutrans-extended/simworld.cc @ 2006]"

The final lines in simu.log seem irrelevant, except that they suggest the default savefile has been loaded and has begun to run. simu.log: Message: simline_t::register_stops():	4 schedule entries in schedule 000001472c892ca0

Analysis of trace

So it appears that the crash occurs when the Path Explorer begins to create new threads. Simutrans' pthread_create_wrapper function is calling msvcrt.dll's callthreadstartex function. My understanding is that msvcrt.dll is the correct C++ library for mingw64 builds, except for threading, because it uses a different set of functions (Win32 threads) to Simutrans (which wants POSIX threads). So Extended is distributed with pthreadsGC2.dll and we want the Simutrans executable to call the functions there. But it is apparently still calling msvcrt.dll.

Attempted diagnosis of cause

Multithreading is enabled for this build, because configure.default includes this line: MULTI_THREAD = 1 # Enable multithreading

That line should tell make to use pthreads, because the Simutrans-Extended Makefile includes this section:

ifneq ($(MULTI_THREAD),)
  ifeq ($(shell expr $(MULTI_THREAD) \>= 1), 1)
    CFLAGS += -DMULTI_THREAD
    ifeq ($(OSTYPE),mingw32 mingw64)
#use lpthreadGC2d for debug alternatively
#		Disabled, as this does not work for cross-compiling
#      LDFLAGS += -lpthreadGC2
	   LDFLAGS += -static -lpthread
    else
      ifneq ($(OSTYPE),haiku)
        LDFLAGS += -lpthread
      endif
    endif
  endif
endif

We have set the MULTI_THREAD and mingw64 flags, so I think the linker (LD) should know to link to pthread, not msvcrt. So my diagnosis of the problem is that the linker is not linking to pthreads in the executable. Is that at least plausible?

Lines of enquiry and possible solutions

  • Have I failed to install a required pthreads package in mingw64? The setup-mingw.sh file kindly made by Prissi has no reference to pthreads. But if pthreads is completely missing, why does the build complete? Surely the linker or make would fail with an error message? So this does not seem likely.
  • The Standard Makefile sets the LDFLAG as -pthread rather than -lpthread. Could this be a better option? Apparently not, as the executable crashes at the same point with the same trace and logfile.
  • The pthreadGC2 flag is commented out. Why is it commented out? What happens if I point the linker to pthreadGC2 instead? Again, it crashes in exactly the same way.
  • Does the linker think "lpthread" means something else? pthreads is not part of GCC, so perhaps there is some setting that is pointing to the wrong library. Perhaps I need to run Autotools' configure utility? Perhaps config.default is missing the pthread_mutex_destroy flag mentioned in configure.ac???
  • Why does the Makefile have the -static flag set when we want Sim-Ex to link to a DLL (a dynamic link library)?