I am building python form source using tarball, I have made some changes to the source code so that it can run on my platform. My platform is NonStop systems. When I try to run the following code my retcode returns a value of 9 whereas it’s ideal return value should be -2.
any suggestions on where to start looking in order to debug this issue. I tried to debug in the subprocess call, the waitpid returns sts value of 2304 and then _handle_exit_status call returns a value of 9.
It is posix compliant to an extent(it’s legacy code so don’t know to what extent). My question being where to look for to start debugging, at which point of the program are signal handlers mapped? Does python use the default mapping or creates it’s own mapping for handling events? Where is the mapping set for handling of KeyboardInterrupt.
That’s how they all show up on my Linux system. Note that I can exit with any 8-bit unsigned value, and negative numbers become positive numbers above 127; exiting 130 just exits 130 like you’d expect, and exiting -2 is exactly the same as exiting 254. But killing the process with 2 should exit with -2, and in this case, it reports KeyboardInterrupt and then does exactly that. Raising KeyboardInterrupt manually does the same thing. Sending different signals should also exit with negative numbers, although the default handling of a signal may affect this; for instance:
The issue seems to be related to the fact that the script is raising a KeyboardInterrupt exception, and the subprocess.call() function is returning a value of 9 instead of the expected value of -2. Here’s what you can do to debug the issue:
Check the documentation for the subprocess module to see what the return codes mean. According to the documentation, a return code of 9 means that the process was terminated by a signal.
Modify the myscript.py file to catch the KeyboardInterrupt exception and return the expected value of -2. Here’s an example:
def signal_handler(sig, frame):
# Your code here
This code sets up a signal handler for the SIGINT signal, which is raised when the user presses Ctrl+C. When the signal is received, the signal_handler function is called, which raises a KeyboardInterrupt exception. The try-except block catches the exception and exits with a return code of -2.
Use the PDB (Python Debugger) module to step through the code and see where the KeyboardInterrupt exception is being raised. Here’s an example:
# Your code here
if __name__ == '__main__':
This code sets a breakpoint in the code using the set_trace() method from the PDB module. When the breakpoint is hit, the code stops executing and you can use the PDB commands to step through the code and see where the exception is being raised.
I hope these suggestions are helpful in debugging the issue. Let me know if you have any further questions.
Thank you Agata, will get back after trying this. I cross checked the valid_signals and saw that SIGINT is mapped to 2 itself. There must be some bitwise operation or some manipulation of signal bits that’s causing this issue. Working on it …
I tried the examine the issue, it’s not related to my platform which is NonStop. I tried Ctrl C on a sample C program while it was in sleep and got an exit status of 130 itself on my platform. I cross checked from the perspective of sample C program and found that behaviour on my platform is similar to Unix.
Then coming to python part even if I execute the command
I am getting an exit status of 9, is it because the parent is killing the child before it handles SIGINT?
I checked the exit status using echo $? command.
Another interesting thing to note is even the command
Is returning a return status of 9.
When I do a simple raise(SIGINT) in my sample C program it is returning a status of 130, so somewhere it is related to CPython that I am getting different status.
You doubt you can compare bash exit status with what is calculated in the subprocess code.
The exit code is 16 bits I think. You have to split that 16 bits into fields to find out what it means.
man 2 waitpid details the macros that are defined to pull apart the wstatus value that has the return code from the dead process.
What you get as wstatus from a call to waitpid is not the same as the value that you can see with bash.
If you read the code is subprocess.py you can see that it uses os.waitpid and does a lot of work calculating the value to put in self.returncode. I see if using os.waitstatus_to_exitcode and other tests.
I recommend that you write two programs in C to investigate what is going on.
One that does the fork/exec of a process and does waitpid so that you can see the full wstatus after you do a normal exit, signal killed exit etc.
The other program, exit-test, that allows you exit in the way you want to test.
Then you can compare with running the same exit-test program using subprocess and compare results.
In this way you are using the OS system calls directly and the values are not being converted in ways that are leading to confusion.
I suggest you run tests on a linux system and see if that matches what non-stop is doing.