Skip to content

tcgetattr / tcsetattr seemingly behaving weirdly when piping output from VM into less and quitting #36453

@jensjoha

Description

@jensjoha

On my machine at least, doing this:
out/ReleaseX64/dart pkg/kernel/bin/dump.dart out/ReleaseX64/vm_platform_strong.dill 2>stderrstuff | less
and immediately (as soon as less actually appears) typing q to quit less, my terminal becomes unresponsive (i.e. it doesn't echo what I type).

Applying a patch like this

diff --git a/runtime/bin/console_posix.cc b/runtime/bin/console_posix.cc
index af28e153e6c..4677525632c 100644
--- a/runtime/bin/console_posix.cc
+++ b/runtime/bin/console_posix.cc
@@ -53,6 +53,7 @@ class PosixConsole {
     if (status != 0) {
       return;
     }
+    fprintf(stderr, "Saving %d\n", term.c_lflag);
     *flag = term.c_lflag;
   }
 
@@ -63,9 +64,11 @@ class PosixConsole {
     struct termios term;
     int status = TEMP_FAILURE_RETRY(tcgetattr(fd, &term));
     if (status != 0) {
+      fprintf(stderr, "Setting restore mode (3) (%ld) failed with status %d!\n", fd, status);
       return;
     }
     term.c_lflag = flag;
+    fprintf(stderr, "Setting restore mode (3) (%ld) (%d)!\n", fd, flag);
     VOID_TEMP_FAILURE_RETRY(tcsetattr(fd, TCSANOW, &term));
   }

yields

Saving 35329
Setting restore mode (3) (0) (35329)!

in the file stderrstuff.

If I instead just had run out/ReleaseX64/dart hello.dart the output is

Saving 35387
Saving 35387
Saving 35387
Hello, World!
Setting restore mode (3) (1) (35387)!
Setting restore mode (3) (2) (35387)!
Setting restore mode (3) (0) (35387)!

(according to calls to stty -a in both cases, it seems to be ICANON, ECHO, ECHOE and ECHOK missing in the case where the terminal becomes unresponsive).

If I remove the call to tcsetattr the problem goes way (though this isn't a real solution).

So it seems that tcgetattr gives a "wrong" result somehow.

Interestingly enough, if I go to the end of the less input (G) before quitting (q) the problem goes away too, despite that the content of stderrstuff still being the same.

My guess as to what happens is this:

  • less sets -ICANON, -ECHO, -ECHOE, -ECHOK before dart calls tcgetattr
  • If less goes to the end (and the dart process shuts down (it doesn't appear to shut down before less goes to the end)) before quitting less, dart sets the wrong stuff, but less (once it quit) sets the right stuff. Result in this case: Everything is fine.
  • If less is quit before going to the end, less quits and sets the right stuff before dart quits and sets the wrong stuff. Result in this case: Terminal becomes unresponsive.
    So, said another way, my guess is that this is basically a kind of race condition between dart and less :/

/cc @mraleph any ideas or ideas of who to ping on this?

Metadata

Metadata

Assignees

Labels

P2A bug or feature request we're likely to work onarea-core-librarySDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries.library-iotype-bugIncorrect behavior (everything from a crash to more subtle misbehavior)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions