qutebrowser / qutebrowser

A keyboard-driven, vim-like browser based on Python and Qt.
https://www.qutebrowser.org/
GNU General Public License v3.0
9.71k stars 1.01k forks source link

`ValueError: I/O operation on closed file` with `:tab-select` and userscript #6742

Open crocket opened 3 years ago

crocket commented 3 years ago

Version info:

qutebrowser v2.3.1 Git commit: Backend: QtWebEngine 5.15.2, based on Chromium 87.0.4280.144 Qt: 5.15.2

Does the bug happen if you start with --temp-basedir?:

Yes

Description

~/.config/qutebrowser/config.py

config.bind("<Return>", "spawn -u command-accept", mode="command")

~/.config/qutebrowser/userscripts/command-accept

#!/bin/sh

echo "command-accept" >> "${QUTE_FIFO}"

How to reproduce

If Enter key is mapped to spawn -u command-accept in config.py, pressing 1 and then enter after pressing gt crashes qutebrowser because

12:04:22 ERROR: Uncaught exception
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/qutebrowser/commands/userscripts.py", line 76, in read_line
    for line in self._fifo:
ValueError: I/O operation on closed file.
The-Compiler commented 3 years ago

Works fine for me. Can you submit the crash report (ideally with --temp-basedir), so I can take a look at the logs?

crocket commented 3 years ago

I just submitted the report through the UI. I reproduced the issue with --temp-basedir.

The-Compiler commented 3 years ago

Report (non-public): https://crashes.qutebrowser.org/view/e8836e99

With:

:bind --mode command <Return> spawn -u command-accept
:tab-focus 1
:tab-select 1

logs for tab-focus:

23:46:14 DEBUG    commands   command:run:537 command called: spawn ['-u', 'command-accept']
23:46:14 DEBUG    commands   command:run:551 Calling qutebrowser.browser.commands.CommandDispatcher.spawn(<qutebrowser.browser.commands.CommandDispatcher>, 'command-accept', True, False, False, False, False, None)
23:46:14 DEBUG    procs      commands:spawn:1088 Executing command-accept with args [], userscript=True
23:46:14 DEBUG    modes      modeman:_handle_keypress:312 match: 2, forward_unbound_keys: auto, passthrough: True, is_non_alnum: True, dry_run: False --> filter: True (focused: <qutebrowser.mainwindow.statusbar.command.Command>)
23:46:14 DEBUG    misc       userscripts:run_async:459 command-accept is no absolute path
23:46:14 DEBUG    misc       userscripts:run_async:463 Userscript to run: /tmp/qutebrowser-basedir-7nfcxfra/config/userscripts/command-accept
23:46:14 DEBUG    procs      userscripts:store_html:151 HTML stored from webview
23:46:14 DEBUG    procs      userscripts:store_text:137 Text stored from webview
23:46:14 DEBUG    procs      userscripts:store_text:139 Both text/HTML stored, kicking off userscript!
23:46:14 DEBUG    procs      guiprocess:start:346 Starting process.
23:46:14 DEBUG    procs      guiprocess:_pre_start:340 Executing: /tmp/qutebrowser-basedir-7nfcxfra/config/userscripts/command-accept
23:46:14 DEBUG    procs      guiprocess:_on_started:330 Process started.
23:46:14 DEBUG    procs      userscripts:read_line:72 QSocketNotifier triggered!
23:46:14 DEBUG    commands   userscripts:<lambda>:443 Got userscript command: command-accept
23:46:14 DEBUG    commands   command:run:537 command called: command-accept
23:46:14 DEBUG    commands   command:run:551 Calling qutebrowser.mainwindow.statusbar.command.Command.command_accept(<qutebrowser.mainwindow.statusbar.command.Command>, False)
23:46:14 DEBUG    save       savemanager:mark_dirty:73 Marking command-history as dirty.
23:46:14 DEBUG    modes      modeman:leave:431 Leaving mode KeyMode.command (reason: cmd accept)
[...]
23:46:14 DEBUG    commands   command:run:537 command called: tab-focus ['1']
23:46:14 DEBUG    commands   argparser:multitype_conv:158 Trying to parse '1' as <class 'int'>
23:46:14 DEBUG    commands   command:run:551 Calling qutebrowser.browser.commands.CommandDispatcher.tab_focus(<qutebrowser.browser.commands.CommandDispatcher>, 1, None, False)
23:46:14 DEBUG    procs      guiprocess:_on_finished:298 Process finished with code 0, status 0.
23:46:14 DEBUG    procs      userscripts:_cleanup:288 Cleaning up
23:46:14 DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/qutebrowser-basedir-7nfcxfra/runtime/qutebrowser-userscript-hb37_o1l.
23:46:14 DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmpntbqdqcn.html.
23:46:14 DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmplr67ky0t.txt.

logs for tab-select:

23:46:16 DEBUG    commands   command:run:537 command called: spawn ['-u', 'command-accept']
23:46:16 DEBUG    commands   command:run:551 Calling qutebrowser.browser.commands.CommandDispatcher.spawn(<qutebrowser.browser.commands.CommandDispatcher>, 'command-accept', True, False, False, False, False, None)
23:46:16 DEBUG    procs      commands:spawn:1088 Executing command-accept with args [], userscript=True
23:46:16 DEBUG    modes      modeman:_handle_keypress:312 match: 2, forward_unbound_keys: auto, passthrough: True, is_non_alnum: True, dry_run: False --> filter: True (focused: <qutebrowser.mainwindow.statusbar.command.Command>)
23:46:16 DEBUG    misc       userscripts:run_async:459 command-accept is no absolute path
23:46:16 DEBUG    misc       userscripts:run_async:463 Userscript to run: /tmp/qutebrowser-basedir-7nfcxfra/config/userscripts/command-accept
23:46:16 DEBUG    procs      userscripts:store_html:151 HTML stored from webview
23:46:16 DEBUG    procs      userscripts:store_text:137 Text stored from webview
23:46:16 DEBUG    procs      userscripts:store_text:139 Both text/HTML stored, kicking off userscript!
23:46:16 DEBUG    procs      guiprocess:start:346 Starting process.
23:46:16 DEBUG    procs      guiprocess:_pre_start:340 Executing: /tmp/qutebrowser-basedir-7nfcxfra/config/userscripts/command-accept
23:46:16 DEBUG    procs      guiprocess:_on_started:330 Process started.
23:46:16 DEBUG    procs      userscripts:read_line:72 QSocketNotifier triggered!
23:46:16 DEBUG    commands   userscripts:<lambda>:443 Got userscript command: command-accept
23:46:16 DEBUG    commands   command:run:537 command called: command-accept
23:46:16 DEBUG    commands   command:run:551 Calling qutebrowser.mainwindow.statusbar.command.Command.command_accept(<qutebrowser.mainwindow.statusbar.command.Command>, False)
23:46:16 DEBUG    save       savemanager:mark_dirty:73 Marking command-history as dirty.
23:46:16 DEBUG    modes      modeman:leave:431 Leaving mode KeyMode.command (reason: cmd accept)
[...]
23:46:16 DEBUG    commands   command:run:537 command called: tab-select ['1']
23:46:16 DEBUG    commands   command:run:551 Calling qutebrowser.browser.commands.CommandDispatcher.tab_select(<qutebrowser.browser.commands.CommandDispatcher>, '1', None)
23:46:16 WARNING  qt-qt.qpa.wayland Unknown module:none:0 Wayland does not support QWindow::requestActivate()
23:46:16 DEBUG    procs      guiprocess:_on_finished:298 Process finished with code 0, status 0.
23:46:16 DEBUG    procs      userscripts:_cleanup:288 Cleaning up
23:46:16 DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/qutebrowser-basedir-7nfcxfra/runtime/qutebrowser-userscript-guly6spq.
23:46:16 DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmp746ctfrg.html.
23:46:16 DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmpd623rczq.txt.
23:46:16 WARNING  qt-qt.qpa.wayland Unknown module:none:0 Wayland does not support QWindow::requestActivate()
23:46:16 ERROR    misc       crashsignal:_handle_early_exits:240 Uncaught exception
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/qutebrowser/commands/userscripts.py", line 76, in read_line
    for line in self._fifo:
ValueError: I/O operation on closed file.

diff:

--- log1    2021-10-16 17:06:59.881093452 +0200
+++ log2    2021-10-16 17:08:46.601269946 +0200
@@ -17,11 +17,17 @@
 DEBUG    save       savemanager:mark_dirty:73 Marking command-history as dirty.
 DEBUG    modes      modeman:leave:431 Leaving mode KeyMode.command (reason: cmd accept)

-DEBUG    commands   command:run:537 command called: tab-focus ['1']
-DEBUG    commands   argparser:multitype_conv:158 Trying to parse '1' as <class 'int'>
-DEBUG    commands   command:run:551 Calling qutebrowser.browser.commands.CommandDispatcher.tab_focus(<qutebrowser.browser.commands.CommandDispatcher>, 1, None, False)
+DEBUG    commands   command:run:537 command called: tab-select ['1']
+DEBUG    commands   command:run:551 Calling qutebrowser.browser.commands.CommandDispatcher.tab_select(<qutebrowser.browser.commands.CommandDispatcher>, '1', None)
+WARNING  qt-qt.qpa.wayland Unknown module:none:0 Wayland does not support QWindow::requestActivate()
 DEBUG    procs      guiprocess:_on_finished:298 Process finished with code 0, status 0.
 DEBUG    procs      userscripts:_cleanup:288 Cleaning up
-DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/qutebrowser-basedir-7nfcxfra/runtime/qutebrowser-userscript-hb37_o1l.
-DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmpntbqdqcn.html.
-DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmplr67ky0t.txt.
+DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/qutebrowser-basedir-7nfcxfra/runtime/qutebrowser-userscript-guly6spq.
+DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmp746ctfrg.html.
+DEBUG    procs      userscripts:_cleanup:193 Deleting temporary file /tmp/tmpd623rczq.txt.
+WARNING  qt-qt.qpa.wayland Unknown module:none:0 Wayland does not support QWindow::requestActivate()
+ERROR    misc       crashsignal:_handle_early_exits:240 Uncaught exception
+Traceback (most recent call last):
+  File "/usr/lib/python3.9/site-packages/qutebrowser/commands/userscripts.py", line 76, in read_line
+    for line in self._fifo:
+ValueError: I/O operation on closed file.

so this might be wayland specific.

The-Compiler commented 3 years ago

Reproduced now (on X11) - standalone reproducer:

echo -e '#!/bin/sh\necho command-accept > $QUTE_FIFO' > /tmp/u.sh && chmod +x /tmp/u.sh && python3 -m qutebrowser --temp-basedir --debug ":set-cmd-text -s :tab-select" ":later 500 completion-item-focus next" ":later 1000 spawn -u /tmp/u.sh"
thjbdvlt commented 11 months ago

hello! i have a similar issue while trying to use a userscript on tab-select, but the error only happens sometimes (~1/10, independant of the url or anything, with the same tab sometimes it works and sometimes it crashes):

Traceback (most recent call last):
  File "/home/uut/softwares/qutebrowser/qutebrowser/commands/userscripts.py", line 60, in read_line
    for line in self._fifo:
ValueError: I/O operation on closed file.

i changed my script in order to send :tab-focus [index] instead of :tab-select [url|title] and it works without any issue.

output of qutebrowser version:

qutebrowser v3.0.2
Git commit: 044b1e38e-dirty on main (2023-10-31 09:28:32 +0100)
Backend: QtWebEngine 6.5.3, based on Chromium 108.0.5359.220 (from api)
Qt: 6.5.3

CPython: 3.9.2
PyQt: 6.5.3

Qt wrapper info:
  PyQt6: success
  PyQt5: not imported
  -> selected: PyQt6 (via autoselect)

colorama: 0.4.6
jinja2: 3.1.2
pygments: 2.16.1
yaml: 6.0.1
adblock: 0.6.0
objc: no
PyQt6.QtWebEngineCore: 6.5.0
PyQt6.sip: 6.7.12
pdf.js: 2.6.0 (/usr/share/javascript/pdf/build/pdf.js)
sqlite: 3.43.1
QtNetwork SSL: no
...