Skip to content

GitLab

    • GitLab: the DevOps platform
    • Explore GitLab
    • Install GitLab
    • How GitLab compares
    • Get started
    • GitLab docs
    • GitLab Learn
  • Pricing
  • Talk to an expert
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
    • Menu
    Projects Groups Snippets
  • Get a free trial
  • Sign up
  • Login
  • Sign in / Register
  • E ECL
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 195
    • Issues 195
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
    • Requirements
  • Merge requests 2
    • Merge requests 2
  • Deployments
    • Deployments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • Code review
    • Insights
    • Issue
    • Repository
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar

GitLab 15.0 is launching on May 22! This version brings many exciting improvements, but also removes deprecated features and introduces breaking changes that may impact your workflow. To see what is being deprecated and removed, please visit Breaking changes in 15.0 and Deprecations.

  • Embeddable Common-Lisp
  • ECL
  • Issues
  • #273
Closed
Open
Created Aug 04, 2016 by Elias Pipping@epippingContributor

Sleeping process not reported as sleeping

Turning my email into an issue

I’m trying to find out how different lisp compilers handle external processes(*). As a part of that, I’ve created a short piece of code that launches an external process, sends it SIGSTOP, asks its about its well-being, and allows its to go about its business again by sending SIGCONT.

I would expect that ext:external-process-status consequently reports

  1. :running before SIGSTOP is sent
  2. then :stopped
  3. then :running or :resumed again once SIGCONT was received
  4. and finally :exited.

Indeed, that is what ps would do if you ran it on the command line (so I’ve added that to the example for comparison). Here’s the output of my script:

internal status: RUNNING (expected: running)
internal status: RUNNING (expected: stopped)
internal status: RUNNING (expected: running/resumed)
internal status: EXITED (expected: exited)

My expectations aren’t met in (2): Even though according to the ecl manual the status of a process can be :stopped, and the process is clearly stopped, it is not reported as such.

So I’d like to ask: Is this a bug or intentional?

(*) I’ve already sent very similar messages to openmcl-devel and sbcl-devel.

Here’s the updated script that I used (which now sends SIGSTOP/SIGCONT repeatedly:

;; CMUCL: make sure to use a version >21b (not yet released as of 2017-94-04)
;;        because of https://gitlab.common-lisp.net/cmucl/cmucl/issues/26
;; ECL: make sure to use a version >16.1.3 (not yet released as of 2017-09-04)
;;      because of https://gitlab.com/embeddable-common-lisp/ecl/issues/273
#+clozure (use-package :ccl)
#+sbcl (use-package :sb-ext)
#+cmu (use-package :ext)
#+mkcl (use-package :mk-ext)

#+clozure (setf (fdefinition 'process-output) #'external-process-output-stream)
#+ecl (setf (fdefinition 'process-output) #'ext:external-process-output)

(defun my-run-program (&rest rest)
  #+ecl (nth-value 2 (apply #'ext:run-program rest))
  #+mkcl (nth-value 1 (apply #'mk-ext:run-program rest))
  #-(or ecl mkcl) (apply #'run-program rest))

(defconstant +sigstop+
  #+clozure (symbol-value (read-from-string "#$SIGSTOP"))
  #+cmu unix:sigstop
  #+ecl ext:+sigstop+
  #+sbcl (progn (require :sb-posix)
                (symbol-value (find-symbol (symbol-name :sigstop)
                                           (find-package :sb-posix))))
  #-(or clozure cmu ecl sbcl) (or #+darwin 17 #-darwin 19)) ; FIXME
(defconstant +sigtstp+
  #+clozure (symbol-value (read-from-string "#$SIGTSTP"))
  #+cmu unix:sigtstp
  #+ecl ext:+sigtstp+
  #+sbcl (progn (require :sb-posix)
                (symbol-value (find-symbol (symbol-name :sigtstp)
                                           (find-package :sb-posix))))
  #-(or clozure cmu ecl sbcl) (or #+darwin 18 #-darwin 20)) ; FIXME
(defconstant +sigcont+
  #+clozure (symbol-value (read-from-string "#$SIGCONT"))
  #+cmu unix:sigcont
  #+ecl ext:+sigcont+
  #+sbcl (progn (require :sb-posix)
                (symbol-value (find-symbol (symbol-name :sigcont)
                                           (find-package :sb-posix))))
  #-(or clozure cmu ecl sbcl) (or #+darwin 19 #-darwin 18)) ; FIXME

(defun internal-status (process)
  #+clozure (external-process-status process)
  #+(or sbcl cmu) (process-status process)
  #+ecl (ext:external-process-status process)
  #+mkcl (mk-ext:process-status process))

(defun external-kill (pid signal)
  (my-run-program "/usr/bin/env" (list "kill"
                                    (format nil "-~a" signal)
                                    (format nil "~a" pid))))

(defun get-pid (process)
  #+clozure (ccl::external-process-pid process)
  #+ecl (ext:external-process-pid process)
  #+(or sbcl cmu) (process-pid process)
  #+mkcl (mkcl:process-id process))

(let* ((p (my-run-program "/bin/sleep" '("5") :wait nil))
       (pid (get-pid p)))
  (format t "internal status: ~a (expected: running)~%" (internal-status p))

  (external-kill pid +sigstop+)
  (sleep 1)
  (format t "internal status: ~a (expected: stopped)~%" (internal-status p))

  (external-kill pid +sigcont+)
  (sleep 1)
  (format t "internal status: ~a (expected: running/resumed)~%" (internal-status p))

  (external-kill pid +sigstop+)
  (sleep 1)
  (format t "internal status: ~a (expected: stopped)~%" (internal-status p))

  (external-kill pid +sigcont+)
  (sleep 1)
  (format t "internal status: ~a (expected: running/resumed)~%" (internal-status p))
  
  (sleep 5)
  (format t "internal status: ~a (expected: exited)~%" (internal-status p)))

Update:

The fact that sleeping processes are not reported at all appears to be down to the fact that the line

waitpid(ecl_to_fix(pid), &code_int, Null(wait)? WNOHANG : 0)

from ecl_waitpid defined at src/c/unixsys.d:242 does not contain WUNTRACED. The fix is not as easy as adding WUNTRACED, however. Such a change turns running/running/running/exited into running/stopped/stopped/stopped which is an improvement but still not correct.

Edited Sep 04, 2017 by Elias Pipping
Assignee
Assign to
Time tracking