37

I'm running 64-bit Python 2.7.3 on Win7 64-bit. I can reliably crash the Python interpreter by doing this:

>>> from scipy import stats
>>> import time
>>> time.sleep(3)

and pressing Control-C during the sleep. A KeyboardInterrupt is not raised; the interpreter crashes. The following is printed:

forrtl: error (200): program aborting due to control-C event
Image              PC                Routine            Line        Source

libifcoremd.dll    00000000045031F8  Unknown               Unknown  Unknown
libifcoremd.dll    00000000044FC789  Unknown               Unknown  Unknown
libifcoremd.dll    00000000044E8583  Unknown               Unknown  Unknown
libifcoremd.dll    000000000445725D  Unknown               Unknown  Unknown
libifcoremd.dll    00000000044672A6  Unknown               Unknown  Unknown
kernel32.dll       0000000077B74AF3  Unknown               Unknown  Unknown
kernel32.dll       0000000077B3F56D  Unknown               Unknown  Unknown
ntdll.dll          0000000077C73281  Unknown               Unknown  Unknown

This makes it impossible to interrupt long-running scipy calculations.

Googling for "forrtl" and the like, I see suggestions that this kind of problem is due to use of a Fortran library that overrides Ctrl-C handling. I don't see a bug on the Scipy trackerbut given that Scipy is a library for use with Python, I would consider this a bug. It breaks Python's handling of Ctrl-C. Is there any workaround for this?

Edit: Following @cgohlke's suggestion I tried to add my own handler after importing scipy. This question about a related issue shows that adding a signal handler doesn't work. I tried using the Windows API SetConsoleCtrlHandler function via pywin32:

from scipy import stats
import win32api
def doSaneThing(sig, func=None):
    print "Here I am"
    raise KeyboardInterrupt
win32api.SetConsoleCtrlHandler(doSaneThing, 1)

After this, hitting Ctrl-C prints "Here I am", but Python still crashes with the forrtl error. Sometimes I also get a message saying "ConsoleCtrlHandler function failed", which quickly disappears.

If I run this in IPython, I can see a normal Python KeyboardInterrupt traceback before the forrtl error. I also see a normal Python traceback followed by the forrtl error if I raise some other error instead of KeyboardInterrupt (e.g., ValueError):

ValueError                                Traceback (most recent call last)
<ipython-input-1-08defde66fcb> in doSaneThing(sig, func)
      3 def doSaneThing(sig, func=None):
      4     print "Here I am"
----> 5     raise ValueError
      6 win32api.SetConsoleCtrlHandler(doSaneThing, 1)

ValueError:
forrtl: error (200): program aborting due to control-C event
[etc.]

It seems that whatever the underlying handler is doing, it's not just trapping Ctrl-C directly, but is reacting to the error condition (ValueError) and crashing itself. Is there any way to eliminate this?

Community
  • 1
  • 1
BrenBarn
  • 210,788
  • 30
  • 364
  • 352
  • Are you using the [semi-unofficial] MKL-linked versions of 64-bit NumPy and Scipy built by [Christoph Gohlke](http://www.lfd.uci.edu/~gohlke/pythonlibs)? – Eryk Sun Mar 17 '13 at 07:39
  • @eryksun: Yes, that's what I'm using. – BrenBarn Mar 17 '13 at 07:43
  • @eryksun: Yes. Okay, I'll look into newer builds. – BrenBarn Mar 17 '13 at 07:50
  • @eryksun: I downloaded the latest build from that page, but the error still occurs. – BrenBarn Mar 17 '13 at 08:02
  • 1
    The Intel Fortran runtime has it's own CTRL-C handler. This issue is not specific to Scipy or Python. Just google for the error message. You could try to set your own handler after `from scipy import stats`. – cgohlke Mar 17 '13 at 16:59
  • @cgohlke: Thanks for the idea about setting a handler. I had googled the issue but the only "solution" I had seen was someone saying "set a SIGINT handler" and someone else saying "That doesn't work". I have edited my question and added a partial answer below, but as I explain there the solution I found isn't totally satisfying. (Also, if a handler can be set to override the underlying Fortran library's one, why doesn't SciPy do that itself to shield users from this potential for crashes?) – BrenBarn Mar 17 '13 at 21:02
  • Scipy doesn't do that, because this behavior is specific to Intel's Fortran library (the binaries distributed on scipy.org are built with mingw). Moreover, I doubt Scipy developers were aware that this occurs with Intel compilers on win32 (I wasn't). – pv. Mar 18 '13 at 09:10
  • @cgohlke: it seems it's possible to disable installation of the event handler somehow: http://software.intel.com/sites/products/documentation/doclib/stdxe/2013/composerxe/compiler/fortran-win/GUID-72A9672B-E562-44CE-98AF-67B0898A6804.htm (it says that for DLL projects, no exception handling is installed) – pv. Mar 18 '13 at 09:19
  • I have visited this question before (when I had the same problem), and used code similar to what's below. I've just re-tested using Python 2.7.10 together with numpy-1.9.2+mkl-cp27-none-win_amd64.whl and scipy-0.16.0-cp27-none-win_amd64.whl from Christoph Gohlke, and I cannot reproduce the problem. Which is nice. – Steve Jessop Sep 11 '15 at 16:28
  • @SteveJessop: Wow, that would be nice. I'll have to try upgrading. – BrenBarn Sep 11 '15 at 20:20
  • For Intel Fortran >=16 set the [`FOR_DISABLE_CONSOLE_CTRL_HANDLER=1`](https://software.intel.com/en-us/node/579775) environment variable. Unfortunately that version no longer supports Visual Studio 2008 required by Python 2.7. – cgohlke Sep 14 '15 at 00:10
  • @cgohlke: Thanks for the update, I'll keep it in mind if I wind up with that version. It is irritating that older Fortran versions don't seem to provide a way to do it. – BrenBarn Sep 14 '15 at 00:13

7 Answers7

23

Here's a variation on your posted solution that may work. Maybe there's a better way to solve this problem -- or maybe even avoid it all together by setting an environment variable that tells the DLL to skip installing a handler. Hopefully this helps until you find a better way.

Both the time module (lines 868-876) and _multiprocessing module (lines 312-321) call SetConsoleCtrlHandler. In the case of the time module, its console control handler sets a Windows event, hInterruptEvent. For the main thread, time.sleep waits on this event via WaitForSingleObject(hInterruptEvent, ul_millis), where ul_millis is the number of milliseconds to sleep unless interrupted by Ctrl+C. Since the handler that you've installed returns True, the time module's handler never gets called to set hInterruptEvent, which means sleep cannot be interrupted.

I tried using imp.init_builtin('time') to reinitialize the time module, but apparently SetConsoleCtrlHandler ignores the 2nd call. It seems the handler has to be removed and then reinserted. Unfortunately, the time module doesn't export a function for that. So, as a kludge, just make sure you import the time module after you install your handler. Since importing scipy also imports time, you need to pre-load libifcoremd.dll using ctypes to get the handlers in the right order. Finally, add a call to thread.interrupt_main to make sure Python's SIGINT handler gets called[1].

For example:

import os
import imp
import ctypes
import thread
import win32api

# Load the DLL manually to ensure its handler gets
# set before our handler.
basepath = imp.find_module('numpy')[1]
ctypes.CDLL(os.path.join(basepath, 'core', 'libmmd.dll'))
ctypes.CDLL(os.path.join(basepath, 'core', 'libifcoremd.dll'))

# Now set our handler for CTRL_C_EVENT. Other control event 
# types will chain to the next handler.
def handler(dwCtrlType, hook_sigint=thread.interrupt_main):
    if dwCtrlType == 0: # CTRL_C_EVENT
        hook_sigint()
        return 1 # don't chain to the next handler
    return 0 # chain to the next handler

win32api.SetConsoleCtrlHandler(handler, 1)

>>> import time
>>> from scipy import stats
>>> time.sleep(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyboardInterrupt

[1] interrupt_main calls PyErr_SetInterrupt. This trips Handlers[SIGINT] and calls Py_AddPendingCall to add checksignals_witharg. In turn this calls PyErr_CheckSignals. Since Handlers[SIGINT] is tripped, this calls Handlers[SIGINT].func. Finally, if func is signal.default_int_handler, you'll get a KeyboardInterrupt exception.

Eryk Sun
  • 29,588
  • 3
  • 76
  • 95
  • Thanks, this is very helpful! `thread.interrupt_main` is the key tool I needed. That's what lets you both return True from the handler (to stop the Ctrl-C propagation) and get the KeyboardInterrupt raised. Just using that handler solves the KeyboardInterrupt problem, which was the main sticking point for me. The delay in interrupting `sleep` is less crucial, and when I'm playing around with data interactively, I can't control whether I will or won't have already imported `time`, so I think the arcane DLL loading is more than I really need in practice. – BrenBarn Mar 18 '13 at 19:43
  • This works great for me. Unfortunately, IPython imports time and a ton of other modules during startup. I was able to work around this by putting this code at the beginning of C:\Python27\Scripts\ipython-script.py. Now ctrl-c works correctly and even interrupts time.sleep(). – Evan Jul 16 '14 at 21:00
  • Any ideas for python3? Thanks! – ch271828n Apr 04 '20 at 05:01
12

Setting the environment variable FOR_DISABLE_CONSOLE_CTRL_HANDLER to 1 seems to fix the issue, but only if it is set before loading offending packages.

import os
os.environ['FOR_DISABLE_CONSOLE_CTRL_HANDLER'] = '1'

[...]

EDIT: While Ctrl+C doesn't crash python anymore, it also fails to stop the current calculation.

jedi
  • 255
  • 1
  • 10
Brecht Machiels
  • 2,562
  • 3
  • 19
  • 35
  • 2
    Worked for me. (Anaconda install) – unddoch Sep 13 '18 at 19:08
  • Worked for me (anaconda, ipython) – Janus Nov 18 '20 at 05:37
  • Works, BUT needs to be done **before importing offending packages**. If you use PyCharm, set this env variable in the Python Console settings (environment section). Python Console settings imports all my packages before I get a prompt as a convivence, but that made me think the above solution was not working. But it was not working because I already imported offending packages sklearn, seaborn, and statsmodels. Once env is set, then loading offending packages is fine. – jedi Dec 14 '20 at 23:36
  • Also worked for me in VS Code, placed before all other imports. – user49404 Apr 08 '21 at 00:09
  • This only let me catch a Ctrl-C event once in the execution of the program. Any subsequent times it was ignored. – jr15 May 12 '21 at 19:47
4

I have been able to get a half-workaround by doing this:

from scipy import stats
import win32api
def doSaneThing(sig, func=None):
    return True
win32api.SetConsoleCtrlHandler(doSaneThing, 1)

Returning true in the handler stops the chain of handlers so that the meddling Fortran handler is no longer called. However, this workaround is only partial, for two reasons:

  1. It does not actually raise a KeyboardInterrupt, meaning that I can't react to it in Python code. It just drops me back to the prompt.
  2. It doesn't fully interrupt things in the way that Ctrl-C normally does in Python. If in a fresh Python session I do a time.sleep(3) and hit Ctrl-C, the sleep is immediately aborted and I get a KeyboardInterrupt. With the above workaround, the sleep is not aborted, and control returns to the prompt only after the sleep time is up.

Nonetheless, this is still better than crashing the whole session. To me this raises the question of why SciPy (and any other Python libraries that rely on these Intel libraries) don't do this themselves.

I'm leaving this answer unaccepted in the hope that someone can provide a real solution or workaround. By "real" I mean that pressing Ctrl-C during a long-running SciPy calculation should work just like it does when SciPy is not loaded. (Note that this doesn't mean it has to work immediately. Non-SciPy calculations like plain Python sum(xrange(100000000)) may not immediately abort on Ctrl-C, but at least when they do, they raise a KeyboardInterrupt.)

BrenBarn
  • 210,788
  • 30
  • 364
  • 352
3

Here's code to patch the dll to remove the call that installs the Ctrl-C handler:

import os
import os.path
import imp
import hashlib

basepath = imp.find_module('numpy')[1]
ifcoremd = os.path.join(basepath, 'core', 'libifcoremd.dll')
with open(ifcoremd, 'rb') as dll:
    contents = dll.read()

m = hashlib.md5()
m.update(contents)

patch = {'7cae928b035bbdb90e4bfa725da59188': (0x317FC, '\xeb\x0b'),
  '0f86dcd44a1c2e217054c50262f727bf': (0x3fdd9, '\xeb\x10')}[m.hexdigest()]
if patch:
    contents = bytearray(contents)
    contents[patch[0]:patch[0] + len(patch[1])] = patch[1]
    with open(ifcoremd, 'wb') as dll:
        dll.write(contents)
else:
    print 'Unknown dll version'

EDIT: Here's how I added a patch for the x64. Run python.exe in the debugger, and set a breakpoint for SetConsoleCtrlHandler until you get to the call you want to patch out:

Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: .\venv\Scripts\python.exe
...
0:000> .symfix
0:000> bp kernel32!SetConsoleCtrlHandler
0:000> g
Breakpoint 0 hit
KERNEL32!SetConsoleCtrlHandler:
00007ffc`c25742f0 ff252af00400    jmp     qword ptr [KERNEL32!_imp_SetConsoleCtrlHandler (00007ffc`c25c3320)] ds:00007ffc`c25c3320={KERNELBASE!SetConsoleCtrlHandler (00007ffc`bfa12e10)}
0:000> k 5
Child-SP          RetAddr           Call Site
00000000`007ef7a8 00000000`71415bb4 KERNEL32!SetConsoleCtrlHandler
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\SYSTEM32\python27.dll -
00000000`007ef7b0 00000000`7035779f MSVCR90!signal+0x17c
00000000`007ef800 00000000`70237ea7 python27!PyOS_getsig+0x3f
00000000`007ef830 00000000`703546cc python27!Py_Main+0x21ce7
00000000`007ef880 00000000`7021698c python27!Py_InitializeEx+0x40c
0:000> g
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:40:30) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
...
Breakpoint 0 hit
KERNEL32!SetConsoleCtrlHandler:
00007ffc`c25742f0 ff252af00400    jmp     qword ptr [KERNEL32!_imp_SetConsoleCtrlHandler (00007ffc`c25c3320)] ds:00007ffc`c25c3320={KERNELBASE!SetConsoleCtrlHandler (00007ffc`bfa12e10)}
0:000> k 5
Child-SP          RetAddr           Call Site
00000000`007ec308 00000000`7023df6e KERNEL32!SetConsoleCtrlHandler
00000000`007ec310 00000000`70337877 python27!PyTime_DoubleToTimet+0x10ee
00000000`007ec350 00000000`7033766d python27!PyImport_IsScript+0x4f7
00000000`007ec380 00000000`70338bf2 python27!PyImport_IsScript+0x2ed
00000000`007ec3b0 00000000`703385a9 python27!PyImport_ImportModuleLevel+0xc82
0:000> g
...
>>> import scipy.stats
...
Breakpoint 0 hit
KERNEL32!SetConsoleCtrlHandler:
00007ffc`c25742f0 ff252af00400    jmp     qword ptr [KERNEL32!_imp_SetConsoleCtrlHandler (00007ffc`c25c3320)] ds:00007ffc`c25c3320={KERNELBASE!SetConsoleCtrlHandler (00007ffc`bfa12e10)}
0:000> k 5
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Users\kevin\Documents\\venv\lib\site-packages\numpy\core\libifcoremd.dll -
Child-SP          RetAddr           Call Site
00000000`007ed818 00007ffc`828309eb KERNEL32!SetConsoleCtrlHandler
00000000`007ed820 00007ffc`828dfa44 libifcoremd!GETEXCEPTIONPTRSQQ+0xdb
00000000`007ed880 00007ffc`828e59d7 libifcoremd!for_lt_ne+0xc274
00000000`007ed8b0 00007ffc`828e5aff libifcoremd!for_lt_ne+0x12207
00000000`007ed8e0 00007ffc`c292ddc7 libifcoremd!for_lt_ne+0x1232f
0:000> ub  00007ffc`828309eb
libifcoremd!GETEXCEPTIONPTRSQQ+0xbb:
00007ffc`828309cb 00e8            add     al,ch
00007ffc`828309cd df040b          fild    word ptr [rbx+rcx]
00007ffc`828309d0 0033            add     byte ptr [rbx],dh
00007ffc`828309d2 c9              leave
00007ffc`828309d3 ff15bf390e00    call    qword ptr [libifcoremd!for_lt_ne+0x40bc8 (00007ffc`82914398)]
00007ffc`828309d9 488d0d00efffff  lea     rcx,[libifcoremd!for_rtl_finish_+0x20 (00007ffc`8282f8e0)]
00007ffc`828309e0 ba01000000      mov     edx,1
00007ffc`828309e5 ff158d390e00    call    qword ptr [libifcoremd!for_lt_ne+0x40ba8 (00007ffc`82914378)]

We'll patch out the lea instruction with a relative jmp (which is 0xeb followed by the number of bytes to jump)

0:000> ? 00007ffc`828309eb - 00007ffc`828309d9
Evaluate expression: 18 = 00000000`00000012
0:000> f 00007ffc`828309d9 L2 eb 10
Filled 0x2 bytes
0:000> ub  00007ffc`828309eb
libifcoremd!GETEXCEPTIONPTRSQQ+0xbe:
00007ffc`828309ce 040b            add     al,0Bh
00007ffc`828309d0 0033            add     byte ptr [rbx],dh
00007ffc`828309d2 c9              leave
00007ffc`828309d3 ff15bf390e00    call    qword ptr [libifcoremd!for_lt_ne+0x40bc8 (00007ffc`82914398)]
00007ffc`828309d9 eb10            jmp     libifcoremd!GETEXCEPTIONPTRSQQ+0xdb (00007ffc`828309eb)
00007ffc`828309db 0d00efffff      or      eax,0FFFFEF00h
00007ffc`828309e0 ba01000000      mov     edx,1
00007ffc`828309e5 ff158d390e00    call    qword ptr [libifcoremd!for_lt_ne+0x40ba8 (00007ffc`82914378)]

I don't know how the .dll file is mapped in this process, so I'll just search for 0d 00 ef ff ff in the file with a hex editor. It is a unique hit, so we can calculate the location in the .dll to patch.

0:000> db  00007ffc`828309d0
00007ffc`828309d0  00 33 c9 ff 15 bf 39 0e-00 eb 10 0d 00 ef ff ff  .3....9.........
00007ffc`828309e0  ba 01 00 00 00 ff 15 8d-39 0e 00 48 8d 0d 0e 9c  ........9..H....
00007ffc`828309f0  09 00 e8 09 2e 0a 00 48-8d 0d 32 9f 09 00 e8 fd  .......H..2.....
00007ffc`82830a00  2d 0a 00 48 8d 0d ca ee-0e 00 e8 51 90 00 00 85  -..H.......Q....
00007ffc`82830a10  c0 0f 85 88 02 00 00 e8-38 fa 0a 00 ff 15 4e 39  ........8.....N9
00007ffc`82830a20  0e 00 89 c1 e8 d7 2d 0a-00 48 8d 05 f8 be 11 00  ......-..H......
00007ffc`82830a30  45 32 e4 c7 05 0b 4a 13-00 00 00 00 00 41 bd 01  E2....J......A..
00007ffc`82830a40  00 00 00 48 89 05 06 4a-13 00 ff 15 30 39 0e 00  ...H...J....09..
0:000> ? 00007ffc`828309d9 -  00007ffc`828309d0
Evaluate expression: 9 = 00000000`00000009
0:000> ? 00007ffc`828309d9 -  00007ffc`828309d0 + 3FDD0
Evaluate expression: 261593 = 00000000`0003fdd9
0:000>

Ok, I've patched the dll at 0x3fdd9. Let's see what it looks like now:

Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: .\venv\Scripts\python.exe
...
0:000> bp libifcoremd!GETEXCEPTIONPTRSQQ+c9
Bp expression 'libifcoremd!GETEXCEPTIONPTRSQQ+c9' could not be resolved, adding deferred bp
0:000> g
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:40:30) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import scipy.stats
...
Breakpoint 0 hit
libifcoremd!GETEXCEPTIONPTRSQQ+0xc9:
00007ffc`845909d9 eb10            jmp     libifcoremd!GETEXCEPTIONPTRSQQ+0xdb (00007ffc`845909eb)
0:000> u
libifcoremd!GETEXCEPTIONPTRSQQ+0xc9:
00007ffc`845909d9 eb10            jmp     libifcoremd!GETEXCEPTIONPTRSQQ+0xdb (00007ffc`845909eb)
00007ffc`845909db 0d00efffff      or      eax,0FFFFEF00h
00007ffc`845909e0 ba01000000      mov     edx,1
00007ffc`845909e5 ff158d390e00    call    qword ptr [libifcoremd!for_lt_ne+0x40ba8 (00007ffc`84674378)]
00007ffc`845909eb 488d0d0e9c0900  lea     rcx,[libifcoremd!GETHANDLEQQ (00007ffc`8462a600)]
00007ffc`845909f2 e8092e0a00      call    libifcoremd!for_lt_ne+0x30 (00007ffc`84633800)
00007ffc`845909f7 488d0d329f0900  lea     rcx,[libifcoremd!GETUNITQQ (00007ffc`8462a930)]
00007ffc`845909fe e8fd2d0a00      call    libifcoremd!for_lt_ne+0x30 (00007ffc`84633800)
0:000>

So now were are jmping over pushing the arguments on the stack and the function call. So its Ctrl-C handler will not be installed.

Kevin Smyth
  • 1,747
  • 17
  • 19
  • Wow! Can you explain what you mean by "similar approach"? It all looks pretty mysterious to me. How did you decide what numbers to put in there? – BrenBarn Jul 01 '16 at 03:30
2

Workaround: patch SetControlCtrlHandler

import ctypes
SetConsoleCtrlHandler_body_new = b'\xC2\x08\x00' if ctypes.sizeof(ctypes.c_void_p) == 4 else b'\xC3'
try: SetConsoleCtrlHandler_body = (lambda kernel32: (lambda pSetConsoleCtrlHandler:
    kernel32.VirtualProtect(pSetConsoleCtrlHandler, ctypes.c_size_t(1), 0x40, ctypes.byref(ctypes.c_uint32(0)))
    and (ctypes.c_char * 3).from_address(pSetConsoleCtrlHandler.value)
)(ctypes.cast(kernel32.SetConsoleCtrlHandler, ctypes.c_void_p)))(ctypes.windll.kernel32)
except: SetConsoleCtrlHandler_body = None
if SetConsoleCtrlHandler_body:
    SetConsoleCtrlHandler_body_old = SetConsoleCtrlHandler_body[0:len(SetConsoleCtrlHandler_body_new)]
    SetConsoleCtrlHandler_body[0:len(SetConsoleCtrlHandler_body_new)] = SetConsoleCtrlHandler_body_new
try:
    import scipy.stats
finally:
    if SetConsoleCtrlHandler_body:
        SetConsoleCtrlHandler_body[0:len(SetConsoleCtrlHandler_body_new)] = SetConsoleCtrlHandler_body_old
Community
  • 1
  • 1
user541686
  • 189,354
  • 112
  • 476
  • 821
  • It doesn't seem to work for me. The crash still occurs. (Also, is there a reason you wrote the code in a strange functional style like that?) – BrenBarn Aug 18 '16 at 19:31
  • Ah, it works if I change the import to `import scipy.stats`. (I don't think the top-level scipy module sets the handler.) However, I have the same question for you as I had for Kevin Smyth: How did you decide what magic bytes to put in there? The reason I'm a bit nervous about solutions like this is that patching the bytes directly may fail (or worse) for different versions of Python, scipy, or the Intel library (or am I wrong about that)? – BrenBarn Aug 18 '16 at 19:37
  • @BrenBarn: I actually updated it now, the code is different for x86 and x64. `C3` is just a `retn` instruction, whereas `C2` is a `retn` instruction that also pops arguments off the stack. The latter is necessary on x86, since it needs to pop off 8 bytes (2 arguments, 4 each) off the stack. On x64 the caller cleans up. It's a really simple patch, so it really shouldn't break anything. The one exception is if the Intel library decides to report a failure if this function fails, but it doesn't currently do that, and I don't expect it to check for this in the future. You should probably use it. – user541686 Aug 18 '16 at 21:25
  • To be thorough, there should be a `mov eax,0` before the `ret` instructions. – Kevin Smyth Oct 04 '18 at 19:05
1

Try

import os
os.environ['FOR_IGNORE_EXCEPTIONS'] = '1'
import scipy.stats
pv.
  • 29,245
  • 7
  • 47
  • 47
  • 2
    It doesn't work. I tried setting it to '1' and also 'TRUE'. It seems to be for just runtime exceptions, not the [default console event handling](http://software.intel.com/sites/products/documentation/doclib/stdxe/2013/composerxe/compiler/fortran-win/GUID-69D9BCB2-F8E7-400A-B07C-069E285A1BA4.htm). – Eryk Sun Mar 18 '13 at 10:57
  • 1
    This actually did work for me and is a much easier solution. Related github issue: https://github.com/ContinuumIO/anaconda-issues/issues/905#issuecomment-232498034 – islandman93 Aug 05 '16 at 19:11
1

This worked for me:

import os
os.environ['FOR_DISABLE_CONSOLE_CTRL_HANDLER'] = '1'
from scipy.stats import zscore
sɐunıɔןɐqɐp
  • 2,609
  • 15
  • 30
  • 36
  • Works, BUT needs to be done before importing offending packages. If you use PyCharm, set this env variable in the Python Console settings (environment section). Python Console settings imports all my packages before I get a prompt as a convivence, but that made me think the above solution was not working. But it was not working because I already imported offending packages sklearn, seaborn, and statsmodels. Once env is set, then loading offending packages is fine. – jedi Dec 14 '20 at 23:50