信号的处理
程序是和网络相关的,调试期间经常地收到SIGPIPE,导致gdb停下来。看了一下gdb info,解决方法很简单。用handle命令设置一下缺省signal的处理行为就可以了:
如果连提示信息都不想看见,就可以这样设置:
handle SIGPIPE nostop
就可以了。其他相关信号也可以类似处理。想了解目前的signal状态可以使用
handle SIGPIPE nostop noprint
info signal
察看。
启动配置文件
GDB使用中比较麻烦的事情,就是每次启动,还要手动敲一把命令,特别是断点比较多的情况,这个特便影响,工作效率。查了一下gdb info,gdb支持自动读取一个启动脚本文件.gdbinit,所以经常输入的启动命令,就都可以写在gdb启动目录的.gdbinit里面。比如
GDB和bash类似,也支持source这个命令,执行另外一个脚本文件。所以可以修改一下.gdbinit:
.gdbinit:
file myapp
handle SIGPIPE nostop
break ss.c:100
break ss.c:200
run
这样修改的断点配置,只需要编辑gdb.break就可以了。再后来,偶而还是需要单独启动GDB,不想执行自动脚本,于是又改进了一下。首先把.gdbinit命名为gdb.init,然后定义一个shell alias:
.gdbinit:
file myapp
handle SIGPIPE nostop
source gdb.break
run
gdb.break:
break ss.c:100
break ss.c:200
$ alias .gdb=”gdb -x gdb.init”
这样如果需要使用自动脚本,就用.gdb命令,否则用gdb进入交互状态的gdb。这样配置以后可以一个简单命令就开始调试,整个效率就能提高不少。
注:转自http://blog.scaner.i.thu.cn/index.php/2006/04/15/gdb-tips-1/
注解
1alias命令
alias
顾名思义就是起别名的意思,在linux里,可以通过alias命令为常用命令设置快捷方式,命令格式如下: alias name='command' 例如:alias del='rm'
欲显示系统已有别名,直接使用 alias或alias -p
若需要设置的命令别名比较多,可以直接修改/etc/bashrc或~/.bashrc,将需要的别名写到里面即可,不同之处是/etc/bashrc设置的别名对于所有登录用户都起作用,而~/.bashrc只对目前用户起作用。
比如:
handle SIGUSR2 nostop
一篇不错的帖子,讲的是gdb中的信号(signal)相关调试技巧
转自Magic C++论坛
http://www.magicunix.com/index_ch.html
http://www.magicunix.com/cgi-bin1/forum_cn/ultimatebb.cgi?ubb=get_topic&f=1&t=000060#000003
引用:
--------------------------------------------------------------------------------
原发贴者 Couger:
我写了一个INT信号的处理函数,在处理函数里设置断点后go,但是在console下按Ctrl-C后MC并没有进入处理函数,而console下的程序也直接退出,没有给出希望的输出。
--------------------------------------------------------------------------------
在console下按Ctrl-C后确实发送了SIGINT信号,但是gdb里的缺省设置将会导致由GDB截获的该信息,调试的应用程序无法接受到该信号。
有两种方法可以使调试的应用程序接受到信号:
(1)改变gdb信号处理的设置
比如,以下设置会告诉gdb在接收到SIGINT时不要停止、打印出来、传递给调试目标程序
=====================================
(gdb) handle SIGINT nostop print pass
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y
Signal Stop Print Pass to program Description
SIGINT No Yes Yes Interrupt
(gdb)
=====================================
(2)使用gdb命令直接向调试的应用程序发送信号
首先在你希望发送信号的语句处设置断点,然后运行程序,当停止到断点所在位置后,用gdb的signal命令发送信号给调试目标程序
====================================
(gdb) signal SIGINT
Continuing with signal SIGINT.
Breakpoint 1, handler (signal=2) at main.cpp:15
15 printf("Signal handler...\n"
;
====================================
;-( 但是这两种方法目前MC都还不支持,所以需要等新版本的MC才可以方便的支持你这种调试情况,呵呵。临时先手工调试一下吧。
新版本将会增加
(1)调试器的信号处理设置
(2)支持发送信号命令
调试用例:
============
/*
* This program is uninterruptable with
* Ctrl+C, uses signal handler
*/
#include ;
#include ;
#include ;
/* The signal handler function */
void handler( int signal ) {
printf("Signal handler...\n"
;
psignal( signal, "Signal: "
;
} /*handler*/
main() {
/* Registering the handler, catching
SIGINT signals */
signal( SIGINT, handler );
/* Do nothing */
while( 1 ) {
printf("Running...\n"
;
sleep(10);
} /*while*/
} /*main*/
============
改变gdb的信号处理设置
============
5.3 Signals
A signal is an asynchronous event that can happen in a program. The
operating system defines the possible kinds of signals, and gives each
kind a name and a number. For example, in Unix SIGINT is the signal a
program gets when you type an interrupt character (often C-c); SIGSEGV
is the signal a program gets from referencing a place in memory far
away from all the areas in use; SIGALRM occurs when the alarm clock
timer goes off (which happens only if your program has requested an
alarm).
Some signals, including SIGALRM, are a normal part of the functioning
of your program. Others, such as SIGSEGV, indicate errors; these
signals are fatal (they kill your program immediately) if the program
has not specified in advance some other way to handle the signal.
SIGINT does not indicate an error in your program, but it is normally
fatal so it can carry out the purpose of the interrupt: to kill the
program.
GDB has the ability to detect any occurrence of a signal in your
program. You can tell GDB in advance what to do for each kind of
signal.
Normally, GDB is set up to let the non-erroneous signals like SIGALRM
be silently passed to your program (so as not to interfere with their
role in the program's functioning) but to stop your program immediately
whenever an error signal happens. You can change these settings with
the handle command.
info signals
info handle
Print a table of all the kinds of signals and how GDB has been told to
handle each one. You can use this to see the signal numbers of all the
defined types of signals.
info handle is an alias for info signals.
handle signal keywords...
Change the way GDB handles signal signal. signal can be the number of a
signal or its name (with or without the `SIG' at the beginning); a list
of signal numbers of the form `low-high'; or the word `all', meaning
all the known signals. The keywords say what change to make.
The keywords allowed by the handle command can be abbreviated. Their full names are:
nostop
GDB should not stop your program when this signal happens. It may still
print a message telling you that the signal has come in.
stop
GDB should stop your program when this signal happens. This implies the print keyword as well.
GDB should print a message when this signal happens.
noprint
GDB should not mention the occurrence of the signal at all. This implies the nostop keyword as well.
pass
noignore
GDB should allow your program to see this signal; your program can
handle the signal, or else it may terminate if the signal is fatal and
not handled. pass and noignore are synonyms.
nopass
ignore
GDB should not allow your program to see this signal. nopass and ignore are synonyms.
When a signal stops your program, the signal is not visible to the
program until you continue. Your program sees the signal then, if pass
is in effect for the signal in question at that time. In other words,
after GDB reports a signal, you can use the handle command with pass or
nopass to control whether your program sees that signal when you
continue.
The default is set to nostop, noprint, pass for non-erroneous signals
such as SIGALRM, SIGWINCH and SIGCHLD, and to stop, print, pass for the
erroneous signals.
You can also use the signal command to prevent your program from seeing
a signal, or cause it to see a signal it normally would not see, or to
give it any signal at any time. For example, if your program stopped
due to some sort of memory reference error, you might store correct
values into the erroneous variables and continue, hoping to see more
execution; but your program would probably terminate immediately as a
result of the fatal signal once it saw the signal. To prevent this, you
can continue with `signal 0'. See section Giving your program a signal.
============
直接使用gdb signal命令发送信号给调试目标程序
================
三、产生信号
使用singal命令,可以产生一个信号给被调试的程序。如:中断信号Ctrl+C。这非常方便于程序的调试,可以在程序运行的任意位置设置断点,并在该断点用GDB产生一个信号,这种精确地在某处产生信号非常有利程序的调试。
语法是:signal ;,UNIX的系统信号通常从1到15。所以;取值也在这个范围。
single命令和shell的kill命令不同,系统的kill命令发信号给被调试程序时,是由GDB截获的,而single命令所发出一信号则是直接发给被调试程序的。
====================