walles / moar

Moar is a pager. It's designed to just do the right thing without any configuration.
Other
587 stars 17 forks source link

Crash when piping less-than-fullscreen output from Powershell into moar #145

Closed scottbilas closed 10 months ago

scottbilas commented 10 months ago

I'm getting a crash when I pipe output to moar from a script in pwsh, where the output is less than a full screen's length. I've tried a few ways to isolate what exactly in the script is making it do this, but haven't succeeded, so I'm not able to give you a small repro case unfortunately. I hope the stack is helpful.

LANG   :
TERM   :

GOOS    : windows
GOARCH  : amd64
Compiler: gc
NumCPU  : 36

panic: The parameter is incorrect. [recovered]
        panic: The parameter is incorrect.

goroutine 1 [running]:
main.main.func1()
        /Users/johan/src/moar/moar.go:234 +0x4d
panic({0x8cedc0, 0xc556b8})
        /usr/local/Cellar/go/1.20.5/libexec/src/runtime/panic.go:884 +0x213
main.startPaging(0xc0000ae3c0)
        /Users/johan/src/moar/moar.go:411 +0x105
main.main()
        /Users/johan/src/moar/moar.go:387 +0x100f
walles commented 10 months ago

Try to repro with this binary:

moar-v1.15.3-1-g848958d-windows-amd64.exe.gz

It contains 848958dad029cbc66d5281ec79caf3d833b7293c for better error reporting on Windows.

Word of warning though, I don't have access to any Windows machine to debug this on so we'll see how far we get.

scottbilas commented 10 months ago

Re-running gives this log

Version: v1.15.3-1-g848958d
LANG   :
TERM   :

GOOS    : windows
GOARCH  : amd64
Compiler: gc
NumCPU  : 36

panic: failed to set stdin console mode: The parameter is incorrect. [recovered]
        panic: failed to set stdin console mode: The parameter is incorrect.

goroutine 1 [running]:
main.main.func1()
        /Users/johan/src/moar/moar.go:234 +0x4d
panic({0x317320, 0xc0004c4b60})
        /usr/local/Cellar/go/1.20.7/libexec/src/runtime/panic.go:884 +0x213
main.startPaging(0xc0000ae3c0)
        /Users/johan/src/moar/moar.go:411 +0x105
main.main()
        /Users/johan/src/moar/moar.go:387 +0x100f
scottbilas commented 10 months ago

Now that I see the stdin panic, I tried comparing again with both more and less. Both pagers will print the output, but I don't get a shell prompt until I hit Enter. My Powershell script had a small bug in its output loop (I'm keeping this old version for testing), and this is certainly causing this weird behavior.

The difference with moar is that it will crash.

Also, after the crash, moar somehow leaves the shell in an odd state where pressing Enter will instead print m and I have to restart the shell. This is probably a bug in Powershell's readline module, which is flakey, but it's odd that only moar will trigger this.

walles commented 10 months ago

Do you have a Powershell repro case that you could share?

scottbilas commented 10 months ago

I managed to get a simple repro with a default prompt, running with pwsh -noprofile to rule out customizations I have.

Works:

PS C:\Users\scott> 1..10 | %{ if ($_ -eq 5) { continue }; $_ } | less
1
2
3
4

Kaboom:

PS C:\Users\scott> 1..10 | %{ if ($_ -eq 5) { continue }; $_ } | moar
PS C:\Users\scott> Please post the following report at <https://github.com/walles/moar/issues>,
or e-mail it to johan.walles@gmail.com.

Version: v1.15.3
LANG   :
TERM   :

GOOS    : windows
GOARCH  : amd64
Compiler: gc
NumCPU  : 16

panic: The parameter is incorrect. [recovered]
        panic: The parameter is incorrect.

goroutine 1 [running]:
main.main.func1()
        /Users/johan/src/moar/moar.go:234 +0x4d
panic({0xc3edc0, 0xfc56b8})
        /usr/local/Cellar/go/1.20.5/libexec/src/runtime/panic.go:884 +0x213
main.startPaging(0xc0000dc280)
        /Users/johan/src/moar/moar.go:411 +0x105
main.main()
        /Users/johan/src/moar/moar.go:387 +0x100f
walles commented 10 months ago

The error trace looks a lot like #149, which is now solved.

I note that in your example it seems as if less isn't actually paging, which also indicates this might have been fixed (or at least handled better) now.

Can you try again with moar 1.15.4 or newer?

walles commented 10 months ago

I believe this should work in 5932600b6570c981073ac30972b0a003a847e1c6.

scottbilas commented 10 months ago

Sorry for delay, I had a chance to test this now.

I note that in your example it seems as if less isn't actually paging

I have LESS=--tabs=4 -RFXi in my environment (F = quit if full screen)

With the latest version, moar no longer dies, and my terminal doesn't get messed up. Yay!

Also, moar now shows me this fun little animation, which I also see in the status bar next to the 100%. What does the animation mean?

moar

Maybe that it's waiting for the pipe to close? I'm not using -follow, though..

I still get the full screen with moar even if I use -quit-if-one-screen, but I assume this is the same thing that causes the animation.

walles commented 10 months ago

Just like you say, the animation means that the input pipe is still open.

With --quit-if-one-screen, moar will exit if:

  1. The screen is not full (true in your case)
  2. No more data is coming (false in your case, since the input pipe is still open)

This is why moar is still paging. If you want it to stop in this case, make sure the other end of the pipe closes when there's no more data for moar to read.

Regarding --follow, moar will always read the input stream in the background.

After > one page of input:

scottbilas commented 10 months ago

Great, thanks for explaining what's going on.

I've gotten used to how less works, but prefer the way moar does it.