免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1030 | 回复: 0
打印 上一主题 下一主题

Debugging Ncurses Programs [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-02 12:10 |只看该作者 |倒序浏览
Activities like printing characters to a screen, moving the cursor, and changing the color of character output are collectively known as screen handling. By its nature, screen handling is very terminal dependent, however, the terminfo and termcap mechanisms were devised to provide terminal independent screen handling. The
curses
library (a pun on the term "cursor optimization") was created to provide a screen handling API for C programmers. The goal of curses was to provide a fast, portable, and terminal independent C API to handle device dependent terminal codes.
Curses has a very long and twisted history. However, the most commonly used modern implementation of the library is called new curses, or
ncurses
, for short, which is maintained by
Thomas E. Dickey
. Ncurses is a GNU project released under an MIT style licence and is used under nearly all modern Unixes including GNU/Linux, and Mac OS X. There are now many extensions to ncurses which includes panels, menus and even a full featured widget set: the
Curses Development Kit
(CDK).
Getting Started
To follow along, download
ncurses1
.
1   // ncurses1.c
2   #include
3   #include
4   #include
5   
6   unsigned int Seeder(void);
7   int Irand(int low, int high);
8   void Print_A_Character(void);
9   
10  int main(void)
11  {
12       atexit( (void *)endwin );
13       initscr();
14       Seeder();
15  
16       for (int i = 0; i
Compile and run the program. It should fill your console (or xterm) with characters. It has a bug though: the top row and first column seem to be devoid of characters:


Since the probability of that happening is miniscule (and gets smaller with each passing second), there must be a bug in the program.
You need to do a bit more to use GDB with a program that uses ncurses. The problem is that GDB's I/O is intermixed with the program's I/O. Once you get used to it, this is not normally a problem. But when the program performs screen handling, it becomes difficult, if not impossible, to keep track of your debugging session. To see this in action, start GDB on the executable, set a breakpoint at Print_A_Character(), and run the program.
   $ gdb debugging_ncurses
   (gdb) break Print_A_Character
   Breakpoint 1 at 0x80486fd: file debugging_ncurses.c, line 26.
   (gdb) run
   Starting program: code/ncurses/debugging_ncurses
   
   Breakpoint 1, Print_A_Character () at debugging_ncurses.c:26
   26              int x = Irand(1, COLS);
Now issue continue 50 a few times. You should see a big mess. Here's what I see:


Quit GDB when you've had enough. Clearly, we need a way to separate GDB's I/O from the program's I/O when screen handling is done.
Separating the Input/Output
You'll need two terminals (either two consoles or two xterms): One for the program's I/O and another for GDB's I/O. Separating out the two I/O will resolve the problem nicely. I'll be using the word `xterm', but the same thing applies to all non-login terminals like rxvt and eterm, and login terminals like virtual consoles.
  • Go to the first xterm and find its device file using either tty or who am i. This will be the xterm with GDB's I/O.:    $ tty
       /dev/pts/1
       $ who am i
       p        pts/1        May 26 12:44 (:0.0)
  • Go to the second xterm and find its device file. This will be the xterm with our program's I/O:    $ tty
       /dev/pts/4
  • Go back to the first xterm and start a debugging session. Set a breakpoint at Print_A_Character().    $ gdb debugging_ncurses
       (gdb) break Print_A_Character
       Breakpoint 1 at 0x80486fd: file debugging_ncurses.c, line 26.
       (gdb)
  • GDB's tty command instructs GDB to redirect the program's I/O to another terminal. The argument to tty is the device file of the terminal you wish the program I/O to go. In this case, I want the program's I/O to go to the second xterm, pts/4. If you're following along, use whatever device file you obtained in step 2:    (gdb) tty /dev/pts/4
       (gdb)
  • Lastly, go to the second xterm (that contains the program's I/O) and tell the shell to sleep for a long time. This is so that anything we type in that window will be sure to go to our program rather than the shell. The amount of time is arbitrary, but pick a time that's longer than you suspect the debugging session will last. This tells the shell to "do nothing" for 100000 seconds:    $ tty
       /dev/pts/4
       $ sleep 100000
  • Go back to the first xterm which is running GDB and debug to your heart's content. When you're done, you can go back to the program output window and slap it with a control-c to break out of the sleep.
    Debugging Ncurses Example
    Let's go through a sample debugging session of debugging_ncurses.c. The problem was that the first row and column aren't being printed to. At first guess, we might suspect that the random number generator is at fault.


    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/11786/showart_1888460.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP