Clean up ncurses mess in terminal after a crash

12,434

Solution 1

Command,

stty sane

did the job. If enter doesn't work, you may use ^J.

stty sane ^J

Sometimes CR/LF interpretation is broken so use the ^J explicitly.

Solution 2

ncurses (any curses implementation) sets the terminal modes to raw and noecho while running, and allows applications to simulate these using the raw and noraw, echo and noecho functions. It does this for performance, to avoid waiting when switching between these modes.

When an application calls endwin, ncurses restores the terminal modes. It can also do this for reset_shell_mode, though endwin is used far more often.

If your application crashes, or exits without restoring the terminal modes using endwin, the most obvious problem is that you cannot see what you are typing, and that pressing enter does not work.

ncurses provides a signal handler to catch the user-initiated signals SIGINT, SIGTERM, and will cleanup when those are caught. It does not try to catch SIGSEGV because at that point, your application is dead and trying to resurrect it to repair things is counter productive.

Some people might advise using stty sane to restore the terminal modes. That "works", but on Unix platforms is likely to leave your erase key set to an unexpected value. It happens to work as expected for Linux- and modern BSD-systems.

However, beyond that, ncurses normally resets

  • colors (default colors for the terminal)
  • line-drawing (disabled)
  • mouse protocol (to disable it)

If your application uses any of these features, then the reset command is the appropriate choice. It usually clears the screen as well (perhaps not what was wanted). And it uses fewer characters:

resetcontrolJ
stty sanecontrolJ

Further reading:

Solution 3

The command

reset

also worked for me on Ubuntu, probably overkill though. What worked best was setting an alias like:

alias 'clean'='stty sane;clear;'

in my .bash_aliases as I found myself needing to do this alot in debugging.

Solution 4

Write a signal handler for SIGSEGV, etc. that calls endwin().

Share:
12,434
Dilawar
Author by

Dilawar

I am computational neuroscientist and an electrical engineer.

Updated on June 23, 2022

Comments

  • Dilawar
    Dilawar about 2 years

    I am drawing a TUI using ncurses. The trouble is that whenever my program gets seg-fault, my terminal is left in mess. I can not see what I am typing. Its a pain since I am working over ssh. I have mitigated some of the effect by using screen.

    I would like to know if there is a command which will refresh my terminal after seg-fault in ncurses so that my terminal starts behaving normally.

  • AlwaysLearning
    AlwaysLearning almost 8 years
    I still do not see the cursor.
  • AlwaysLearning
    AlwaysLearning almost 8 years
    I still do not see the cursor.
  • AlwaysLearning
    AlwaysLearning almost 8 years
    Here is how to do it (only be sure to handle SIGSEGV and not SIGTERM): linuxquestions.org/questions/programming-9/…
  • serup
    serup almost 8 years
    suggest writting the control J as below comment Thomas Dickey
  • mekb
    mekb about 3 years
    scroll now instead goes to a different command in history instead of scrolling up and down in terminal view
  • Thomas Dickey
    Thomas Dickey about 3 years
    The comment about "older terminal" is incorrect.
  • Thomas Dickey
    Thomas Dickey about 3 years
    That won't work (will actually aggravate the situation).
  • Thomas Dickey
    Thomas Dickey about 3 years
    The reset command "should" do this, as a side-effect of the initialization strings it sends. The terminal description may not do that, but tput cnorm is more explicit and more likely to work.
  • Dilawar
    Dilawar about 3 years
    @ThomasDickey Fixed and updated the answer.