【转贴】gdb中的信号(signal)相关调试技巧

一篇不错的帖子,讲的是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 <stdio.h> 
#include <signal.h> 
#include <unistd.h> 

/* 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. 

print 
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 <singal>,UNIX的系统信号通常从1到15。所以<singal>取值也在这个范围。 

single命令和shell的kill命令不同,系统的kill命令发信号给被调试程序时,是由GDB截获的,而single命令所发出一信号则是直接发给被调试程序的。 
已标记关键词 清除标记
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹?   那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页