A Trick for Debugging Ncurses Applications

Currently I'm developing another roguelike game, using ncurses as a frontend. (Whether or not this game will ever see the light of day is, as always, an open question.) Debugging with ncurses is difficult. My usual method is to fprintf information to stderr [0], but ncurses already outputs things to the terminal, including complex formatting data. With ncurses, "printf debugging" is quite useless: debug info will cascade across the screen in a strange cylindrical staircase pattern, thereby rendering the content of the game (player, dungeon, HUD, etc) illegible. For a long time I did not know of a good workaround.

If you're a responsible lad and have read the man pages, you should know that terminal emulators have a file associated with them called /dev/ttyXX, where XX is an alphanumeric ID. These files are special devices that act as an I/O interface to the terminal. You can get a terminal window's associated tty by running the tty(1) command.

Suppose you have two terminal windows open, which we shall call TERM1 and TERM2. You run tty in TERM1 and discover that its tty device is /dev/ttyp3. Then in TERM2, you run the command echo deja vu > /dev/ttyp3. You should see the text "deja vu" appear in TERM1. In other words, you can use tty files to print things from one terminal to another.

Now the final point: if you're working on an ncurses program, you can call fprintf to print debugging information to stderr as necessary. Then you can run your program using a command like ./rogue 2>/dev/ttyXX to redirect stderr to another terminal window. Your ncurses program and debugging output no longer interfere with each other, hooray.

So there it is. This technique may have been obvious to you, or you may have seen it elsewhere before; but I never have, so I decided to document it here in hopes that someone else will find it useful.


^0: For lower-level debugging I would use gdb, lldb or objdump. For the first two programs, it might be necessary to use a similar redirection technique as described in this article, although it would probably necessitate further trickery.