On Fri, Nov 20, 2020 at 11:44 AM Erich Steinböck <erich.steinbo...@gmail.com> wrote:
> According to https://gitlab.kitware.com/cmake/cmake/-/issues/20610 > "CMake currently hard-codes default /GR /EHsc flags." > > And this is how to change flags according to > https://gitlab.kitware.com/cmake/cmake/-/issues/19084 > string(REGEX REPLACE " /EHsc" " /EHs" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") > I'm buidling a trial with those options explicitly set, but your solution looks good too. You might want to be more explicit and use /EHsc-, which is what the docs here: https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=msvc-160 recommends. > > With above change and a rebuild the issue seems to be gone. > Fantastic! > > So why was the issue confined to SysFileTree? > Is /EHs allowing us to use ThrowExceptionX in external C code? > It wasn't so much the "s' part of the option, but the "c" part of the option that was the issue. > Or does it allow using throw / catch blocks in such external code? > > SysFileTree is a little unique. It creates an object that has a destructor that makes API calls. When the exception was thrown, the destructor made two API calls to set the Stem count on the return result. These two calls acquired the kernel lock and released them. This had the side effect of nulling out ActivityManager::currentActivity (which was non-null before the destructor was called). The catch code in NativeActivation checks to see if this activity is holding the lock, and if not, it requests it. Since this value is NULL, it requests the semaphore again, creating the nested situation. a In other situations (such as our test cases). The throw goes immediately to the catch in NativeActivation, the test for "am I currently holding the lock" succeeds because the ApiContext destructor in the ThrowExceptionX() functions was never getting run. The lock was not re-requested, so things were working largely by accident. Turning off the "c" part of /EH allows the code generated for the ThrowExceptionX functions to properly unwinded from a thrown exception. > Just for documentation - these are current CMake defaults for MSVC (we're > changing /MD to /MT everywhere and now also change /EHsc to /EHs for > CMAKE_CXX_FLAGS) > -- CMAKE_CXX_FLAGS /DWIN32 /D_WINDOWS /W3 /GR /EHsc > -- CMAKE_CXX_FLAGS_DEBUG /MDd /Zi /Ob0 /Od /RTC1 > -- CMAKE_CXX_FLAGS_RELEASE /MD /O2 /Ob2 /DNDEBUG > -- CMAKE_C_FLAGS /DWIN32 /D_WINDOWS /W3 > -- CMAKE_C_FLAGS_DEBUG /MDd /Zi /Ob0 /Od /RTC1 > -- CMAKE_C_FLAGS_RELEASE /MD /O2 /Ob2 /DNDEBUG > > On Fri, Nov 20, 2020 at 3:43 PM Rick McGuire <object.r...@gmail.com> > wrote: > >> Ok, I tried an experiment, and I believe I found the root cause of the >> problem. It appears that CMake is using the compiler option /Ehc, which >> assumes that C extern functions will never throw an exception. Since >> ThrowExceptionC is declared as an extern C function, the compiler is not >> generating any code for exception handling, causing the problem. The fix is >> to figure out how to change the compiler options getting used. >> >> Rick >> >> On Fri, Nov 20, 2020 at 9:21 AM Rick McGuire <object.r...@gmail.com> >> wrote: >> >>> A deeper dive. This definitely looks like a bug in the Windows >>> throw/catch handling. After the exception is thrown, I see ApiContext >>> destructors running for two API calls from the StemHanderl destructor, but >>> never see the destructor for the ThrowException2 stack frame getting >>> called. This leaves the semaphore in a bad state. >>> >>> Rick >>> >>> On Fri, Nov 20, 2020 at 9:12 AM Rick McGuire <object.r...@gmail.com> >>> wrote: >>> >>>> I think I figured it out. After the exception is thrown, the destructor >>>> for the StemHandler variable gets invoked, which ends up making a call to >>>> several APIs while in the state where the kernel semaphore is held. This >>>> acquires, and then releases the semaphore, which has the effect that the >>>> ApiContext ends up not releasing the semaphore when invoked because it >>>> doesn't believe it is holding it. This looks like a Windows bug or compiler >>>> bug to me, because the destructors are getting invoked out of order. That >>>> is, the StemHandler destructor appears to be invoked BEFORE the ApiContext >>>> one for the ThrowException2() call. We may need to continue to rely on >>>> using the RaiseExceptionX calls. >>>> >>>> Rick >>>> >>>> On Fri, Nov 20, 2020 at 9:03 AM Erich Steinböck < >>>> erich.steinbo...@gmail.com> wrote: >>>> >>>>> This is Windows-only. >>>>> But it also seems to be SysFileTree-specific - see below code sample. >>>>> >>>>> ~~~ >>>>> i = 1 >>>>> start: >>>>> signal on syntax >>>>> select case i >>>>> when 1 then call SysGetKey "z" >>>>> when 2 then call SysSearchPath "PATH", "%", "z" >>>>> when 3 then call SysFileSearch "%", "%", f., "z" >>>>> when 4 then call SysFileTree "%", f., "z" >>>>> when 5 then call SysFileTree "", f. >>>>> otherwise exit >>>>> end >>>>> say "no SYNTAX" >>>>> syntax: >>>>> signal off syntax >>>>> say condition("object")~code condition("object")~message >>>>> i += 1 >>>>> >>>>> m = ""~start("LENGTH") >>>>> r = m~result >>>>> signal start >>>>> ~~~ >>>>> >>>>> On Fri, Nov 20, 2020 at 1:08 PM Rick McGuire <object.r...@gmail.com> >>>>> wrote: >>>>> >>>>>> I suspected it would. I'm not sure what's going on here. The >>>>>> destructor for ApiContext in the ThrowException2 stub is supposed to >>>>>> release the kernel semaphore when an exception is thrown, then when the >>>>>> exception is caught in NativeActivation, the semaphore is reacquired. >>>>>> Somehow, the semaphore is ending up as a nested request, such that the >>>>>> main >>>>>> thread ends up holding on to it forever. I've traced this process in the >>>>>> debugger, and everything is happening as suspected, but somehow the mutex >>>>>> is still messed up. Does this fail on any other platforms, or is it just >>>>>> a >>>>>> Windows problem? >>>>>> >>>>>> Rick >>>>>> >>>>>> On Fri, Nov 20, 2020 at 5:58 AM Erich Steinböck < >>>>>> erich.steinbo...@gmail.com> wrote: >>>>>> >>>>>>> Replacing ThrowException2 with RaiseException2 in >>>>>>> nullStringException() in RexxUtilCommon.hpp makes this piece of code >>>>>>> work >>>>>>> again. >>>>>>> >>>>>>> On Fri, Nov 20, 2020 at 10:34 AM Erich Steinböck < >>>>>>> erich.steinbo...@gmail.com> wrote: >>>>>>> >>>>>>>> isolate the problem to a single test >>>>>>>>> >>>>>>>> OK, this piece of code reproduces the hang - both on 32- and 64-bit >>>>>>>> Windows >>>>>>>> >>>>>>>> ~~~ >>>>>>>> signal on syntax >>>>>>>> call SysFileTree "", f. >>>>>>>> syntax: >>>>>>>> >>>>>>>> m = ""~start("HELLO") >>>>>>>> r = m~result >>>>>>>> ~~~ >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>> Oorexx-devel mailing list >>>>>>> Oorexx-devel@lists.sourceforge.net >>>>>>> https://lists.sourceforge.net/lists/listinfo/oorexx-devel >>>>>>> >>>>>> _______________________________________________ >>>>>> Oorexx-devel mailing list >>>>>> Oorexx-devel@lists.sourceforge.net >>>>>> https://lists.sourceforge.net/lists/listinfo/oorexx-devel >>>>>> >>>>> _______________________________________________ >>>>> Oorexx-devel mailing list >>>>> Oorexx-devel@lists.sourceforge.net >>>>> https://lists.sourceforge.net/lists/listinfo/oorexx-devel >>>>> >>>> _______________________________________________ >> Oorexx-devel mailing list >> Oorexx-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/oorexx-devel >> > _______________________________________________ > Oorexx-devel mailing list > Oorexx-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/oorexx-devel >
_______________________________________________ Oorexx-devel mailing list Oorexx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/oorexx-devel