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 amoffat
Recipients amoffat, loewis, ned.deily
Date 2012年09月11日.04:19:28
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1347337170.8.0.208818111589.issue15898@psf.upfronthosting.co.za>
In-reply-to
Content
Below I attached a script that reproduces the behavior of an assertion error on a specific fork condition for a process with a pty. Here are the results
Xubuntu x64:
 Python 2.7, parent_close_slave_before_child_write = False: WORKS
 Python 2.7, parent_close_slave_before_child_write = True: WORKS
 Python 3.2, parent_close_slave_before_child_write = False: WORKS
 Python 3.2, parent_close_slave_before_child_write = True: WORKS
Mac OSX 10.7.2:
 Python 2.7, parent_close_slave_before_child_write = False: WORKS
 Python 2.7, parent_close_slave_before_child_write = True: WORKS
 Python 3.2, parent_close_slave_before_child_write = False: >> FAILS <<
 Python 3.2, parent_close_slave_before_child_write = True: WORKS
Here's dtruss -f for python 2.7 and 3.0 on Mac OSX:
2.7, parent_close_slave_before_child_write = False (WORKS)
 PID/THRD SYSCALL(args) = return
 356/0xc4a: open_nocancel("/dev/ptmx0円", 0x20002, 0x0) = 3 0
 356/0xc4a: ioctl(0x3, 0x20007454, 0xFFFFFFFF) = 0 0
 356/0xc4a: ioctl(0x3, 0x20007452, 0x0) = 0 0
 356/0xc4a: ioctl(0x3, 0x40807453, 0x10041AD20) = 0 0
 356/0xc4a: stat64("/dev/ttys0030円", 0x7FFF5FBFF030, 0x0) = 0 0
 356/0xc4a: open_nocancel("/dev/ttys0030円", 0x20002, 0x0) = 4 0
 356/0xc4a: fork() = 362 0
 362/0xc61: fork() = 0 0
 362/0xc61: thread_selfid(0x100420BE0, 0x3, 0x1) = 3169 0
 362/0xc61: getpid(0x100420BE0, 0x3, 0x0) = 362 0
 362/0xc61: select(0x0, 0x0, 0x0, 0x0, 0x7FFF5FBFF3C0) = 0 0
 362/0xc61: setsid(0x0, 0x0, 0x1001A7B40) = 362 0
 362/0xc61: close(0x3) = 0 0
 362/0xc61: dup2(0x4, 0x0, 0x0) = 0 0
 362/0xc61: dup2(0x4, 0x1, 0x0) = 1 0
 362/0xc61: dup2(0x4, 0x2, 0x0) = 2 0
 362/0xc61: getrlimit(0x1008, 0x7FFF5FBFF3D0, 0x0) = 0 0
 ... close range ...
 362/0xc61: ioctl(0x1, 0x40487413, 0x7FFF5FBFF360) = 0 0
 362/0xc61: fstat64(0x1, 0x7FFF5FBFF2D0, 0x0) = 0 0
 362/0xc61: open_nocancel("/dev/0円", 0x100004, 0x0) = 3 0
 362/0xc61: fcntl_nocancel(0x3, 0x2, 0x1) = 0 0
 362/0xc61: fstatfs64(0x3, 0x7FFF5FBFE7B0, 0x0) = 0 0
 362/0xc61: getdirentries64(0x3, 0x1010AB600, 0x1000) = 3080 0
 ... lots of lstat64 ...
 362/0xc61: close_nocancel(0x3) = 0 0
 362/0xc61: open("/dev/ttys0030円", 0x2, 0x1FF) = 3 0
 362/0xc61: close(0x3) = 0 0
 362/0xc61: write(0x1, "testing0円", 0x7) = 7 0
 362/0xc61: close(0x1) = 0 0
 356/0xc4a: select(0x0, 0x0, 0x0, 0x0, 0x7FFF5FBFF3C0) = 0 0
 356/0xc4a: close(0x4) = 0 0
 356/0xc4a: read(0x3, "testing0円", 0x400) = 7 0
 356/0xc4a: write_nocancel(0x1, "'testing'\n0円", 0xA) = 10 0
 356/0xc4a: wait4(0x16A, 0x7FFF5FBFF3D4, 0x0) = 362 0
 356/0xc4a: sigaction(0x2, 0x7FFF5FBFF800, 0x7FFF5FBFF830) = 0 0
3.0, parent_close_slave_before_child_write = False (FAILS)
 PID/THRD SYSCALL(args) = return
 385/0xe53: open_nocancel("/dev/ptmx0円", 0x20002, 0xD15EB8) = 3 0
 385/0xe53: ioctl(0x3, 0x20007454, 0xBFFFF1BC) = 0 0
 385/0xe53: ioctl(0x3, 0x20007452, 0xBFFFF1BC) = 0 0
 385/0xe53: ioctl(0x3, 0x40807453, 0x64F220) = 0 0
 385/0xe53: stat64("/dev/ttys0030円", 0xBFFFF164, 0x64F220) = 0 0
 385/0xe53: open_nocancel("/dev/ttys0030円", 0x20002, 0x0) = 4 0
 385/0xe53: fork() = 389 0
 389/0xe5c: fork() = 0 0
 389/0xe5c: thread_selfid(0x0, 0x0, 0x0) = 3676 0
 389/0xe5c: getpid(0x0, 0x0, 0x0) = 389 0
 389/0xe5c: select_nocancel(0x0, 0x0, 0x0) = 0 0
 389/0xe5c: setsid(0x0, 0x0, 0x0) = 389 0
 389/0xe5c: close_nocancel(0x3) = 0 0
 389/0xe5c: dup2(0x4, 0x0, 0x0) = 0 0
 389/0xe5c: dup2(0x4, 0x1, 0x0) = 1 0
 389/0xe5c: dup2(0x4, 0x2, 0x0) = 2 0
 389/0xe5c: getrlimit(0x8, 0xBFFFF46C, 0x0) = 0 0
 ... close range ...
 389/0xe5c: ioctl(0x1, 0x402C7413, 0xBFFFF410) = 0 0
 389/0xe5c: fstat64(0x1, 0xBFFFF3A4, 0xBFFFF410) = 0 0
 389/0xe5c: open_nocancel("/dev/0円", 0x100004, 0xBFFFE968) = 3 0
 389/0xe5c: fcntl_nocancel(0x3, 0x2, 0x1) = 0 0
 389/0xe5c: fstatfs64(0x3, 0xBFFFE8D8, 0x1) = 0 0
 389/0xe5c: getdirentries64(0x3, 0x10DFC00, 0x1000) = 3080 0
 ... lots of lstat64 ...
 389/0xe5c: close_nocancel(0x3) = 0 0
 389/0xe5c: open_nocancel("/dev/ttys0030円", 0x20002, 0x0) = 3 0
 389/0xe5c: close_nocancel(0x3) = 0 0
 389/0xe5c: write_nocancel(0x1, "testing0円", 0x7) = 7 0
 389/0xe5c: close_nocancel(0x1) = 0 0
 385/0xe53: select_nocancel(0x0, 0x0, 0x0) = 0 0
 385/0xe53: close_nocancel(0x4) = 0 0
 385/0xe53: read_nocancel(0x3, "0円", 0x400) = 0 0
 385/0xe53: write_nocancel(0x1, "b''\n0円", 0x4) = 4 0
 385/0xe53: wait4_nocancel(0x185, 0xBFFFF474, 0x0) = 389 0
 385/0xe53: sigaction(0x2, 0xBFFFF800, 0xBFFFF838) = 0 0
 385/0xe53: madvise(0xDA0000, 0x20000, 0x9) = 0 0
 385/0xe53: madvise(0xDC0000, 0x20000, 0x9) = 0 0
 385/0xe53: madvise(0xD80000, 0x20000, 0x9) = 0 0
2.7, parent_close_slave_before_child_write = True (WORkS)
 PID/THRD SYSCALL(args) = return
 363/0xcab: open_nocancel("/dev/ptmx0円", 0x20002, 0x0) = 3 0
 363/0xcab: ioctl(0x3, 0x20007454, 0xFFFFFFFF) = 0 0
 363/0xcab: ioctl(0x3, 0x20007452, 0x0) = 0 0
 363/0xcab: ioctl(0x3, 0x40807453, 0x10041AD20) = 0 0
 363/0xcab: stat64("/dev/ttys0030円", 0x7FFF5FBFF030, 0x0) = 0 0
 363/0xcab: open_nocancel("/dev/ttys0030円", 0x20002, 0x0) = 4 0
 363/0xcab: fork() = 368 0
 368/0xcb5: fork() = 0 0
 368/0xcb5: thread_selfid(0x100420BE0, 0x3, 0x1) = 3253 0
 368/0xcb5: getpid(0x100420BE0, 0x3, 0x0) = 368 0
 363/0xcab: select(0x0, 0x0, 0x0, 0x0, 0x7FFF5FBFF3C0) = 0 0
 363/0xcab: close(0x4) = 0 0
 368/0xcb5: select(0x0, 0x0, 0x0, 0x0, 0x7FFF5FBFF3C0) = 0 0
 368/0xcb5: setsid(0x0, 0x0, 0x1001A7B40) = 368 0
 368/0xcb5: close(0x3) = 0 0
 368/0xcb5: dup2(0x4, 0x0, 0x0) = 0 0
 368/0xcb5: dup2(0x4, 0x1, 0x0) = 1 0
 368/0xcb5: dup2(0x4, 0x2, 0x0) = 2 0
 368/0xcb5: getrlimit(0x1008, 0x7FFF5FBFF3D0, 0x0) = 0 0
 ... close range ...
 368/0xcb5: ioctl(0x1, 0x40487413, 0x7FFF5FBFF360) = 0 0
 368/0xcb5: fstat64(0x1, 0x7FFF5FBFF2D0, 0x0) = 0 0
 368/0xcb5: open_nocancel("/dev/0円", 0x100004, 0x0) = 3 0
 368/0xcb5: fcntl_nocancel(0x3, 0x2, 0x1) = 0 0
 368/0xcb5: fstatfs64(0x3, 0x7FFF5FBFE7B0, 0x0) = 0 0
 368/0xcb5: getdirentries64(0x3, 0x1010AB600, 0x1000) = 3080 0
 ... lots of lstat64 ...
 368/0xcb5: close_nocancel(0x3) = 0 0
 368/0xcb5: open("/dev/ttys0030円", 0x2, 0x1FF) = 3 0
 368/0xcb5: close(0x3) = 0 0
 368/0xcb5: write(0x1, "testing0円", 0x7) = 7 0
 368/0xcb5: close(0x1) = 0 0
 363/0xcab: read(0x3, "testing0円", 0x400) = 7 0
 363/0xcab: write_nocancel(0x1, "'testing'\n0円", 0xA) = 10 0
 363/0xcab: wait4(0x170, 0x7FFF5FBFF3D4, 0x0) = 368 0
 363/0xcab: sigaction(0x2, 0x7FFF5FBFF800, 0x7FFF5FBFF830) = 0 0
3.0, parent_close_slave_before_child_write = True (WORkS)
 PID/THRD SYSCALL(args) = return
 393/0xed3: open_nocancel("/dev/ptmx0円", 0x20002, 0xD15EB8) = 3 0
 393/0xed3: ioctl(0x3, 0x20007454, 0xBFFFF1BC) = 0 0
 393/0xed3: ioctl(0x3, 0x20007452, 0xBFFFF1BC) = 0 0
 393/0xed3: ioctl(0x3, 0x40807453, 0x64F220) = 0 0
 393/0xed3: stat64("/dev/ttys0030円", 0xBFFFF164, 0x64F220) = 0 0
 393/0xed3: open_nocancel("/dev/ttys0030円", 0x20002, 0x0) = 4 0
 393/0xed3: fork() = 399 0
 399/0xee3: fork() = 0 0
 399/0xee3: thread_selfid(0x0, 0x0, 0x0) = 3811 0
 399/0xee3: getpid(0x0, 0x0, 0x0) = 399 0
 393/0xed3: select_nocancel(0x0, 0x0, 0x0) = 0 0
 393/0xed3: close_nocancel(0x4) = 0 0
 399/0xee3: select_nocancel(0x0, 0x0, 0x0) = 0 0
 399/0xee3: setsid(0x0, 0x0, 0x0) = 399 0
 399/0xee3: close_nocancel(0x3) = 0 0
 399/0xee3: dup2(0x4, 0x0, 0x0) = 0 0
 399/0xee3: dup2(0x4, 0x1, 0x0) = 1 0
 399/0xee3: dup2(0x4, 0x2, 0x0) = 2 0
 399/0xee3: getrlimit(0x8, 0xBFFFF46C, 0x0) = 0 0
 ... close range ...
 399/0xee3: ioctl(0x1, 0x402C7413, 0xBFFFF410) = 0 0
 399/0xee3: fstat64(0x1, 0xBFFFF3A4, 0xBFFFF410) = 0 0
 399/0xee3: open_nocancel("/dev/0円", 0x100004, 0xBFFFE968) = 3 0
 399/0xee3: fcntl_nocancel(0x3, 0x2, 0x1) = 0 0
 399/0xee3: fstatfs64(0x3, 0xBFFFE8D8, 0x1) = 0 0
 399/0xee3: getdirentries64(0x3, 0x10DFC00, 0x1000) = 3080 0
 ... lots of lstat64 ...
 399/0xee3: close_nocancel(0x3) = 0 0
 399/0xee3: open_nocancel("/dev/ttys0030円", 0x20002, 0x0) = 3 0
 399/0xee3: close_nocancel(0x3) = 0 0
 399/0xee3: write_nocancel(0x1, "testing0円", 0x7) = 7 0
 399/0xee3: close_nocancel(0x1) = 0 0
 393/0xed3: read_nocancel(0x3, "testing0円", 0x400) = 7 0
 393/0xed3: write_nocancel(0x1, "b'testing'\n0円", 0xB) = 11 0
 393/0xed3: wait4_nocancel(0x18F, 0xBFFFF474, 0x0) = 399 0
 393/0xed3: sigaction(0x2, 0xBFFFF800, 0xBFFFF838) = 0 0
 393/0xed3: madvise(0xDA0000, 0x20000, 0x9) = 0 0
 393/0xed3: madvise(0xDC0000, 0x20000, 0x9) = 0 0
 393/0xed3: madvise(0xD80000, 0x20000, 0x9) = 0 0
-----------
import os
import pty
import resource
import signal
import tty
import time
import sys
PY3 = sys.version_info.major == 3
if PY3: raw_input = input
# change this to False for failure on py3
parent_close_slave_before_child_write = True
print("pid: %d" % os.getpid())
raw_input("hit enter when 'dtruss -f' is ready> ")
send_from_child = "testing123".encode()
master, slave = pty.openpty()
pid = os.fork()
# child process
if pid == 0:
 if parent_close_slave_before_child_write: time.sleep(2)
 else: time.sleep(1)
 os.setsid()
 os.close(master)
 os.dup2(slave, 0)
 os.dup2(slave, 1)
 os.dup2(slave, 2)
 max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0]
 os.closerange(3, max_fd)
 # make controlling terminal. taken from pty.fork
 tmp_fd = os.open(os.ttyname(1), os.O_RDWR)
 os.close(tmp_fd)
 os.write(1, send_from_child)
 os.close(1)
 os._exit(255)
# parent process
else:
 if parent_close_slave_before_child_write: time.sleep(1)
 else: time.sleep(2)
 os.close(slave)
 actual_output = os.read(master, 1024)
 os.waitpid(pid, 0)
 assert(actual_output == send_from_child)
 print("correct output")
History
Date User Action Args
2012年09月11日 04:19:31amoffatsetrecipients: + amoffat, loewis, ned.deily
2012年09月11日 04:19:30amoffatsetmessageid: <1347337170.8.0.208818111589.issue15898@psf.upfronthosting.co.za>
2012年09月11日 04:19:30amoffatlinkissue15898 messages
2012年09月11日 04:19:28amoffatcreate

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