Subject: Re: bug#45256: Viewing images over network using TRAMP (errors and unexpected prompts)

From: Michael Albinus <[email-masked]>
Date: Wed, 16 Dec 2020 10:08:08 +0100

Mikhail P <[email-masked]> writes:

> Greetings.

Hi,

> I am experiencing problems with viewing remote images. When resizing
> an image (e.g. by resizing Emacs frame) Emacs occasionally
> (approximately ~30% reproducibility) can prompt ... changed on disk;
> really edit the buffer? which does not make a lot of sense. Regardless
> of my response Emacs outputs errors, lags for several seconds and only
> after that resizes the image.
>
> I am using currently most recent commit on TRAMP repo
> (69844458e33b5dcae53de249d9d82c59a5876055) containing some necessary
> fixes. Prior to these fixes Emacs could occasionally stall on resizing
> remote image and only interruption with C-g could help (or sometimes
> making Emacs completely unresponsive). Also attaching TRAMP debug file
> which I hope exposes the problem.

FTR, this has been merged with the Emacs git master.

> As far as I could understand from my conversation with TRAMP devs
> while working on the fixes there are problems with functions called on
> idle-timer in image mode ... 😬

Well, we see in the debug file the following backtrace:

--8<---------------cut here---------------start------------->8---
  backtrace()
  tramp-send-string((tramp-file-name "ssh" nil nil "horsehop" nil "/storage1/mikpom/wizard_devel/CNV/figs/TCGA_CNV/AT..." nil) "(env QUOTING_STYLE=locale \\stat -c '((/////%N/////...")
  tramp-send-command((tramp-file-name "ssh" nil nil "horsehop" nil "/storage1/mikpom/wizard_devel/CNV/figs/TCGA_CNV/AT..." nil) "(env QUOTING_STYLE=locale \\stat -c '((/////%N/////...")

[...]

  tramp-file-name-handler(file-readable-p "/ssh:horsehop:/storage1/mikpom/wizard_devel/CNV/fi...")
  file-readable-p("/ssh:horsehop:/storage1/mikpom/wizard_devel/CNV/fi...")
  image-toggle-display-image()
  image-fit-to-window(#<window 3 on TCGA-02-2485.png>)
  apply(image-fit-to-window #<window 3 on TCGA-02-2485.png>)
  timer-event-handler([t 0 1 0 nil image-fit-to-window (#<window 3 on TCGA-02-2485.png>) idle 0])

[...]

  tramp-file-name-handler(verify-visited-file-modtime #<buffer TCGA-02-2485.png>)
  add-text-properties(1 64075 (display (image :type png :data "\211PNG\15\n\32\n\0\0\0\15IHDR\0\0\5\0\0\0\3\300\10\6\0\0\0j\334\324y\0\0\0\4sBIT\10\10\10\10|\10d\210\0..." :scale 1 :max-width 1152 :max-height 884) rear-nonsticky (display) read-only t front-sticky (read-only)))
  image-toggle-display-image()
  image-fit-to-window(#<window 3 on TCGA-02-2485.png>)
  apply(image-fit-to-window #<window 3 on TCGA-02-2485.png>)
  timer-event-handler([t 0 1 0 nil image-fit-to-window (#<window 3 on TCGA-02-2485.png>) idle 0])
18:56:54.633834 tramp-send-string (1) # Remote file error (compat): Forbidden reentrant call of Tramp
--8<---------------cut here---------------end--------------->8---

That is, two calls of timer-event-handler([t 0 1 0 nil image-fit-to-window ...])

image-fit-to-window calls remote file operations,
verify-visited-file-modtime the first time, file-readable-p the second
time. The first call of image-fit-to-window hasn't finished, when the
second call of image-fit-to-window happens one second later. That is
relevant, this situation happens only for slow remote connections (I had
a hard time to reconstruct the scenario).

>From my pov, image-fit-to-window must be hardened in order to avoid this
reentrant call. Maybe an internal lock at entry, which is honored by
every next call until the lock is removed.

And at least it shall be wrapped with

(ignore-error 'remote-file-error ...)

in order to masque the situation.

> Thanks,
> Mikhail

Best regards, Michael.