-
-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cysignals for windows #76
Conversation
One immediate major comment: I don't like code of the form
where the "POSIX version" and "Windows version" are mostly the same but not really. You really should avoid that. |
setup.py
Outdated
] | ||
|
||
scripts = [] | ||
|
||
if os.name is not 'nt': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very bad. Compare strings with !=
rundoctests.py
Outdated
# side effects from doctests. | ||
p = Process(target=testfile, args=(f,)) | ||
p.start() | ||
p.join(200) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe to be safer, increase the timeout to 10 minutes or so. And better be explicit and use join(timeout=600)
. You also need to handle the case of timeout.
src/cysignals/signals.pyx
Outdated
void setup_cysignals_handlers() nogil | ||
void print_backtrace() nogil | ||
void _sig_on_interrupt_received() nogil | ||
void _sig_on_recover() nogil | ||
void _sig_off_warning(const char*, int) nogil | ||
|
||
IF UNAME_SYSNAME != 'Windows': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for that. I doesn't hurt to declare functions which do not exist.
src/cysignals/signals.pyx
Outdated
elif sig == SIGSEGV: | ||
if msg is NULL: | ||
msg = "Segmentation fault" | ||
PyErr_SetString(SignalError, msg) | ||
else: | ||
raise SystemError(f"unknown signal number {sig}") | ||
IF UNAME_SYSNAME != 'Windows': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please be more explicit on this one ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am just saying that you should try to replace the code
IF UNAME_SYSNAME == 'Windows':
X
ELSE:
Y
by
X
Y
(i.e. remove the conditions)
src/cysignals/signals.pyx
Outdated
@@ -193,22 +205,23 @@ def init_cysignals(): | |||
import signal | |||
old = signal.signal(signal.SIGINT, python_check_interrupt) | |||
|
|||
setup_alt_stack() | |||
IF UNAME_SYSNAME != 'Windows': | |||
setup_alt_stack() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one cause an undefined reference to 'setup_alt_stack'
if removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one cause an undefined reference to 'setup_alt_stack' if removed
Yes of course. But then you just implement setup_alt_stack
to do nothing on Windows. This is related to the "major comment" that you should try to implement things as much as possible the same for POSIX and Windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok i get the idea. Thx.
src/cysignals/signals.pyx
Outdated
feature... | ||
""" | ||
setup_alt_stack() | ||
IF UNAME_SYSNAME != 'Windows': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
undefined reference to 'setup_alt_stack'
if removed
rundoctests.py
Outdated
flag_skip_posix = OPTIONFLAGS_BY_NAME["SKIP_POSIX"] | ||
|
||
|
||
class WindowsSkipDocTestParser(DocTestParser): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Windows
in the name here? You handle SKIP_WINDOWS
as well as SKIP_POSIX
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I should have rename after adding SKIP_POSIX
.
Can you at least enable tests such that we can follow up on the errors? |
Can you explain why you need all the patches in |
example/setup.py
Outdated
# Option "-D_hypot=hypot" is mandatory for mingw64 | ||
extensions = [Extension('cysignals_example', | ||
['cysignals_example.pyx'], | ||
extra_compile_args=['-D_hypot=hypot'])] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's up with hypot
? The example code doesn't involve hypot
at all, so why is this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
short story :
In file included from c:/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/math.h:36:0,
from c:\Python27-x64\include/pyport.h:325,
from c:\Python27-x64\include/Python.h:58,
from cysignals_example.cpp:24:
c:/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/cmath:1136:11: error: '::hypot' has not been declared
using ::hypot;
Long story :
https://ci.appveyor.com/project/vinklein/cysignals/build/1.0.194
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is likely a bug in mingw64.
Can you send me the pre-processed source file (created with -save-temps
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And maybe also the file c:/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/cmath
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually a Python bug: python/cpython#880
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In master, I pushed a commit to stop using <math.h>
in the example. Hopefully the issue will be gone then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why but it look like <math.h>
is still called (https://ci.appveyor.com/project/vinklein/cysignals/build/job/no6rwrud4sojkauv).
src/cysignals/implementation.c
Outdated
@@ -4,7 +4,8 @@ Interrupt and signal handling for Cython | |||
|
|||
/***************************************************************************** | |||
* Copyright (C) 2006 William Stein <wstein@gmail.com> | |||
* 2006-2016 Martin Albrecht <martinralbrecht+cysignals@gmail.com> | |||
* 2006-2016 Martin Albrecht <martinralbrecht+cysignals@gmail.com |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't change this line
@@ -4,7 +4,8 @@ Interrupt and signal handling for Cython | |||
|
|||
/***************************************************************************** | |||
* Copyright (C) 2006 William Stein <wstein@gmail.com> | |||
* 2006-2016 Martin Albrecht <martinralbrecht+cysignals@gmail.com> | |||
* 2006-2016 Martin Albrecht <martinralbrecht+cysignals@gmail.com | |||
* 2016 Marc Culler and Nathan Dunfield | |||
* 2010-2018 Jeroen Demeyer <J.Demeyer@UGent.be> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to add your own name here
src/cysignals/implementation.c
Outdated
@@ -21,6 +22,23 @@ Interrupt and signal handling for Cython | |||
* along with cysignals. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
****************************************************************************/ | |||
#define ENABLE_DEBUG_CYSIGNALS 0 | |||
#if ENABLE_DEBUG_CYSIGNALS | |||
#define DEBUG(...) fprintf(stderr, __VA_ARGS__); fflush(stderr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't do this. Use cysigs.debug_level
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If i understand correctly the different debug_level
s are here to indicate how much details we want to be printed rather than a trace category like WARNING
, INFO
DEBUG
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than a trace category like WARNING, INFO DEBUG ?
I consider it as various levels of debug information. It's more like DEBUG_A_LITTLE
, DEBUG_SOME_MORE
and DEBUG_A_LOT
.
src/cysignals/implementation.c
Outdated
} | ||
|
||
__PYX_EXTERN_C DL_EXPORT(int) sig_raise_exception(int, char const *); | ||
//extern int sig_raise_exception(int sig, const char* msg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with this?
src/cysignals/macros.h
Outdated
@@ -92,8 +92,11 @@ extern "C" { | |||
* if the first returns 0). | |||
*/ | |||
|
|||
#define _sig_on_(message) ( unlikely(_sig_on_prejmp(message, __FILE__, __LINE__)) || _sig_on_postjmp(cysetjmp(cysigs.env)) ) | |||
|
|||
#if defined(__MINGW32__) || defined(_WIN32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this. Just #define cysetjmp
appropriately.
Am I understanding correctly that you are still using the same |
It would be good to (eventually) port For now, the most important thing is to clean up and reorganize the code. Feel free to write wrapper functions where needed, for example to hide the difference between |
You mean in a documentation or here ? |
Where did you get those patches from? Is it possible to configure The problem with patching on appveyor is that cysignals won't work on real Windows machines, it will only work on appveyor. |
I didn't get them form some place i written them based after finding this stackoverflow Python 3.4: compile cython module for 64-bit windows. They are just git diff with vanilla versions of distutils.
This is not really a problem as the patchs are not appveyor specific. The wiki page How-to-install-cysignals-on-Windows is not up to date but the idea is here. |
I seems to me that your patches come from https://bugs.python.org/issue11723 |
It also seems like you should be able to monkey-patch |
Yes via the stackoverflow mentioned above. I don't mean i invented the solution. |
I will look at it. |
# This was discovered at https://github.com/sagemath/cysignals/issues/71 | ||
# but I don't know a good analysis nor solution. | ||
DOCTEST = ulimit -s 1024 && $(PYTHON) -B rundoctests.py | ||
ifeq ($(OS),Windows_NT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just pushed a commit to master which hopefully makes these changes to Makefile
unneeded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works for removing LN_SITE_PACKAGE
.
But ulimit
don't exist on windows.
I will push the rebase after some others tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But ulimit don't exist on windows.
OK, so you get an error but the tests continue, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will push the rebase after some others tests
Maybe squash your commits. It's not really helpful to have a lot of commits, especially when some just revert earlier commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so you get an error but the tests continue, right?
Yes ulimit don't look to be blocking, but i have another error crashing distcheck with my current rebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe instead of doing these kind of hacks, we could just say that one should run make distcheck
on Windows. I think that it's fine if we run make distcheck
on at least one platform, but not all.
src/cysignals/macros.h
Outdated
@@ -276,10 +304,21 @@ static inline void sig_error(void) | |||
{ | |||
fprintf(stderr, "sig_error() without sig_on()\n"); | |||
} | |||
#if defined(__MINGW32__) || defined(_WIN32) | |||
/* | |||
* The Windows abort function will terminate the process no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the abort()
function terminate the process or does the SIGABRT
signal abort the process? If only abort()
really aborts, then you could use raise(SIGABRT)
instead.
fprintf(stderr, "Incremented win32ctrlc to %d\n", win32ctrlc); | ||
} | ||
#endif | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't you raise(SIGFPE)
here?
src/cysignals/implementation.c
Outdated
sig_atomic_t inside = cysigs.inside_signal_handler; | ||
cysigs.inside_signal_handler = 1; | ||
|
||
if (inside == 0 && cysigs.sig_on_count > 0 && sig != SIGQUIT) | ||
#else | ||
int inside = 0; // not used for windows | ||
if(cysigs.sig_on_count > 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason that you are not using inside_signal_handler
on Windows?
src/cysignals/implementation.c
Outdated
if(cysigs.debug_level >=1) | ||
fprintf(stderr, "Mapped from %d\n", cysigs.sig_mapped_to_FPE); | ||
#endif | ||
int mapped_sig = cysigs.sig_mapped_to_FPE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify this as sig = cysigs.sig_mapped_to_FPE;
Looking again at some Windows documentation, I'm not convinced that the SIGINT is not supported for any Win32 application. When a CTRL+C interrupt occurs, Win32 operating systems generate a new thread to specifically handle that interrupt. This can cause a single-thread application, such as one in UNIX, to become multithreaded and cause unexpected behavior. but it only says that for So maybe you are overcomplicating things with the |
That page also says Do not use longjmp unless the interrupt is caused by a floating-point exception (that is, sig is SIGFPE). but it doesn't really say why. For |
Yes it does work ! |
The most of disabled tests seems to be that way because of |
Currently (in windows_dev branch) |
I would rather not have it in |
setup_trampoline use |
Just commenting here: the reason that I'm using |
Rebase on 582dbf6 and many modifications :
Some remaining issues:
works on windows but running
|
For what i know there is no clean way to do that (look at terminateprocess and terminatethread), the existing functions can cause resources to not be released. |
|
One point to clarify : running |
src/cysignals/tests.pyx
Outdated
@@ -165,19 +165,19 @@ def interrupt_after_delay(ms_delay=500): | |||
""" | |||
signal_after_delay(SIGINT, ms_delay) | |||
|
|||
IF UNAME_SYSNAME != 'Windows': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be needed anymore
@@ -639,7 +639,14 @@ def unguarded_abort(): | |||
We run Python in a subprocess and make it call abort():: | |||
|
|||
>>> from cysignals.tests import subpython_err | |||
>>> subpython_err('from cysignals.tests import *; unguarded_abort()') | |||
>>> subpython_err('from cysignals.tests import *; unguarded_abort()') # doctest: +SKIP_WINDOWS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this test duplicated?
You are still introducing various needless whitespace changes, please have a look at the diff. |
Yes. Some have already been fixed under vinklein:appveyor_test branch |
Modify cysignals for windows compatibility
For easier testing, I copied this to a branch |
This PR is a proposal for issue #63. For feedback and advices.
The core of this PR is based on cypari fork of cysignals.
Continuous integration is working in four version python versions Python27, Python27-64bits, Python34 and Python34-64bits (build #186 for example).
Some notes / remaining questions :
win32ctrlc
CYSIGNALS_CRASH_QUIET
doesn't work yet on windows. Fixed