gdb调试c++异常,系统调用,库的load,unload,信号异常等.
Others
2021-11-28 22:29:48
views: null
-
捕获C++
异常
-
格式
catch throw [regexp] | catch rethrow [regexp] | catch catch [regexp]
-
说明
- 以正则表达式的方式指定感兴趣的异常.
- 在
throw
阶段捕获.
$_exception
获取抛出的什么异常.
- 无参表示捕获所有.
-
局限
- 系统依赖.遵循
gnu-v3
标准的c++ ABI
支持这种断点.
-
案例
-
代码
#include<stdio.h>
int main(){
try{
throw 2;
}
catch(int a){
printf("%d\n",a);
}
}
-
编译执行
g++ -g test.cpp -o a.out
gdb -q -ex 'catch throw int' -ex 'r' -ex 'bt' ./a.out
-
查看catch
异常的位置
g++ -g test.cpp -o a.out
gdb -q -ex 'catch catch int' -ex 'r' -ex 'bt' ./a.out
-
二次抛出
-
代码
int main(){
try{
throw 2;
}
catch(int a){
printf("%d\n",a);
throw a;
}
}
-
编译执行指令
g++ -g test.cpp -o a.out
gdb -q -ex 'catch rethrow int' -ex 'r' -ex 'bt' ./a.out
-
捕获系统调用
-
格式
catch syscall | catch syscall [name | number | group:groupname | g:groupname] ...
-
说明
- 无参表示捕获所有系统调用.
- 有参则捕获指定.
- 按名字,按系统调用编号,按分组.都可.
-
案例
-
代码
#include<stdio.h>
int main(){
try{
throw 2;
}
catch(int a){
printf("%d\n",a);
}
}
-
编译执行
g++ -g test.cpp -o a.out
gdb -q -ex 'catch syscall' -ex 'r' -ex 'bt' ./a.out
-
捕获printf
gdb -q -ex 'catch syscall write' -ex 'r' -ex 'bt' ./a.out
-
捕获库的装载卸载
-
格式
catch load [regexp] | catch unload [regexp]
-
说明
-
案例
-
代码
#include<stdio.h>
int main(){
try{
throw 2;
}
catch(int a){
printf("%d\n",a);
}
}
-
编译执行
g++ -g test.cpp -o a.out
gdb -q -ex 'catch load libc' -ex 'r' -ex 'bt' ./a.out
-
使用场景
- 观察某个库的加载卸载,比如
dlopen,dlclose
之类.
-
捕获信号
-
格式
catch signal [signal... | ‘all’]
-
说明
- 无参所有信号,
gdb
默认捕获一些信号.
SIG
然后tab
补全.
-
常见
-
信号与异常
-
说明
C++
的捕获机制,linux
下并不是所有的都会被捕获到.
- 比如:空指针异常和算术异常和指令异常.
- 或者说信号都不能被异常捕获机制捕获.
-
信号处理
- 信号默认处理方式,和信号自定义处理方式.
- 信号处理进程共享,不会存在线程特有处理方式.
-
信号分发
- 信号分发会发给合适的线程.
- 没有阻塞,在执行的,循环搜索.
- 分发给指定线程的信号:空指针异常和算术异常和指令异常.
-
信号处理周期
- 每次从内核出来会检查进程状态,是否有信号需要处理.
SIGPENDING
.
-
信号信息
- 一般通过
siginfo_t
打包信号信息,没有内存保存则仅仅是信号值.
-
信号区分
- 普通信号
0-32
.实时信号33-64
.
- 普通信号用
set
存储(uint位运算)
,实时信号用队列存储.
- 普通信号不存在重复的,实时信号可重复.
-
信号处理函数
- 一般有默认,但是
SIGKILL == 9
不能被自定义,也无法捕获,这种是为了防止牛皮癣,存在干不掉的进程.1
号进程就是牛皮癣.
Origin blog.csdn.net/rubikchen/article/details/119950628