Edgewall Software
Modify

Opened 7 years ago

Closed 6 years ago

#10958 closed defect (fixed)

OSError: [Errno 3] No such process

Reported by: ormandi.matyas@… Owned by: Jun Omae
Priority: high Milestone: 1.0.2
Component: plugin/git Version: 1.0
Severity: major Keywords: cygwin
Cc: Thijs Triemstra Branch:
Release Notes:

Fix an ESRCH error while killing a child process on Cygwin in PyGIT.py.

API Changes:

Description

How to Reproduce

While doing a GET operation on /browser, Trac issued an internal error.

(please provide additional details here)

Request parameters:

{'path': '/'}

User agent: Chrome/23.0.1271.64

System Information

Trac 1.0
Genshi 0.6 (without speedups)
GIT 1.7.9
pysqlite 2.4.1
Python 2.6.8 (unknown, Jun 9 2012, 11:30:32)
[GCC 4.5.3]
setuptools 0.6c11
SQLite 3.7.13
jQuery 1.7.2

Enabled Plugins

Python Traceback

Traceback (most recent call last):
  File "build/bdist.cygwin-1.7.17-i686/egg/trac/web/main.py", line 497, in _dispatch_request
    dispatcher.dispatch(req)
  File "build/bdist.cygwin-1.7.17-i686/egg/trac/web/main.py", line 214, in dispatch
    resp = chosen_handler.process_request(req)
  File "build/bdist.cygwin-1.7.17-i686/egg/trac/versioncontrol/web_ui/browser.py", line 391, in process_request
    dir_data = self._render_dir(req, repos, node, rev, order, desc)
  File "build/bdist.cygwin-1.7.17-i686/egg/trac/versioncontrol/web_ui/browser.py", line 559, in _render_dir
    entries = [entry(n) for n in node.get_entries()
  File "build/bdist.cygwin-1.7.17-i686/egg/tracopt/versioncontrol/git/git_fs.py", line 585, in get_entries
    historian)
  File "/usr/lib/python2.6/contextlib.py", line 23, in __exit__
    self.gen.next()
  File "build/bdist.cygwin-1.7.17-i686/egg/tracopt/versioncontrol/git/PyGIT.py", line 930, in get_historian
    terminate(p[0])
  File "build/bdist.cygwin-1.7.17-i686/egg/tracopt/versioncontrol/git/PyGIT.py", line 58, in terminate
    return terminate_nix(process)
  File "build/bdist.cygwin-1.7.17-i686/egg/tracopt/versioncontrol/git/PyGIT.py", line 54, in terminate_nix
    return os.kill(process.pid, signal.SIGTERM)
OSError: [Errno 3] No such process

Attachments (0)

Change History (8)

comment:1 by Thijs Triemstra, 7 years ago

Cc: Thijs Triemstra added
Component: version control/browserplugin/git

comment:2 by Christian Boos, 6 years ago

Keywords: cygwin added
Milestone: unscheduled

Well, we don't really support Trac on Windows with Cygwin's Python. You're on your own with that setup (PatchWelcome, but make sure the changes don't break the regular Unix platforms).

comment:3 by Jun Omae, 6 years ago

Milestone: unscheduled1.0.2
Owner: set to Jun Omae
Status: newassigned

repos:jomae.git:ticket10958, 5d27bd6d/jomae.git ignores a OSError of ESRCH.

On POSIX platforms, it is able to send signals to the terminated process which has not been waited (zombie process). However, cannot on cygwin.

Linux

$ python
Python 2.4.3 (#1, Jan  9 2013, 06:49:54)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from subprocess import Popen, PIPE
>>> import signal, os
>>> def handler(sig, frame):
...   print 'Caught SIGCHLD\n'
...
>>> signal.signal(signal.SIGCHLD, handler)
0
>>> proc = Popen(('/bin/cat',), stdin=PIPE, stdout=PIPE)
>>> proc.stdin.close()
>>> Caught SIGCHLD


>>> os.kill(proc.pid, signal.SIGTERM)  # Be able to send signals until wait
>>> os.kill(proc.pid, signal.SIGTERM)
>>> os.kill(proc.pid, signal.SIGTERM)
>>> proc.wait()
0
>>> os.kill(proc.pid, signal.SIGTERM)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OSError: [Errno 3] No such process

Cygwin

$ /usr/bin/python
Python 2.7.3 (default, Dec 18 2012, 13:50:09)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from subprocess import Popen, PIPE
>>> import signal, os
>>> def handler(sig, frame):
...   print 'Caught SIGCHLD\n'
...
>>> signal.signal(signal.SIGCHLD, handler)
0
>>> proc = Popen(('/bin/cat',), stdin=PIPE, stdout=PIPE)
>>> proc.stdin.close()
>>>
Caught SIGCHLD

>>> os.kill(proc.pid, signal.SIGTERM)  # Have yet to wait, however, cannot send any signals
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 3] No such process
>>> proc.wait()
0

comment:4 by Christian Boos, 6 years ago

So OK, this ignores the exception, but what happens with the process, will it be left dangling? Wouldn't we better off using terminate_win for that, assuming we can get the appropriate Windows pid from the cygwin pid (cygwin_winpid_to_pid with ctypes? Well, you're the ctypes hacker ;-) ).

in reply to:  4 comment:5 by Christian Boos, 6 years ago

Replying to cboos:

(cygwin_winpid_to_pid

Sorry, got it backwards. Googled a bit more: this one sounds promising:

winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);

(from so:1679337)

in reply to:  4 ; comment:6 by Jun Omae, 6 years ago

Replying to cboos:

So OK, this ignores the exception, but what happens with the process, will it be left dangling?

No, it will be not left dangling, I think. The process is fork/exec'ed from cygwin python. I think that os.kill() correctly works.

>>> proc = Popen(('/bin/cat',), stdin=PIPE, stdout=PIPE)
>>> os.kill(proc.pid, signal.SIGTERM)  # the child is still alive
>>> Caught SIGCHLD                     # ... it terminates

>>> proc.returncode
>>> proc.wait()
-15
>>> proc.returncode
-15
>>> os.kill(proc.pid, signal.SIGTERM)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 3] No such process

Also, I just tried to call ctypes.windll.kernel32.TerminateProcess when cygwin. cygwin_internal works well, however, Python on cygwin doesn't provide ctypes.windll.

in reply to:  6 comment:7 by Christian Boos, 6 years ago

Replying to jomae:

Replying to cboos:

So OK, this ignores the exception, but what happens with the process, will it be left dangling?

No, it will be not left dangling, I think. The process is fork/exec'ed from cygwin python. I think that os.kill() correctly works.

I see. Then I suggest to rephrase the comment like this:

            os.kill(process.pid, signal.SIGTERM) 
        except OSError, e: 
            # If the process has already finished and has not been
            # waited for, killing it raises an ESRCH error on Cygwin

comment:8 by Jun Omae, 6 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Thanks. My patch with your suggestions is committed in [11710-11711].

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jun Omae.
The resolution will be deleted.
to The owner will be changed from Jun Omae to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.