Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when piping to a pager like less, bat #86

Closed
bb opened this issue Feb 9, 2021 · 11 comments · Fixed by #118
Closed

Crash when piping to a pager like less, bat #86

bb opened this issue Feb 9, 2021 · 11 comments · Fixed by #118
Labels
bug Something isn't working

Comments

@bb
Copy link

bb commented Feb 9, 2021

jql crashes for me when piping the output to a pager like less or bat and the output is not fully read (because it's longer than the viewport). I'm running version 2.9.3. installed via brew on macos (latest version).

This works as it only provides very few lines of output for my example file:

RUST_BACKTRACE=1 jql '.!'  tmp.json | less

However, when outputting a bit more, it crashes when I quit the pager without scrolling to the end:

RUST_BACKTRACE=1 jql '.'  tmp.json | less
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1021:9
stack backtrace:
   0: _rust_begin_unwind
   1: std::panicking::begin_panic_fmt
   2: jql::render_output
   3: <async_std::task::builder::SupportTaskLocals<F> as core::future::future::Future>::poll
   4: jql::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[1]    60860 abort      RUST_BACKTRACE=1 jql '.' tmp.json |
       60861 done       less

When I scroll the less to the end (e.g. by pressing G key) or when I pipe to cat which also reads everything, there's no issue.

Please let me know when you need more information.

@yamafaktory
Copy link
Owner

Hi @bb and thanks for reporting the issue.
So to recap, it works with cat but not with less, right?
Can you provide the failing JSON file?
I'll have a look at it anyway.

@bb
Copy link
Author

bb commented Feb 11, 2021

Yes. Works with any consumer which reads to the end, e.g. cat. Fails with those who only read part of the output, e.g. less (assuming output is longer than screen height. Otherwise less reads all of it and it works).

@bb
Copy link
Author

bb commented Feb 11, 2021

Just noticed I only answered one of the two question. I worked with geojson files from https://osm-boundaries.com/Map. But the actual file does not matter, as long as it's longer than the screen size and bigger than some internal buffer.

The geojson files need OSM login, but there here are two examples of (non-geojson) json data:

This fails:
curl https://osm-boundaries.com/ajax.php\?cmd\=GetTreeContent\&db\=osm20201228\&rootId\=-2202162 | jql "." | less (If you press q in less WITHOUT scrolling down. File size is 2700k.)

While this works:
curl https://osm-boundaries.com/ajax.php\?cmd\=GetTreeContent\&db\=osm20201228\&rootId\=%23 | jql "." | less (16k).

@yamafaktory
Copy link
Owner

Yeah, the problem is that jql reads the whole piped content in memory and expect it to be valid JSON. less - and by extension bat (which is using less by default https://github.com/sharkdp/bat#automatic-paging) - is paging the output which is thus incomplete JSON.
I might have to look at https://docs.rs/serde_json/1.0.62/serde_json/struct.StreamDeserializer.html.
Will keep you posted.

@yamafaktory
Copy link
Owner

@bb sorry for the late reply!

I was checking again and indeed jql is already using what I mentioned in the previous message. It seems to be a Rust issue in the end rust-lang/rust#46016.

They mentioned multiple workarounds including this one used by ripgrep https://github.com/BurntSushi/ripgrep/pull/586/files.

Since it's using unsafe, I'd prefer to avoid it... but it might be the only solution currently available.

@yamafaktory yamafaktory added the bug Something isn't working label Feb 16, 2021
@bb
Copy link
Author

bb commented Feb 16, 2021

@yamafaktory thanks for following up. No need to worry or feel sorry. Honestly, I finished the stuff I was using jql for and don't need it now or anytime soon. So it's absolutely not critical nor urgent for me...

My workaround was to press Shift-G in less so it scrolls to the end and thus prevents the crash.

@yerke
Copy link

yerke commented Jan 27, 2022

@yamafaktory You might want to try the approach similar to crev-dev/cargo-crev@3f3dedf (as discussed in crev-dev/cargo-crev#287). No unsafe there.

@yamafaktory
Copy link
Owner

@yerke I guess this is what I mentioned a while ago here #86 (comment)

@yamafaktory
Copy link
Owner

yamafaktory commented Jan 27, 2022

@yerke nevermind this was just one of the links, I see what you mean (commit).

@yamafaktory
Copy link
Owner

I'm going to release a new version soon, thanks @yerke!

Looking good now: https://asciinema.org/a/465294.

@yamafaktory
Copy link
Owner

@bb A new version has been released. Don't hesitate to re-open the issue if the fix doesn't work has expected (works for me locally and in the CI).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants