aboutsummaryrefslogtreecommitdiffstats
path: root/test/src/process-tests.el
diff options
context:
space:
mode:
authorPhilipp Stephani2020-12-30 23:43:07 +0100
committerPhilipp Stephani2020-12-31 00:18:02 +0100
commit8bc85d46cc9214a531f2d2ecb3f5fb48af8105a6 (patch)
tree346a7c64ac0b6a78eacdeb69b73a446d33d87266 /test/src/process-tests.el
parentf43f1e32e92ef341077b4ffdfdd743b1a6d9d284 (diff)
downloademacs-8bc85d46cc9214a531f2d2ecb3f5fb48af8105a6.tar.gz
emacs-8bc85d46cc9214a531f2d2ecb3f5fb48af8105a6.zip
Manually limit file descriptors that we select on to FD_SETSIZE.
This works even if another thread or process resets the resource limit for open file descriptors, e.g., using 'prlimit' on GNU/Linux. * src/process.c (create_process, create_pty, Fmake_pipe_process) (Fmake_serial_process, connect_network_socket) (server_accept_connection): Limit file descriptors to FD_SETSIZE. * test/src/process-tests.el (process-tests--with-raised-rlimit): New helper macro. (process-tests--fd-setsize-test): Rename from 'process-tests--with-many-pipes'. Increase resource limit during test if possible. (process-tests/fd-setsize-no-crash/make-process) (process-tests/fd-setsize-no-crash/make-pipe-process) (process-tests/fd-setsize-no-crash/make-network-process) (process-tests--new-pty): Rename callers.
Diffstat (limited to 'test/src/process-tests.el')
-rw-r--r--test/src/process-tests.el100
1 files changed, 71 insertions, 29 deletions
diff --git a/test/src/process-tests.el b/test/src/process-tests.el
index 590f72f9b03..eee8636067c 100644
--- a/test/src/process-tests.el
+++ b/test/src/process-tests.el
@@ -426,11 +426,52 @@ add some process objects to VAR."
426 ,(macroexp-progn body) 426 ,(macroexp-progn body)
427 (mapc #'delete-process ,var)))) 427 (mapc #'delete-process ,var))))
428 428
429(defmacro process-tests--with-many-pipes (&rest body) 429(defmacro process-tests--with-raised-rlimit (&rest body)
430 "Generate lots of pipe processes. 430 "Evaluate BODY using a higher limit for the number of open files.
431Attempt to set the resource limit for the number of open files
432temporarily to the highest possible value."
433 (declare (indent 0) (debug t))
434 (let ((prlimit (make-symbol "prlimit"))
435 (soft (make-symbol "soft"))
436 (hard (make-symbol "hard"))
437 (pid-arg (make-symbol "pid-arg")))
438 `(let ((,prlimit (executable-find "prlimit"))
439 (,pid-arg (format "--pid=%d" (emacs-pid)))
440 (,soft nil) (,hard nil))
441 (cl-flet ((set-limit
442 (value)
443 (cl-check-type value natnum)
444 (when ,prlimit
445 (call-process ,prlimit nil nil nil
446 ,pid-arg
447 (format "--nofile=%d:" value)))))
448 (when ,prlimit
449 (with-temp-buffer
450 (when (eql (call-process ,prlimit nil t nil
451 ,pid-arg "--nofile"
452 "--raw" "--noheadings"
453 "--output=SOFT,HARD")
454 0)
455 (goto-char (point-min))
456 (when (looking-at (rx (group (+ digit)) (+ blank)
457 (group (+ digit)) ?\n))
458 (setq ,soft (string-to-number
459 (match-string-no-properties 1))
460 ,hard (string-to-number
461 (match-string-no-properties 2))))))
462 (and ,soft ,hard (< ,soft ,hard)
463 (set-limit ,hard)))
464 (unwind-protect
465 ,(macroexp-progn body)
466 (when ,soft (set-limit ,soft)))))))
467
468(defmacro process-tests--fd-setsize-test (&rest body)
469 "Run BODY as a test for FD_SETSIZE overflow.
431Try to generate pipe processes until we are close to the 470Try to generate pipe processes until we are close to the
432FD_SETSIZE limit. Within BODY, only a small number of file 471FD_SETSIZE limit. Within BODY, only a small number of file
433descriptors should still be available." 472descriptors should still be available. Furthermore, raise the
473maximum number of open files in the Emacs process above
474FD_SETSIZE."
434 (declare (indent 0) (debug t)) 475 (declare (indent 0) (debug t))
435 (let ((process (make-symbol "process")) 476 (let ((process (make-symbol "process"))
436 (processes (make-symbol "processes")) 477 (processes (make-symbol "processes"))
@@ -440,28 +481,29 @@ descriptors should still be available."
440 ;; MS-Windows we artificially limit FD_SETSIZE to 64, see the 481 ;; MS-Windows we artificially limit FD_SETSIZE to 64, see the
441 ;; commentary in w32proc.c. 482 ;; commentary in w32proc.c.
442 (fd-setsize (if (eq system-type 'windows-nt) 64 1024))) 483 (fd-setsize (if (eq system-type 'windows-nt) 64 1024)))
443 `(process-tests--with-buffers ,buffers 484 `(process-tests--with-raised-rlimit
444 (process-tests--with-processes ,processes 485 (process-tests--with-buffers ,buffers
445 ;; First, allocate enough pipes to definitely exceed the 486 (process-tests--with-processes ,processes
446 ;; FD_SETSIZE limit. 487 ;; First, allocate enough pipes to definitely exceed the
447 (cl-loop for i from 1 to ,(1+ fd-setsize) 488 ;; FD_SETSIZE limit.
448 for ,buffer = (generate-new-buffer 489 (cl-loop for i from 1 to ,(1+ fd-setsize)
449 (format " *pipe %d*" i)) 490 for ,buffer = (generate-new-buffer
450 do (push ,buffer ,buffers) 491 (format " *pipe %d*" i))
451 for ,process = (process-tests--ignore-EMFILE 492 do (push ,buffer ,buffers)
452 (make-pipe-process 493 for ,process = (process-tests--ignore-EMFILE
453 :name (format "pipe %d" i) 494 (make-pipe-process
454 :buffer ,buffer 495 :name (format "pipe %d" i)
455 :coding 'no-conversion 496 :buffer ,buffer
456 :noquery t)) 497 :coding 'no-conversion
457 while ,process 498 :noquery t))
458 do (push ,process ,processes)) 499 while ,process
459 (unless (cddr ,processes) 500 do (push ,process ,processes))
460 (ert-fail "Couldn't allocate enough pipes")) 501 (unless (cddr ,processes)
461 ;; Delete two pipes to test more edge cases. 502 (ert-fail "Couldn't allocate enough pipes"))
462 (delete-process (pop ,processes)) 503 ;; Delete two pipes to test more edge cases.
463 (delete-process (pop ,processes)) 504 (delete-process (pop ,processes))
464 ,@body)))) 505 (delete-process (pop ,processes))
506 ,@body)))))
465 507
466(defmacro process-tests--with-temp-file (var &rest body) 508(defmacro process-tests--with-temp-file (var &rest body)
467 "Bind VAR to the name of a new regular file and evaluate BODY. 509 "Bind VAR to the name of a new regular file and evaluate BODY.
@@ -502,7 +544,7 @@ FD_SETSIZE file descriptors (Bug#24325)."
502 (skip-unless sleep) 544 (skip-unless sleep)
503 (dolist (conn-type '(pipe pty)) 545 (dolist (conn-type '(pipe pty))
504 (ert-info ((format "Connection type `%s'" conn-type)) 546 (ert-info ((format "Connection type `%s'" conn-type))
505 (process-tests--with-many-pipes 547 (process-tests--fd-setsize-test
506 (process-tests--with-processes processes 548 (process-tests--with-processes processes
507 ;; Start processes until we exhaust the file descriptor 549 ;; Start processes until we exhaust the file descriptor
508 ;; set size. We assume that each process requires at 550 ;; set size. We assume that each process requires at
@@ -538,7 +580,7 @@ FD_SETSIZE file descriptors (Bug#24325)."
538 "Check that Emacs doesn't crash when trying to use more than 580 "Check that Emacs doesn't crash when trying to use more than
539FD_SETSIZE file descriptors (Bug#24325)." 581FD_SETSIZE file descriptors (Bug#24325)."
540 (with-timeout (60 (ert-fail "Test timed out")) 582 (with-timeout (60 (ert-fail "Test timed out"))
541 (process-tests--with-many-pipes 583 (process-tests--fd-setsize-test
542 (process-tests--with-buffers buffers 584 (process-tests--with-buffers buffers
543 (process-tests--with-processes processes 585 (process-tests--with-processes processes
544 ;; Start processes until we exhaust the file descriptor set 586 ;; Start processes until we exhaust the file descriptor set
@@ -580,7 +622,7 @@ FD_SETSIZE file descriptors (Bug#24325)."
580 :coding 'no-conversion 622 :coding 'no-conversion
581 :noquery t))) 623 :noquery t)))
582 (push server processes) 624 (push server processes)
583 (process-tests--with-many-pipes 625 (process-tests--fd-setsize-test
584 ;; Start processes until we exhaust the file descriptor 626 ;; Start processes until we exhaust the file descriptor
585 ;; set size. We assume that each process requires at 627 ;; set size. We assume that each process requires at
586 ;; least one file descriptor. 628 ;; least one file descriptor.
@@ -627,7 +669,7 @@ FD_SETSIZE file descriptors (Bug#24325)."
627 (should tty-name) 669 (should tty-name)
628 (should (file-exists-p tty-name)) 670 (should (file-exists-p tty-name))
629 (push tty-name tty-names))) 671 (push tty-name tty-names)))
630 (process-tests--with-many-pipes 672 (process-tests--fd-setsize-test
631 (process-tests--with-processes processes 673 (process-tests--with-processes processes
632 (process-tests--with-buffers buffers 674 (process-tests--with-buffers buffers
633 (dolist (tty-name tty-names) 675 (dolist (tty-name tty-names)