markbt / streampager

A pager for command output or large files
MIT License
45 stars 11 forks source link

`sp < README.md` only partially fills the screen on macos #1

Closed wez closed 5 years ago

wez commented 5 years ago

This may end up being a termwiz bug...

It looks like it reads twenty-something lines and stops; looks like we're blocked in read:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00007fff6a223ef2 libsystem_kernel.dylib`read + 10
    frame #1: 0x000000010ddce523 sp`_$LT$termwiz..terminal..unix..UnixTerminal$u20$as$u20$termwiz..terminal..Terminal$GT$::poll_input::h67d2894f39979c8d + 819
    frame #2: 0x000000010dd0419b sp`sp::event::EventStream::get::h3859247ddb8f6064 + 635
    frame #3: 0x000000010dcdc443 sp`sp::display::start::hd7cd8f6d1e4cc3a8 + 3139
    frame #4: 0x000000010dcc6897 sp`sp::main::ha85757a29d4d2a6d + 5991
    frame #5: 0x000000010dcd8c16 sp`std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h3afe26cb7fcbb116 + 6
    frame #6: 0x000000010de63788 sp`do_call<closure,i32> [inlined] {{closure}} at rt.rs:49:12 [opt]
    frame #7: 0x000000010de6377c sp`do_call<closure,i32> at panicking.rs:293 [opt]
    frame #8: 0x000000010de6a7bf sp`__rust_maybe_catch_panic at lib.rs:87:7 [opt]
    frame #9: 0x000000010de641ae sp`lang_start_internal [inlined] try<i32,closure> at panicking.rs:272:12 [opt]
    frame #10: 0x000000010de6417b sp`lang_start_internal [inlined] catch_unwind<closure,i32> at panic.rs:388 [opt]
    frame #11: 0x000000010de6417b sp`lang_start_internal at rt.rs:48 [opt]
    frame #12: 0x000000010dccb7b9 sp`main + 41
    frame #13: 0x00007fff6a0ed3d5 libdyld.dylib`start + 1
    frame #14: 0x00007fff6a0ed3d5 libdyld.dylib`start + 1

Possibly related to https://github.com/wez/wezterm/commit/cc0d2e5493f0f2b810ca243c650fa02d83084937

wez commented 5 years ago

and to be clear: it does respond to input, it just looks funny until the first keypress because the screen is incomplete and there's no status bar at the bottom

markbt commented 5 years ago

All the read calls in poll_input should be non-blocking. Can you work out which fd it's reading?

wez commented 5 years ago
(lldb) up
frame #2: 0x000000010cafc5fe sp`_$LT$termwiz..terminal..unix..UnixTerminal$u20$as$u20$termwiz..terminal..Terminal$GT$::poll_input::h6fbe481e85ab86cb(self=0x00007ffee33864b0, wait=Option<core::time::Duration> @ 0x00007ffee3385640) at unix.rs:496:18
   493
   494          if pfd[1].revents != 0 {
   495              let mut buf = [0u8; 64];
-> 496              match self.read.read(&mut buf) {
   497                  Ok(n) => {
   498                      let input_queue = &mut self.input_queue;
   499                      self.input_parser.parse(
(lldb)
wez commented 5 years ago

(but note that I'm temporarily pointing this to termwiz 0.2 because I think you may have force-pushed the wezterm branch in your cargo.toml; I'll publish 0.3.0 with your latest changes as soon as the CI is done building them)

wez commented 5 years ago

In this case, poll_input is being called with wait=None, which leads to that blocking read. Digging into this a bit more, this appears to be yet another macOS poll(2) bug. This stackoverflow page has a similar question that manifests the same way: https://stackoverflow.com/questions/591826/it-really-looks-like-os-x-has-a-bug-when-using-poll-on-a-named-pipe-fifo I'm seeing the poll call return POLLNVAL for the tty input stream.

wez commented 5 years ago

I'll take this as a termwiz issue: I think we need to use select(2) to get reliable behavior on macos :-/

markbt commented 5 years ago

It looks like it is that bug. In poll_input(wait = None), only the call to poll should be blocking - the reads to the other pipes should all be nonblocking (set up elsewhere in the module).

wez commented 5 years ago

I have a version of this that uses select(2) on macos, but now the behavior is that we're blocked forever in select(2) and the screen isn't fully painted. I think part of the problem here is that poll_input is being called with wait=None before the screen has been fully painted at least once. I think there is still something fishy with polling the tty on macos and I'm continuing to poke at this.

wez commented 5 years ago

Traced this to three issues: