bug#33016: 26.1; (make-process ...) doesn't signal an error, when executable given as absolute Windows path does not exist

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#33016: 26.1; (make-process ...) doesn't signal an error, when executable given as absolute Windows path does not exist

Klaus-Dieter Bauer
The error-handling of `make-process' for a non-existents
executable is inconsistent between invocation as a command
(on PATH) and invocation as a full path.

To reproduce, start `emacs -Q'.

Entering

    M-x eval-expression RET
      (make-process :name "test" :command '("No Such Command"))

will bring up the debugger with 

    (file-missing "Searching for program" "No such file or directory" "nosuchcommand")

However, entering

    M-x eval-expression RET 
      (make-process :name "test" :command '("c:/No Such Command"))

will merely display in the echo-area message:

    eval: Spawning child process: Invalid argument

I stumbled upon this when debugging a quick-and-dirty
script, that called a program by absolute path. When a new
version of the program changed the name of the executable
(tex2lyx2.3 -> tex2lyx), this issue occurred, and hindered
debugging the problem.

The wording of the message might indicate a 
Windows-specific issue.

regards, Klaus



In GNU Emacs 26.1 (build 1, x86_64-w64-mingw32)
 of 2018-05-30 built on CIRROCUMULUS
Repository revision: 07f8f9bc5a51f5aa94eb099f3e15fbe0c20ea1ea
Windowing system distributor 'Microsoft Corp.', version 10.0.17134
Recent messages:
(#<process test<1>> #<process test>)
Quit
Entering debugger...
Back to top level
eval: Spawning child process: Invalid argument
Quit
Type C-x 1 to delete the help window, C-M-v to scroll help.
Quit
Entering debugger...
Back to top level
read--expression: Trailing garbage following expression
Configured using:
 'configure --without-dbus --host=x86_64-w64-mingw32
 --without-compress-install 'CFLAGS=-O2 -static -g3''

Configured features:
XPM JPEG TIFF GIF PNG RSVG SOUND NOTIFY ACL GNUTLS LIBXML2 ZLIB
TOOLKIT_SCROLL_BARS THREADS LCMS2

Important settings:
  value of $LANG: ENU
  locale-coding-system: cp1252

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message rmc puny seq dired
dired-loaddefs format-spec rfc822 mml mml-sec password-cache epa derived
epg epg-config gnus-util rmail rmail-loaddefs mm-decode mm-bodies
mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail
rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils cl-extra
help-fns radix-tree help-mode easymenu cl-print byte-opt gv bytecomp
byte-compile cl-loaddefs cl-lib cconv debug elec-pair time-date
mule-util tooltip eldoc electric uniquify ediff-hook vc-hooks
lisp-float-type mwheel dos-w32 ls-lisp disp-table term/w32-win w32-win
w32-vars term/common-win tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode
prog-mode register page menu-bar rfn-eshadow isearch timer select
scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang
vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932
hebrew greek romanian slovak czech european ethiopic indian cyrillic
chinese composite charscript charprop case-table epa-hook jka-cmpr-hook
help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote w32notify w32 lcms2 multi-tty make-network-process emacs)

Memory information:
((conses 16 100958 5519)
 (symbols 56 20557 1)
 (miscs 48 45 202)
 (strings 32 31151 1771)
 (string-bytes 1 808081)
 (vectors 16 14466)
 (vector-slots 8 493429 6988)
 (floats 8 53 305)
 (intervals 56 327 7)
 (buffers 992 14))

Reply | Threaded
Open this post in threaded view
|

bug#33016: 26.1; (make-process ...) doesn't signal an error, when executable given as absolute Windows path does not exist

Eli Zaretskii
> From: Klaus-Dieter Bauer <[hidden email]>
> Date: Thu, 11 Oct 2018 14:55:27 +0200
>
> Entering
>
>     M-x eval-expression RET
>       (make-process :name "test" :command '("No Such Command"))
>
> will bring up the debugger with
>
>     (file-missing "Searching for program" "No such file or directory" "nosuchcommand")
>
> However, entering
>
>     M-x eval-expression RET
>       (make-process :name "test" :command '("c:/No Such Command"))
>
> will merely display in the echo-area message:
>
>     eval: Spawning child process: Invalid argument
>
> I stumbled upon this when debugging a quick-and-dirty
> script, that called a program by absolute path. When a new
> version of the program changed the name of the executable
> (tex2lyx2.3 -> tex2lyx), this issue occurred, and hindered
> debugging the problem.
>
> The wording of the message might indicate a
> Windows-specific issue.

The error in the second case is Windows specific, but the
inconsistency isn't: on Unix the second case "succeeds", in that it
returns a process object without any error messages.

The error message you see in the first case is because Emacs searches
for the program along exec-path (because it is not an absolute file
name).  In the second case this search is not done, because the file
name is already absolute.

So I don't think this is a bug.



Reply | Threaded
Open this post in threaded view
|

bug#33016: 26.1; (make-process ...) doesn't signal an error, when executable given as absolute Windows path does not exist

Klaus-Dieter Bauer
On Thu, Oct 11, 2018 at 4:22 PM Eli Zaretskii <[hidden email]> wrote:
> From: Klaus-Dieter Bauer <[hidden email]>
> Date: Thu, 11 Oct 2018 14:55:27 +0200
>
> Entering
>
>     M-x eval-expression RET
>       (make-process :name "test" :command '("No Such Command"))
>
> will bring up the debugger with
>
>     (file-missing "Searching for program" "No such file or directory" "nosuchcommand")
>
> However, entering
>
>     M-x eval-expression RET
>       (make-process :name "test" :command '("c:/No Such Command"))
>
> will merely display in the echo-area message:
>
>     eval: Spawning child process: Invalid argument
>
> I stumbled upon this when debugging a quick-and-dirty
> script, that called a program by absolute path. When a new
> version of the program changed the name of the executable
> (tex2lyx2.3 -> tex2lyx), this issue occurred, and hindered
> debugging the problem.
>
> The wording of the message might indicate a
> Windows-specific issue.

The error in the second case is Windows specific, but the
inconsistency isn't: on Unix the second case "succeeds", in that it
returns a process object without any error messages.

The error message you see in the first case is because Emacs searches
for the program along exec-path (because it is not an absolute file
name).  In the second case this search is not done, because the file
name is already absolute.

So I don't think this is a bug.

Now I understand the intent of the implementation better. However, the Unix/Windows difference still seems like a bug to me.

On Unix, the elisp will succeed, but the output and exit-status of the process clarify the issue.
On Windows, a non-local exit occurs due to the resulting exception.
As example:

    (let (p)
      (setq p
        (make-process :name "test" :command '("/tmp/nosuchcommand") :buffer (current-buffer)))
      ;; -- Subsequent code never reached on Windows
      (while (process-live-p p)
        (sleep-for 0.01))
      (message "(Process exit status %d)"
        (process-exit-status p)))

So on Windows two issues occur:
  - The exception doesn't indicate what went wrong.
  - The control-flow of the Elisp program is different from Unix.

This different seems, like it may give rise to Windows-specific bugs, that would be unnecessarily hard to debug.

Then again, calling programs by full path is probably rare, so it's probably a pretty low-priority issue.

- Klaus

 
Reply | Threaded
Open this post in threaded view
|

bug#33016: 26.1; (make-process ...) doesn't signal an error, when executable given as absolute Windows path does not exist

Eli Zaretskii
> From: Klaus-Dieter Bauer <[hidden email]>
> Date: Fri, 19 Oct 2018 10:03:00 +0200
> Cc: [hidden email]
>
> On Unix, the elisp will succeed, but the output and exit-status of the process clarify the issue.
> On Windows, a non-local exit occurs due to the resulting exception.
> As example:
>
>      (let (p)
>        (setq p
>          (make-process :name "test" :command '("/tmp/nosuchcommand") :buffer (current-buffer)))
>        ;; -- Subsequent code never reached on Windows
>        (while (process-live-p p)
>          (sleep-for 0.01))
>        (message "(Process exit status %d)"
>          (process-exit-status p)))
>
> So on Windows two issues occur:
>   - The exception doesn't indicate what went wrong.
>   - The control-flow of the Elisp program is different from Unix.
>
> This different seems, like it may give rise to Windows-specific bugs, that would be unnecessarily hard to
> debug.

That's true, but the way Emacs invokes async subprocesses on Windows
cannot be similar to Unix, because Windows lacks the 'fork' system
call.  Therefore, on Windows, the Emacs process itself invokes the
program, whereas on Unix this is done by a separate "forked" process,
which means Emacs on Unix simply doesn't know whether running the
program failed, until much later.

What this means is if some Lisp program wants to produce a consistent
behavior in these situations, it should have slightly different
application-level code for Posix and non-Posix hosts.

> Then again, calling programs by full path is probably rare, so it's probably a pretty low-priority issue.

Right.