unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#33747: 26.1; process-send-string exceeds max-specpdl-size
@ 2018-12-14 17:49 Markus Triska
  2018-12-14 18:40 ` Eli Zaretskii
  0 siblings, 1 reply; 5+ messages in thread
From: Markus Triska @ 2018-12-14 17:49 UTC (permalink / raw)
  To: 33747


To reproduce this issue, please install the PostScript viewer
Ghostscript ("gs"), and put the following forms in "pipe.el":

    (setq target (start-process "gs" nil "gs" "-g100x100")
          source (start-process "bash" nil "bash"
                                "-c" "while true; do echo \
      rand 2 31 exp div setgray 0 0 100 100 rectfill; done"))

    (set-process-filter source 'send-to-target)

    (defun send-to-target (proc str)
      (process-send-string target str))

When you then invoke Emacs via:

    $ emacs -Q pipe.el --eval '(eval-buffer)'

you get almost instantly:

    error in process filter: Variable binding depth exceeds max-specpdl-size

The reason for this seems to be that process-send-string also builds up
frames for unwind-protect when it waits for input if the queue is full.

However, in this concrete case, I would prefer to simply send (or queue)
the string and *not* wait for any input within the process filter.

Is there a way to accomplish this? Alternatively, would you please
consider to provide such a mechanism?

For example, when sending output to a process and the output queue of
that process is full, would it be admissible or even preferable to wait
only for input of that specific process, instead of also waiting for and
handling input from other processes (as seems to be the case now)?

Thank you and all the best!
Markus


In GNU Emacs 26.1 (build 1, x86_64-pc-linux-gnu, X toolkit, Xaw scroll bars)
 of 2018-11-18 built on debian
Repository revision: 07f8f9bc5a51f5aa94eb099f3e15fbe0c20ea1ea
Windowing system distributor 'The X.Org Foundation', version 11.0.11902000
System Description:	Debian GNU/Linux 9.6 (stretch)






^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#33747: 26.1; process-send-string exceeds max-specpdl-size
  2018-12-14 17:49 bug#33747: 26.1; process-send-string exceeds max-specpdl-size Markus Triska
@ 2018-12-14 18:40 ` Eli Zaretskii
  2018-12-14 18:50   ` Markus Triska
  0 siblings, 1 reply; 5+ messages in thread
From: Eli Zaretskii @ 2018-12-14 18:40 UTC (permalink / raw)
  To: Markus Triska; +Cc: 33747

> From: Markus Triska <triska@metalevel.at>
> Date: Fri, 14 Dec 2018 18:49:09 +0100
> 
> The reason for this seems to be that process-send-string also builds up
> frames for unwind-protect when it waits for input if the queue is full.
> 
> However, in this concrete case, I would prefer to simply send (or queue)
> the string and *not* wait for any input within the process filter.
> 
> Is there a way to accomplish this?

AFAIK, process-send-string is a blocking function: it cannot return
before the entire string was sent.





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#33747: 26.1; process-send-string exceeds max-specpdl-size
  2018-12-14 18:40 ` Eli Zaretskii
@ 2018-12-14 18:50   ` Markus Triska
  2018-12-14 19:54     ` Eli Zaretskii
  0 siblings, 1 reply; 5+ messages in thread
From: Markus Triska @ 2018-12-14 18:50 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 33747

Eli Zaretskii <eliz@gnu.org> writes:

> AFAIK, process-send-string is a blocking function: it cannot return
> before the entire string was sent.

Yes indeed. However, the C function send_process internally calls
wait_reading_process_output, and this may again invoke the filter!  What
I find surprising is that this call of wait_reading_process_output is
not limited to the process whose output queue is full, i.e., the one for
which process-send-string was actually invoked. Would it work to limit
it to that process, or could there be an alternative means to prevent
reading from other processes in that case? It would be very useful in
such situations where I simply want to send, and not read anything.





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#33747: 26.1; process-send-string exceeds max-specpdl-size
  2018-12-14 18:50   ` Markus Triska
@ 2018-12-14 19:54     ` Eli Zaretskii
  2018-12-14 21:23       ` Markus Triska
  0 siblings, 1 reply; 5+ messages in thread
From: Eli Zaretskii @ 2018-12-14 19:54 UTC (permalink / raw)
  To: Markus Triska; +Cc: 33747

> From: Markus Triska <triska@metalevel.at>
> Cc: 33747@debbugs.gnu.org
> Date: Fri, 14 Dec 2018 19:50:39 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > AFAIK, process-send-string is a blocking function: it cannot return
> > before the entire string was sent.
> 
> Yes indeed. However, the C function send_process internally calls
> wait_reading_process_output

That's so as not to wedge the entire session.  Communications with
async subprocesses aren't supposed to stop everything in its tracks.

> and this may again invoke the filter!

In general, calling APIs that could take a long time from a process
filter is not a very good idea, btw.  Remember that process filters
are run when Emacs is idle, so when you call an API that could take a
long time, you make Emacs less responsive.  And then there's the
infinite recursion case that you hit.

> What I find surprising is that this call of
> wait_reading_process_output is not limited to the process whose
> output queue is full, i.e., the one for which process-send-string
> was actually invoked.

I don't see any reason why it should only wait for output from the
same process.  Once again, this is Emacs's way to wait without
stopping everything else, so waiting for input from any source makes
perfect sense to me.





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#33747: 26.1; process-send-string exceeds max-specpdl-size
  2018-12-14 19:54     ` Eli Zaretskii
@ 2018-12-14 21:23       ` Markus Triska
  0 siblings, 0 replies; 5+ messages in thread
From: Markus Triska @ 2018-12-14 21:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 33747

Eli Zaretskii <eliz@gnu.org> writes:

> stopping everything else, so waiting for input from any source makes
> perfect sense to me.

In this concrete case, I am looking for a way to make Emacs not wait
for, or at least not process, input from a specific process while
sending output to a different process.

For the case I posted, I can alleviate the issue a bit if I set:

    (setq max-specpdl-size 5000)

However, if I then use for example the following definition of
send-to-target instead of the one I posted:

   (defun send-to-target (proc str)
     (if (process-live-p target)
         (process-send-string target str)
       (kill-process source)))

then I get, for the receipe I posted:

    Lisp nesting exceeds ‘max-lisp-eval-depth’

This is unfortunate, because increasing this limit will eventually crash
Emacs. The root cause is that process-send-string triggers the filter of
the same process that caused the filter to be invoked. I find this
unexpected, because the target process is different, and if possible, I
would like a way do prevent this. Could you please consider adding a
feature that prevents triggering the filter in such cases?

Thank you and all the best!
Markus







^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-12-14 21:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-12-14 17:49 bug#33747: 26.1; process-send-string exceeds max-specpdl-size Markus Triska
2018-12-14 18:40 ` Eli Zaretskii
2018-12-14 18:50   ` Markus Triska
2018-12-14 19:54     ` Eli Zaretskii
2018-12-14 21:23       ` Markus Triska

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).