homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients Drekin, abarry, eryksun, tim.golden, troyhirni, vstinner
Date 2016年03月11日.13:31:44
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1457703106.3.0.708755021231.issue18597@psf.upfronthosting.co.za>
In-reply-to
Content
Background Discussion
The Windows 10 console uses the condrv.sys device driver, which is set up as follows in the NT namespace:
 C:\>odir \ -r -n con;con*$;cond*
 Directory of \
 Device
 ConDrv <Device>
 Driver
 condrv <Driver>
 GLOBAL??
 CON -> \Device\ConDrv\Console
 CONIN$ -> \Device\ConDrv\CurrentIn
 CONOUT$ -> \Device\ConDrv\CurrentOut
Previously the base console API used an NT LPC port to communicate with the attached console process (i.e. an instance of conhost.exe). There wasn't a real console device. Instead, opening "CON", "CONIN$", or "CONOUT$" was special cased to call OpenConsoleW (undocumented). 
With the new console device driver, opening the DOS "CON" device gets translated to the NT path "\Device\ConDrv\Console", i.e. it opens the file named "Console" on the ConDrv device. 
Opening the Console file returns a handle for a regular kernel File object. To that end, you may have noticed that console handles in Windows 10 are no longer tagged for routing by setting the lower two bits (e.g. 3, 7, 11, etc). For example:
 >>> kernel32.GetStdHandle(STD_INPUT_HANDLE)
 32
 >>> kernel32.DebugBreak()
 (e1c.e20): Break instruction exception - code 80000003 (first chance)
 KERNELBASE!DebugBreak+0x2:
 00007ffa`60280262 cc int 3
 0:000> !handle 32
 Handle 32
 Type File
Previously, all operations on console handles were internally routed to special console functions, such as ReadFile => ReadConsoleA. Thus with the old LPC-based console, a ReadFile basically has the behavior of ReadConsoleA (with the addition of special casing input lines that start with Ctrl+Z). 
The new design scraps a lot of the special-cased code. For example, reading from a console handle in Windows 10 uses a regular NtReadFile system call. So the error it sets, if any at all, depends on translating the NTSTATUS code that's returned by NtReadFile. Let's see what status the console sets here:
 C:\Temp>cdb -xi ld python ccbug.py
 [...]
 ntdll!LdrpDoDebuggerBreak+0x30:
 00007ffb`170de260 cc int 3
 0:000> g
 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25)
 [MSC v.1900 64 bit (AMD64)]
 calling DebugBreak...
 (8d0.62c): Break instruction exception - code 80000003 (first chance)
 KERNELBASE!DebugBreak+0x2:
 00007ffb`13f40262 cc int 3
 0:000> bp ntdll!NtReadFile
 0:000> g
 Breakpoint 0 hit
 ntdll!NtReadFile:
 00007ffb`170b35d0 4c8bd1 mov r10,rcx
 0:000> pt
 ntdll!NtReadFile+0xa:
 00007ffb`170b35da c3 ret
 0:000> r rax
 rax=0000000000000101
The console weirdly returns a success code, STATUS_ALERTED (0x101, "the delay completed because the thread was alerted"), which is why ReadFile doesn't set an error. STATUS_ALERTED is normally returned when an NT wait function gets alerted by NtAlertThread (note that this is not the same as getting alerted by an asynchronous procedure call). For example:
 
 tid = threading.get_ident()
 h = kernel32.OpenThread(MAXIMUM_ALLOWED, 0, tid)
 t = threading.Timer(5, ntdll.NtAlertThread, (h,))
 delay = LARGE_INTEGER(10 * -10**7) # 10 seconds
 t.start()
 r = ntdll.NtDelayExecution(True, byref(delay))
 >>> hex(r)
 '0x101'
NtAlertThread is rarely used because WinAPI wait functions (e.g. SleepEx) automatically restart a wait when the underlying NT wait returns STATUS_ALERTED. 
The ReadConsole implementation has always translated STATUS_ALERTED to ERROR_OPERATION_ABORTED. This still exists in the Windows 10 implementation of ReadConsole. However, the correct error status for this case is STATUS_CANCELLED (0xC0000120, "the I/O request was cancelled"): 
 >>> ntdll.RtlNtStatusToDosError(0xC0000120)
 995
Whoever reimplemented the console IPC using a device driver should have updated the console to return STATUS_CANCELLED when an I/O operation is interrupted by Ctrl+C or Ctrl+Break. Then nothing would need to be special cased.
History
Date User Action Args
2016年03月11日 13:31:46eryksunsetrecipients: + eryksun, vstinner, tim.golden, Drekin, abarry, troyhirni
2016年03月11日 13:31:46eryksunsetmessageid: <1457703106.3.0.708755021231.issue18597@psf.upfronthosting.co.za>
2016年03月11日 13:31:46eryksunlinkissue18597 messages
2016年03月11日 13:31:44eryksuncreate

AltStyle によって変換されたページ (->オリジナル) /