unofficial mirror of bug-guix@gnu.org 
 help / color / mirror / code / Atom feed
* bug#57095: another "inappropriate ioctl" bug :)
@ 2022-08-09 23:06 Csepp
  2022-08-10 13:43 ` Josselin Poiret via Bug reports for GNU Guix
  0 siblings, 1 reply; 7+ messages in thread
From: Csepp @ 2022-08-09 23:06 UTC (permalink / raw)
  To: 57095


```
./pre-inst-env guix import pypi -r linode-cli | tee -a gnu/packages/python-xyz.scm

...
In guix/build/syscalls.scm:
  2284:35  1 (_)
   2273:8  0 (terminal-window-size _)

guix/build/syscalls.scm:2273:8: In procedure terminal-window-size:
In procedure terminal-window-size: Inappropriate ioctl for device
```

I assume the progress bar code does not gracefully handle the very
common case when stdout is not a terminal.

Good thing I'm in a local checkout so I can just make it return some
constant.




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

* bug#57095: another "inappropriate ioctl" bug :)
  2022-08-09 23:06 bug#57095: another "inappropriate ioctl" bug :) Csepp
@ 2022-08-10 13:43 ` Josselin Poiret via Bug reports for GNU Guix
  2022-08-10 14:53   ` Ludovic Courtès
  2022-09-01 21:04   ` bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device") Ludovic Courtès
  0 siblings, 2 replies; 7+ messages in thread
From: Josselin Poiret via Bug reports for GNU Guix @ 2022-08-10 13:43 UTC (permalink / raw)
  To: Csepp, 57095

Hi!

Csepp <raingloom@riseup.net> writes:

> ```
> ./pre-inst-env guix import pypi -r linode-cli | tee -a gnu/packages/python-xyz.scm
>
> ...
> In guix/build/syscalls.scm:
>   2284:35  1 (_)
>    2273:8  0 (terminal-window-size _)
>
> guix/build/syscalls.scm:2273:8: In procedure terminal-window-size:
> In procedure terminal-window-size: Inappropriate ioctl for device
> ```
>
> I assume the progress bar code does not gracefully handle the very
> common case when stdout is not a terminal.

There is some code in place to handle this issue, and it works most of
the time, but not here.  The issue is that we handle any error coming
from ioctl by first throwing a `'system-error`, and handling it with a
`catch` that checks whether the errno is ENOTTY (and deprecated
equivalents) and in that case falls back to a good default.  In the case
where the error is not of that type, it is rethrown.  This works well in
most cases, but here comes the Guile shenanigans:

We also use a big wrapping `with-error-handling` to display errors
properly in the case when they are not caught.  The difference is that
`with-error-handling` adds a non-unwinding handler, while catch is
unwinding.  My first thought was that non-unwinding handlers, even outer
ones would get priority over unwinding ones, since once the stack's
unwound you can't really go back (I have no idea if that last part is
actually true).  In practice this is actually false, I tested with a
very simple example, but that lead me to test by setting `#:unwind? #t`
for the `guard*` definition in guix/ui.scm and the issue went away, so I'm
clueless as to why this happens.  What seems weird is that the error is
not caught at all!

Does anyone have a clue?

Best,
-- 
Josselin Poiret




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

* bug#57095: another "inappropriate ioctl" bug :)
  2022-08-10 13:43 ` Josselin Poiret via Bug reports for GNU Guix
@ 2022-08-10 14:53   ` Ludovic Courtès
  2022-09-01 21:04   ` bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device") Ludovic Courtès
  1 sibling, 0 replies; 7+ messages in thread
From: Ludovic Courtès @ 2022-08-10 14:53 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 57095, Csepp

Hi!

Josselin Poiret <dev@jpoiret.xyz> skribis:

> We also use a big wrapping `with-error-handling` to display errors
> properly in the case when they are not caught.  The difference is that
> `with-error-handling` adds a non-unwinding handler, while catch is
> unwinding.  My first thought was that non-unwinding handlers, even outer
> ones would get priority over unwinding ones, since once the stack's
> unwound you can't really go back (I have no idea if that last part is
> actually true).  In practice this is actually false, I tested with a
> very simple example, but that lead me to test by setting `#:unwind? #t`
> for the `guard*` definition in guix/ui.scm and the issue went away, so I'm
> clueless as to why this happens.  What seems weird is that the error is
> not caught at all!

The inner handler, even if it’s unwinding and the outer one is not,
appears to have higher precedence:

--8<---------------cut here---------------start------------->8---
scheme@(guix read-print)> (with-exception-handler (lambda args (pk 'outer args))
			    (lambda ()
			      (with-exception-handler
				  (lambda args (pk 'inner args))
				(lambda()
				  (rmdir "/"))
				#:unwind? #t))
			    #:unwind? #f)

;;; (inner (#<&compound-exception components: (#<&external-error> #<&origin origin: "rmdir"> #<&message message: "~A"> #<&irritants irritants: ("Device or resource busy")> #<&exception-with-kind-and-args kind: system-error args: ("rmdir" "~A" ("Device or resource busy") (16))>)>))
$17 = (#<&compound-exception components: (#<&external-error> #<&origin origin: "rmdir"> #<&message message: "~A"> #<&irritants irritants: ("Device or resource busy")> #<&exception-with-kind-and-args kind: system-error args: ("rmdir" "~A" ("Device or resource busy") (16))>)>)
scheme@(guix read-print)> (with-exception-handler (lambda args (pk 'outer args))
			    (lambda ()
			      (catch 'system-error
				(lambda ()
				  (rmdir "/"))
				(lambda args
				  (pk 'inner args))))
			    #:unwind? #f)

;;; (inner (system-error "rmdir" "~A" ("Device or resource busy") (16)))
$18 = (system-error "rmdir" "~A" ("Device or resource busy") (16))
--8<---------------cut here---------------end--------------->8---

This appears to work:

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> ,use(guix build syscalls)
scheme@(guile-user)> (terminal-columns)
$19 = 119
scheme@(guile-user)> ,use(guix ui)
scheme@(guile-user)> (with-error-handling (terminal-columns))
$20 = 119
scheme@(guile-user)> (terminal-columns (open-input-string ""))
$21 = 143
scheme@(guile-user)> (with-error-handling (terminal-columns (open-input-string "")))
$22 = 143
--8<---------------cut here---------------end--------------->8---

Needs more investigation…

Ludo’.




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

* bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device")
  2022-08-10 13:43 ` Josselin Poiret via Bug reports for GNU Guix
  2022-08-10 14:53   ` Ludovic Courtès
@ 2022-09-01 21:04   ` Ludovic Courtès
  2022-09-01 21:21     ` Maxime Devos
  1 sibling, 1 reply; 7+ messages in thread
From: Ludovic Courtès @ 2022-09-01 21:04 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 57095, Csepp

Hi,

Josselin Poiret <dev@jpoiret.xyz> skribis:

> We also use a big wrapping `with-error-handling` to display errors
> properly in the case when they are not caught.  The difference is that
> `with-error-handling` adds a non-unwinding handler, while catch is
> unwinding.  My first thought was that non-unwinding handlers, even outer
> ones would get priority over unwinding ones, since once the stack's
> unwound you can't really go back (I have no idea if that last part is
> actually true).  In practice this is actually false, I tested with a
> very simple example, but that lead me to test by setting `#:unwind? #t`
> for the `guard*` definition in guix/ui.scm and the issue went away, so I'm
> clueless as to why this happens.  What seems weird is that the error is
> not caught at all!

Here’s a reproducer:

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)>  (with-exception-handler (lambda _ (catch 'x (lambda () (throw 'x)) (const 'good) ))
			 (lambda ()
			   (rmdir "/"))
			 #:unwind? #f)
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Throw to key `x' with args `()'.
--8<---------------cut here---------------end--------------->8---

Or, simplified:

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)>  (with-exception-handler
			  (lambda _ (with-exception-handler (const 'good)
				      (lambda () (throw 'x))
				      #:unwind? #t))
			 (lambda ()
			   (rmdir "/"))
			 #:unwind? #f)
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Throw to key `x' with args `()'.
--8<---------------cut here---------------end--------------->8---

We expect 'x to be caught, leading the handler to return 'good.
Instead, 'x is not caught at all.

In both cases, setting #:unwind? #t in the outer
‘with-exception-handler’ gives the expected result.

I spent some time staring at the relevant code in ‘boot-9.scm’ but
nothing came out of it.

Ludo’.




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

* bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device")
  2022-09-01 21:04   ` bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device") Ludovic Courtès
@ 2022-09-01 21:21     ` Maxime Devos
  2022-09-02  9:17       ` Ludovic Courtès
  0 siblings, 1 reply; 7+ messages in thread
From: Maxime Devos @ 2022-09-01 21:21 UTC (permalink / raw)
  To: Ludovic Courtès, Josselin Poiret; +Cc: 57095, Csepp


[-- Attachment #1.1.1: Type: text/plain, Size: 524 bytes --]


On 01-09-2022 23:04, Ludovic Courtès wrote:
> [...]
> We expect 'x to be caught, leading the handler to return 'good.
> Instead, 'x is not caught at all.
>
> In both cases, setting #:unwind? #t in the outer
> ‘with-exception-handler’ gives the expected result.
>
> I spent some time staring at the relevant code in ‘boot-9.scm’ but
> nothing came out of it.
>
> Ludo’.
>
>
Maybe my answer on IRC is relevant here:

https://logs.guix.gnu.org/guile/2022-09-01.log#231503

Greetings,
Maxime.


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 929 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]

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

* bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device")
  2022-09-01 21:21     ` Maxime Devos
@ 2022-09-02  9:17       ` Ludovic Courtès
  2022-09-02 18:14         ` Maxime Devos
  0 siblings, 1 reply; 7+ messages in thread
From: Ludovic Courtès @ 2022-09-02  9:17 UTC (permalink / raw)
  To: Maxime Devos; +Cc: 57095, Josselin Poiret, Csepp

Hi,

Maxime Devos <maximedevos@telenet.be> skribis:

> Maybe my answer on IRC is relevant here:
>
> https://logs.guix.gnu.org/guile/2022-09-01.log#231503

Interesting.

It’s a Guile bug, and a tricky one.  Here’s what Andy wrote on IRC:

<sneek> civodul, wingo says: i believe it is a bug.  in a pre-unwind handler,
	you want to make it so that if it throws again, it is handled by the
	handler that was current when the with-exception-handler was invoked
	(the dynamically outer handler)
<sneek> civodul, wingo says: to implement this, when a throw first starts, we
	capture the current handler stack, and arrange for subsequent throws
	to resolve via that captured handler stack
<sneek> civodul, wingo says: but if there is an additional
	with-exception-handler within the exception handler, that doesn't
	augment the captured exception handler stack to which inner exceptions
	will dispatch
<sneek> civodul, wingo says: the fix will be small but also gnarly :P  will
	take some thinking.  there are funny interactions with delimited
	continuations

I’ll defer to Andy to see what the best way to fix it is…

What’s frustrating is that I can’t think of a way to work around it,
except by changing ‘terminal-columns’ & co. to not use exceptions (or
introducing a variant that does that).

Thoughts?

Ludo’.




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

* bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device")
  2022-09-02  9:17       ` Ludovic Courtès
@ 2022-09-02 18:14         ` Maxime Devos
  0 siblings, 0 replies; 7+ messages in thread
From: Maxime Devos @ 2022-09-02 18:14 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 57095, Josselin Poiret, Csepp


[-- Attachment #1.1.1: Type: text/plain, Size: 497 bytes --]


On 02-09-2022 11:17, Ludovic Courtès wrote:
> [...]
>
> What’s frustrating is that I can’t think of a way to work around it,
> except by changing ‘terminal-columns’ & co. to not use exceptions (or
> introducing a variant that does that).
>
> Thoughts?

Exception handlers do not cross process boundaries. Maybe run the inner 
(catch ...) or (with-exception-handle ...) or whatever is used here in a 
separate thread + wait for the thread to return?

Greetings,
Maxime.


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 929 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]

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

end of thread, other threads:[~2022-09-02 18:23 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-09 23:06 bug#57095: another "inappropriate ioctl" bug :) Csepp
2022-08-10 13:43 ` Josselin Poiret via Bug reports for GNU Guix
2022-08-10 14:53   ` Ludovic Courtès
2022-09-01 21:04   ` bug#57095: 'terminal-window-size' throws ENOTTY ("Inappropriate ioctl for device") Ludovic Courtès
2022-09-01 21:21     ` Maxime Devos
2022-09-02  9:17       ` Ludovic Courtès
2022-09-02 18:14         ` Maxime Devos

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

	https://git.savannah.gnu.org/cgit/guix.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).