Skip to content
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

subprocess failing in GUI applications on Windows #48155

Closed
twhitema mannequin opened this issue Sep 18, 2008 · 29 comments
Closed

subprocess failing in GUI applications on Windows #48155

twhitema mannequin opened this issue Sep 18, 2008 · 29 comments
Labels
3.8 only security fixes 3.9 only security fixes 3.10 only security fixes OS-windows stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@twhitema
Copy link
Mannequin

twhitema mannequin commented Sep 18, 2008

BPO 3905
Nosy @terryjreedy, @pfmoore, @amauryfa, @tjguk, @benjaminp, @zware, @eryksun, @zooba

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2008-09-18.23:07:01.790>
labels = ['type-bug', '3.8', '3.9', '3.10', 'library', 'OS-windows']
title = 'subprocess failing in GUI applications on Windows'
updated_at = <Date 2021-03-04.15:59:11.568>
user = 'https://bugs.python.org/twhitema'

bugs.python.org fields:

activity = <Date 2021-03-04.15:59:11.568>
actor = 'eryksun'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)', 'Windows']
creation = <Date 2008-09-18.23:07:01.790>
creator = 'twhitema'
dependencies = []
files = []
hgrepos = []
issue_num = 3905
keywords = []
message_count = 27.0
messages = ['73408', '73409', '73420', '73427', '73428', '73433', '73460', '73461', '73463', '73468', '73496', '73514', '73517', '74804', '133002', '133052', '133106', '153234', '220206', '220218', '220219', '245640', '338056', '338066', '338070', '338075', '388098']
nosy_count = 16.0
nosy_names = ['terry.reedy', 'paul.moore', 'amaury.forgeotdarc', 'tim.golden', 'kevinwatters', 'tlesher', 'benjamin.peterson', 'trentm', 'twhitema', 'Weird', 'denversc', 'chn', 'zach.ware', 'eryksun', 'steve.dower', 'borisompol']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'test needed'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue3905'
versions = ['Python 3.8', 'Python 3.9', 'Python 3.10']

@twhitema
Copy link
Mannequin Author

twhitema mannequin commented Sep 18, 2008

I'm getting a 'The handle is invalid' error when using subprocess.Popen
in Python 2.5 (and 2.6). If any of the stdio handles are somehow invalid
or not real io handles (fd is not 0, 1 or 2), and you are not telling
subprocess to PIPE all of the handles, then subprocess throws the
following exception.

The easiest way to reproduce this is using run PythonWin from a Windows
Command Prompt:
C:\Python\Lib\site-packages\pythonwin\Pythonwin.exe
and then use the following 2 subprocess code lines below:

import subprocess
p = subprocess.Popen(["python", "-c", "print 32"], stdin=None,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "C:\Python26\lib\subprocess.py", line 588, in init_
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "C:\Python26\lib\subprocess.py", line 703, in _get_handles
    p2cread = self._make_inheritable(p2cread)
  File "C:\Python26\lib\subprocess.py", line 748, in _make_inheritable
    DUPLICATE_SAME_ACCESS)
WindowsError: [Error 6] The handle is invalid

Specifying PIPE for all subprocess.Popen handles is the only way I've
found to get around this problem:

p = subprocess.Popen(["python", "-c", "print 32"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.close()
p.communicate()
('32\r\n', '')

@twhitema twhitema mannequin added the OS-windows label Sep 18, 2008
@twhitema
Copy link
Mannequin Author

twhitema mannequin commented Sep 18, 2008

This seems to be somewhat related to bpo-1124861:
http://bugs.python.org/issue1124861

@trentm
Copy link
Mannequin

trentm mannequin commented Sep 19, 2008

The failure is in the DuplicateHandle call that subprocess makes on, in
this case, the stdin handle (as returned by
GetStdHandle(STD_INPUT_HANDLE)) call earlier.

Two cases here:

  1. When this is run in a subsystem:windows process (like PythonWin or
    IDLE) that is launched from Windows Explorer (e.g. from a Start Menu
    shortcut or Desktop shortcut) then GetStdHandle(STD_INPUT_HANDLE)
    returns None.

[http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx]

If an application does not have associated standard handles,
such as a service running on an interactive desktop, and has
not redirected them, the return value is NULL.

In this case you don't get the error that Todd described, because the
code path taken in subprocess.py then use CreatePipe for the p2cread
variable on which DuplicateHandle is called.

  1. However, when the subsystem:windows process is launched from the
    cmd.exe shell the GetStdHandle call returns a value -- in Todd's and
    my testing, the value 3.

The code path in subprocess.py then calls DuplicateHandle on this in
Popen._make_inheritable. This fails with traceback Todd posted.

My *guess* at what the problem is stems from this comment in the MSDN
docs on console handles:

[http://msdn.microsoft.com/en-us/library/ms682075(VS.85).aspx]

A process can use the DuplicateHandle function to create a
duplicate console handle that has different access or
inheritability from the original handle. Note, however,
that a process can create a duplicate console handle only
for its own use. This differs from other handle types (such
as file, pipe, or mutex objects), for which DuplicateHandle
can create a duplicate that is valid for a different process.

My guess is that the stdin handle (3) is inherited from the shell
(cmd.exe) and attempting to DuplicateHandle on it violates the clause
that you can on dupe a console handle of your own. I'm not sure of that
though.

Anyone else have more light to shed on this?

If this is the case I'm not sure what a possible or good solution could
be for subprocess.

@jmfauth
Copy link
Mannequin

jmfauth mannequin commented Sep 19, 2008

I do not really know if this is related to this, but I suspect yes.
On my w2k+sp4 box, swiss french, Python 3.0rc1, IDLE does not start or
more precisely it starts by opening the following message box:

Subprocess Startup Error
---------------------------
IDLE's subprocess didn't make connection. Either IDLE can't start a
subprocess or personal firewall software is blocking the connection.

It is certainly neither a firewall issue, nor a tkinter issue (tkinter
applications are working fine.)

No problem with the 3.0b2 realease, 3.0b3: not tested.

@amauryfa
Copy link
Member

jmfauth: please try to run idle from a command prompt:

cd <path_to_python3.0rc1>
python Lib/idlelib/idle.py

Do you see interesting output there?

@jmfauth
Copy link
Mannequin

jmfauth mannequin commented Sep 19, 2008

Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

C:\>cd python30

C:\Python30>python Lib/idlelib/idle.py
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python30\lib\idlelib\run.py", line 76, in main
    sockthread.set_daemon(True)
AttributeError: 'Thread' object has no attribute 'set_daemon'

C:\Python30>

Sorry if I can help here, things like socket and subprocess are not my
cup of tea.

@birkenfeld
Copy link
Member

Benjamin, I think you're responsible.

@birkenfeld
Copy link
Member

There are also instances of set_daemon left in socketserver and
multiprocessing/dummy. How is that possible?

@benjaminp
Copy link
Contributor

The idle problem has already been fixed, and I got the socket server one
in r66520.

@benjaminp benjaminp removed their assignment Sep 20, 2008
@jmfauth
Copy link
Mannequin

jmfauth mannequin commented Sep 20, 2008

Just for information and from an end user perspective.

I have tried to replace the socketserver.py from the original 3.0rc1
distribution by the socketserver.py as proposed by Benjamin Peterson
(r66520).

Script difference (line 568):

        if self.daemon_threads:
            t.daemon = True
        t.start()

and

        if self.daemon_threads:
            t.set_daemon(True)
        t.start()

Unfortunately, no luck, I'm still getting exactly the same error
messages, the msg box and the raised AttributeError:

AttributeError: 'Thread' object has no attribute 'set_daemon'

@birkenfeld
Copy link
Member

Jean-Michel, you'll need to apply the idlelib/run.py patch; replace

    sockthread.set_daemon(True)

with

    sockthread.daemon = True

around line 75.

@twhitema
Copy link
Mannequin Author

twhitema mannequin commented Sep 21, 2008

Uh, the Idle bug reported by Jean-Michel is a completely different bug
(please see the first three messages of this report).

Please re-open this bug, as the subprocess issue I have reported is
still outstanding.

@birkenfeld birkenfeld reopened this Sep 21, 2008
@jmfauth
Copy link
Mannequin

jmfauth mannequin commented Sep 21, 2008

Georg Brandl

Thanks, patch applied on w2k+sp4 box, swiss french, Python 3.0rc1.
IDLE is working fine.

@Weird
Copy link
Mannequin

Weird mannequin commented Oct 15, 2008

Georg Brandl thank you, i was having the same problem, but now is fixed

@denversc
Copy link
Mannequin

denversc mannequin commented Apr 5, 2011

I just re-tested this in cpython trunk at changeset and the issue does not appear to be reproducible.

I first launched IDLE by running "python lib\idlelib\idle.py". Then I entered the following:

Python 3.3a0 (default, Apr  2 2011, 21:55:40) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import sys
>>> sys.getwindowsversion()
sys.getwindowsversion(major=5, minor=1, build=2600, platform=2, service_pack='Service Pack 3')
>>> import subprocess
>>> PIPE = subprocess.PIPE
>>> p = subprocess.Popen(["python", "-c", "print(32)"], stdin=None, stdout=PIPE, stderr=PIPE)
>>> p
<subprocess.Popen object at 0x00F85610>
>>> p.returncode
>>>

Popen() did not raise any exceptions. I also tried in Python 2.7 and the Popen called succeeded there as well. So my inability to reproduce the issue does not necessarily mean that the issue is fixed, but rather that it is likely dependent on the version of Windows on which Python is running.

That being said, the linked issue bpo-1124861 logs what appears to be the same issue and it was fixed in Python 2.6. So maybe I'm just not old enough to have encountered this issue :) Anyways, this issue probably can be closed as either a duplicate or fixed incidentally.

@twhitema
Copy link
Mannequin Author

twhitema mannequin commented Apr 5, 2011

I still see this problem (in Python 2.7.1 and Python 3.1.2).

When testing using idle, you'll need to launch using "pythonw.exe", i.e.:

pythonw.exe lib\idlelib\idle.py

@denversc
Copy link
Mannequin

denversc mannequin commented Apr 6, 2011

Ahh okay. I've reproduced it in trunk at changeset 053bc5ca199b.

As suggested, I ran: PCBuild\pythonw.exe lib\idlelib\idle.py

Python 3.3a0 (default, Apr  2 2011, 21:55:40) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import subprocess
>>> subprocess.Popen(["python", "-c", "print(32)"], stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    subprocess.Popen(["python", "-c", "print(32)"], stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  File "C:\dev\cpython\cpython\lib\subprocess.py", line 732, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "C:\dev\cpython\cpython\lib\subprocess.py", line 903, in _get_handles
    p2cread = self._make_inheritable(p2cread)
  File "C:\dev\cpython\cpython\lib\subprocess.py", line 946, in _make_inheritable
    _subprocess.DUPLICATE_SAME_ACCESS)
WindowsError: [Error 6] The handle is invalid
>>> 

So, the issue is definitely not fixed.

@terryjreedy
Copy link
Member

In 3.2.2, starting IDLE from a Command Prompt, I get the same error as Denver. Starting IDLE 'normally', from the icon, there is no error. So even though Command Prompt detaches pythonw in some way and gives me a new prompt to do something else, there is something different about the pythonw process that trips up subprocess.

Changing ["python", "-c", "print(32)"] to ["notepad"] gives the same result. Running in the interactive interpreted eliminated the error. So does changing stdin=None to stdin=subprocess.PIPE eliminates the error and brings up Notepad, which seems to operate normally. (I am guessing that it ignores stdin, etc.).

I see that that the latter was known in the original post and plausibly diagnosed by Trent Mick, but never fixed because it was not obvious how to do so.

Can the WindowsError be caught in subproccess, and if it is this error (6), follow the alternate patch that is used for NULL returns? Could that cause worse problems that the current situation?

If this is unfixable due to Windows behavior, perhaps we should say something in the doc.

@BreamoreBoy
Copy link
Mannequin

BreamoreBoy mannequin commented Jun 10, 2014

I cannot reproduce this problem with 3.4.1 or 3.5.a0 on Windows 7.

@terryjreedy
Copy link
Member

Mark, you did not specify which of the variations you tried ;-) I reproduce as I said in my last message.

C:\Programs\Python34>pythonw -m idlelib

Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [
>>> import subprocess
>>> p = subprocess.Popen(["python", "-c", "print(32)"], stdin=None,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Traceback (most recent call last):
...
    _winapi.DUPLICATE_SAME_ACCESS)
OSError: [WinError 6] The handle is invalid

Change startup command from pythonw to python, no error, and it runs.
>>> p.communicate()
(b'32\r\n', b'')

@BreamoreBoy
Copy link
Mannequin

BreamoreBoy mannequin commented Jun 11, 2014

*facepalm* looks like I've run it with the wrong exe, sorry about the noise :-(

@borisompol
Copy link
Mannequin

borisompol mannequin commented Jun 22, 2015

Probably the same issue: everything works when called from command line, but when called via a desktop shortcut I get
...
_winapi.DUPLICATE_SAME_ACCESS)
OSError: [WinError 6] The handle is invalid

Changing pythonw to python solved the problem. ...this could be expected behavior. If anyone is interested I can attach my test files.

@terryjreedy
Copy link
Member

I reran test with IDLE started 4 ways:
I am closing this as out of date because the problem seems to have been fixed elsewise.

3.8.0a2+ 32 bit debug python, built today, opened from python icon, then idle started with 'import idlelib.idle'
3.8.0a2 64 bit installed, directly from IDLE icon
3.7.2 python -m idlelib
3.7.2 pythonw -m idlelib

#  and it ran correctly all 4 times.
>>> import subprocess
>>> p = subprocess.Popen(["python", "-c", "print(32)"], stdin=None,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> p.communicate()
(b'32\r\n', b'')

Anyone with the same or similar failure on current Python (now 3.7, 3.8) should open a new issue and give careful details -- release or build, system, startup procedure, and a reproducing example only using stdlib modules (no PythonWin).

@eryksun
Copy link
Contributor

eryksun commented Mar 16, 2019

I am closing this as out of date because the problem seems to have been
fixed elsewise.

This is a problem only in Windows 7, which we should have addressed years ago. It's common enough that we shouldn't leave it as just an unresolved third-party issue. I discussed the problem and suggested a workaround in bpo-25492, which I closed as a duplicate of this issue four years ago.

@eryksun eryksun added 3.7 (EOL) end of life 3.8 only security fixes type-bug An unexpected behavior, bug, or error labels Mar 16, 2019
@terryjreedy
Copy link
Member

Since Win 10 was released a year after Jun 2014, I must have still been on Win 7 when I saw the failure. I believe there have some patches to filenos and subprocess since, but I don't know the relation between filenos and file handles. A current test on a Win 7 machine similar to what I did would still be good. Perhaps it would have been better to reopen bpo-25492, but I am adding the current Windows people nosy here.

@terryjreedy terryjreedy reopened this Mar 16, 2019
@eryksun
Copy link
Contributor

eryksun commented Mar 16, 2019

A current test on a Win 7 machine similar to what I did
would still be good.

Python 3.8 is the last version to support Windows 7 (i.e. NT 6.1). It should get bug fixes through Spring 2021, so we have a couple more years to fix this.

We should constrain the fix to just older versions of Windows (prior to 6.2) and the classic console file handles (i.e. the lower 2 bits are set such as 3, 7, 11) that they use. Otherwise a bad standard handle should fail the call.

@eryksun
Copy link
Contributor

eryksun commented Mar 4, 2021

For whatever the reason and Windows version, it's still the case that _get_handles() should work around any bad standard handles in the current process. In bpo-25492, I suggested checking os.get_handle_inheritable(). That's too permissive. It should require a valid file handle, checked via _winapi.GetFileType(). For example:

    if stdin is None:
        p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)
        if p2cread is not None:
            try:
                _winapi.GetFileType(p2cread)
            except OSError:
                p2cread = None

@eryksun eryksun added stdlib Python modules in the Lib dir 3.9 only security fixes 3.10 only security fixes and removed 3.7 (EOL) end of life labels Mar 4, 2021
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@erlend-aasland
Copy link
Contributor

Python 3.8 is the last version to support Windows 7 (i.e. NT 6.1). It should get bug fixes through Spring 2021, so we have a couple more years to fix this.

Python 3.8 and 3.9 are now in security-only mode. Suggesting to close this.

@erlend-aasland erlend-aasland added the pending The issue will be closed if no feedback is provided label May 20, 2022
@AA-Turner
Copy link
Member

Closing per Erlend, it's been several days with no comments to the contrary.

A

@AA-Turner AA-Turner removed the pending The issue will be closed if no feedback is provided label May 28, 2022
@erlend-aasland erlend-aasland closed this as not planned Won't fix, can't repro, duplicate, stale May 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.8 only security fixes 3.9 only security fixes 3.10 only security fixes OS-windows stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

7 participants