dotnet fsi crashes with lines longer than terminal width
When editing a line in FSI, and seemingly only when we've already used the height of the terminal in lines of input, the interpreter process crashes when a single line overflows the terminal width.
It also unreliably reproduces when the terminal screen is not full, but the most reliable reproduction needs the long line to be at the bottom of a terminal screen where history has rolled off the top of the terminal.
Repro steps
- Type to fill the terminal, or run commands so that your prompt ends up at the bottom of the terminal you're using.
-
$ dotnet fsi - Type a long line (sample below), longer than the number of columns in the terminal
- When you get past the terminal width, the interpreter process will crash
The sample below is running on Ubuntu 22.04 from official apt sources, but I can reproduce in the following environments:
- FreeBSD 13.2 + neovim terminal
- FreeBSD 13.2 + oksh + kitty terminal
- FreeBSD 13.2 + oksh + xfce4-terminal
- Ubuntu 22.04 + osh + Gnome terminal
- Ubuntu 22.04 + osh + kitty terminal
- Ubuntu 22.04 + bash + kitty terminal
- Ubuntu 22.04 + neovim terminal
- Ubuntu 22.04 + vim terminal
++Edit++: also under tmux as a terminal multiplexer
For vim and neovim terminals, I have reproduced both by sending lines from a script file with Ionide-vim and by typing directly into the terminal. I originally found this by means of sending script lines to the interpreter with Ionide-vim. I had a long line that only caused issues when I had created my fsi window in a vertical split (two panes side by side, so each is half the screen width); if I stacked the windows on top of one another instead (each has whole screen width), I did not have any issue. Repro followed from there.
$ ps -o comm= $$
bash
greg@mercury:~$ uname -a
Linux mercury 6.5.0-1023-oem #24-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 14:26:31 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
greg@mercury:~$ ps -o comm= $$
bash
greg@mercury:~$ dotnet --version
8.0.105
greg@mercury:~$ dotnet fsi
Microsoft (R) F# Interactive version 12.8.102.0 for F# 8.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> printfn "This is a very long sentence which I will type to overflow the boundary of the terminal and yield the error that I am talking about in this bug report. No holding down a key for me! System.PlatformNotSupportedException: Operation is not supported on this platform.
at System.ConsolePal.set_BufferHeight(Int32 value)
at <StartupCode$fsi>.$Console.writeChar@358(ReadLineConsole x, FSharpRef`1 rendered, Char c) in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/fsi/console.fs:line 359
at <StartupCode$fsi>.$Console.read@544(ReadLineConsole x, StringBuilder input, FSharpRef`1 anchor, FSharpRef`1 rendered, FSharpRef`1 changed, FSharpRef`1 optionsCache, FSharpRef`1 current, Unit unitVar0) in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/fsi/console.fs:line 633
at FSharp.Compiler.Interactive.ReadLineConsole.ReadLine() in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/fsi/console.fs:line 643
at [email protected]() in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/Compiler/Interactive/fsi.fs:line 1458
Stopped due to error
Unhandled exception. System.PlatformNotSupportedException: Operation is not supported on this platform.
at System.ConsolePal.set_BufferHeight(Int32 value)
at <StartupCode$fsi>.$Console.writeChar@358(ReadLineConsole x, FSharpRef`1 rendered, Char c) in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/fsi/console.fs:line 359
at <StartupCode$fsi>.$Console.read@544(ReadLineConsole x, StringBuilder input, FSharpRef`1 anchor, FSharpRef`1 rendered, FSharpRef`1 changed, FSharpRef`1 optionsCache, FSharpRef`1 current, Unit unitVar0) in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/fsi/console.fs:line 633
at FSharp.Compiler.Interactive.ReadLineConsole.ReadLine() in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/fsi/console.fs:line 643
at [email protected]() in /build/dotnet8-z6Gph8/dotnet8-8.0.105-8.0.5/src/fsharp/artifacts/source-build/self/src/src/Compiler/Interactive/fsi.fs:line 1458
greg@mercury:~$
Expected behavior
You should be able to type arbitrarily long lines into FSI (or at least a whole lot longer than one screen width) and it should interpret the code.
Actual behavior
Overflowing a terminal line causes the exception above.
Sometimes, I have observed that instead of immediately throwing the exception, instead the cursor will wrap around to the beginning of the current line without a linefeed/newlline character (as if it were just executing a carriage return, but I have not validated the actual character codes being interpreted while typing), and the exception will only be thrown sometime after that. It can also get very confused about what quotes have been terminated when this specific behavior occurs. I cannot reliably reproduce the latter behavior, but it throws the same System.PlatformNotSupportedException: Operation is not supported on this platform. When the latter behavior occurs I do not get the full stack trace either.
Known workarounds
Write shorter code.
Related information
vim and nvim versions.
greg@mercury:~$ nvim --version
NVIM v0.11.0-dev
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Run "nvim -V1 -v" for more info
greg@mercury:~$ /usr/bin/vim.basic --version
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Mar 14 2024 09:05:11)
Included patches: 1-579, 1969, 580-1848, 4975, 5016, 5023, 5072, 2068, 1849-1854, 1857, 1855-1857, 1331, 1858, 1858-1859, 1873, 1860-1969, 1992, 1970-1992, 2010, 1993-2068, 2106, 2069-2106, 2108, 2107-2109, 2109-3995, 4563, 4646, 4774, 4895, 4899, 4901, 4919, 213, 1840, 1846-1847, 2110-2112, 2121
Modified by [email protected]
Compiled by [email protected]
Huge version without GUI. Features included (+) or not (-):
+acl +file_in_path +mouse_urxvt -tag_any_white
+arabic +find_in_path +mouse_xterm -tcl
+autocmd +float +multi_byte +termguicolors
+autochdir +folding +multi_lang +terminal
-autoservername -footer -mzscheme +terminfo
-balloon_eval +fork() +netbeans_intg +termresponse
+balloon_eval_term +gettext +num64 +textobjects
-browse -hangul_input +packages +textprop
++builtin_terms +iconv +path_extra +timers
+byte_offset +insert_expand -perl +title
+channel +ipv6 +persistent_undo -toolbar
+cindent +job +popupwin +user_commands
-clientserver +jumplist +postscript +vartabs
-clipboard +keymap +printer +vertsplit
+cmdline_compl +lambda +profile +vim9script
+cmdline_hist +langmap -python +viminfo
+cmdline_info +libcall +python3 +virtualedit
+comments +linebreak +quickfix +visual
+conceal +lispindent +reltime +visualextra
+cryptv +listcmds +rightleft +vreplace
+cscope +localmap -ruby +wildignore
+cursorbind -lua +scrollbind +wildmenu
+cursorshape +menu +signs +windows
+dialog_con +mksession +smartindent +writebackup
+diff +modify_fname +sodium -X11
+digraphs +mouse -sound -xfontset
-dnd -mouseshape +spell -xim
-ebcdic +mouse_dec +startuptime -xpm
+emacs_tags +mouse_gpm +statusline -xsmp
+eval -mouse_jsbterm -sun_workshop -xterm_clipboard
+ex_extra +mouse_netterm +syntax -xterm_save
+extra_search +mouse_sgr +tag_binary
-farsi -mouse_sysmouse -tag_old_static
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
defaults file: "$VIMRUNTIME/defaults.vim"
fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -Wdate-time -g -O2 -ffile-prefix-map=/build/vim-RPNH56/vim-8.2.3995=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: gcc -Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -o vim -lm -ltinfo -lselinux -lsodium -lacl -lattr -lgpm -L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu -lpython3.10 -lcrypt -ldl -lm -lm
With more experimentation, it appears that this is specific to readline-enabled interpreters. Disabling readline with $ dotnet fsi --readline- seems to eliminate the error.
What's the version of sdk in use?
Ubuntu:
$ dotnet --version
8.0.105
FreeBSD:
$ dotnet --version
8.0.100
Extra context:
Right now, due to a confluence of how FSAC and editors interact, working around this with the --readline- option has pretty negative knock-on effects for interactive programming with Ionide plugins.
- Editor plugin interactions: https://github.com/ionide/Ionide-vim/issues/82
- FSAC issues with CLI options: https://github.com/ionide/FsAutoComplete/issues/1210
A fix for the latter (FSAC issues with CLI options) will make the situation much more tenable for interactive development. Personally, I hope to get that PR raised tonight, as this is impacting my productivity.
After that fix, I think the situation will be much less severe. It certainly won't be a major concern for me, as the vast majority (99%) of my interactive use is sending lines from an editor to the interpreter via Ionide.
This isn't to say that "it works on my machine" but rather to give further debug data point that this indeed seems specific to the terminal being used. On Windows 11 and Windows Terminal, FSI handles long lines. For example:
PowerShell 7.4.2
Loading personal and system profiles took 1605ms.
> dotnet fsi
Microsoft (R) F# Interactive version 12.8.200.0 for F# 8.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> printfn "This is a very long sentence which I will type to overflow the boundary of the terminal and yield the error
that I am talking about in this bug report. No holding down a key for me! System.PlatformNotSupportedException: Opera
tion is not supported on this platform.asdflkajsfdaoiwejfoawjefoaijwefljawlkefjlakwjfelkajwveoijaoifjeoawjfeawljlvkjaw
kljfoeiawjfeoiawjfoejawoefjoajwfeioajwfeljaklvjelkajfeoaijwfeoiawjefoij";;
This is a very long sentence which I will type to overflow the boundary of the terminal and yield the error that I am talking about in this bug report. No holding down a key for me! System.PlatformNotSupportedException: Operation is not supported on this platform.asdflkajsfdaoiwejfoawjefoaijwefljawlkefjlakwjfelkajwveoijaoifjeoawjfeawljlvkjawkljfoeiawjfeoiawjfoejawoefjoajwfeioajwfeljaklvjelkajfeoaijwfeoiawjefoij
val it: unit = ()
Versions:
> dotnet fsi --version
Microsoft (R) F# Interactive version 12.8.200.0 for F# 8.0
> dotnet --version
8.0.204
Hopefully that's helpful.