目录
1.信号的保存
信号其他相关常见概念
•实际执行信号的处理动作称为信号递达(Delivery)
递达方式有三种:1.自定义 2.默认 3.忽略
•信号从产生到递达之间的状态,称为信号未决(Pending)。
信号在位图里,还没来得及处理!
•进程可以选择阻塞(Block)某个信号。
•被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
阻塞屏蔽信号
•注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的⼀种处理动作。
这些概念在内核中的具体表现
三张表

pending--unsigned int pending--保存收到的新号的位图 未决表
未决表 比特位的位置:表示的是第几个信号
比特位的内容:是否收到!
比特位的位置:信号的编号(1-31)
比特位的内容:0 或 1
1:收到了这个信号(信号已产生,但还没被处理)
0:没有收到这个信号
block --unsigned int block---也是位图
阻塞表 比特位的位置:表示的是第几个信号
比特位的内容:是否阻塞!
比特位的位置:信号的编号(1-31)
比特位的内容:0 或 1
1:这个信号被阻塞(暂时不递达)
0:这个信号不被阻塞(可以递达)
pending & (-block) 剩下的结果就是可以直接被递达的
handler --sighandler_t handler31---函数指针数组,数组下标就是信号编号!
处理动作表
数组下标:信号的编号(1-31)
数组元素的值:
SIG_DFL:默认处理
SIG_IGN:忽略信号
用户自定义函数指针
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
注册进程,处理信号的方法本质就是修改handler表
三张表合起来共同支撑让进程识别信号
自定义捕捉
#include <iostream>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void handler(int sig)
{
std::cout<<"hello sig:"<<sig<<std::endl;
}
int main()
{
signal(2,handler);//自定义捕捉
while(true)
{
sleep(1);
std::cout<<"."<<std::endl;
}
return 0;
}

忽略信号
#include <iostream>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void handler(int sig)
{
std::cout<<"hello sig:"<<sig<<std::endl;
}
int main()
{
//signal(2,handler);//自定义捕捉
signal(2,SIG_IGN);//忽略信号
while(true)
{
sleep(1);
std::cout<<"."<<std::endl;
}
return 0;
}

恢复处理动作
#include <iostream>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void handler(int sig)
{
std::cout<<"hello sig:"<<sig<<std::endl;
signal(2,SIG_DFL);
std::cout<<"恢复处理动作"<<std::endl;
}
int main()
{
signal(2,handler);//自定义捕捉
//signal(2,SIG_IGN);//忽略信号
while(true)
{
sleep(1);
std::cout<<"."<<std::endl;
}
return 0;
}

所谓的SIG_DFL、SIG_IGN也是写成宏了
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
把0值和1值强转成了这个类型

横着看,对于一号信号来讲,没有block、pending,处理动作是默认

像二号信号,pending位为1收到了二号信号但这个信号没有办法被递达,因为block位置1
三号信号,没有收到三号信号,block为1依旧保持阻塞着
• 每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有⼀个函数指针表⽰处理动作。信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。在上图的例子中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。
• SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。
• SIGQUIT信号未产生过,⼀旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。
block跟pending两者没有直接的约束关系
验证信号保存的话题:
Linux提供信号操作:
1.一定是围绕着三张表展开!
sigset_t
一个位图的操作类型
每个信号只有⼀个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集 , 这个类型可以表示每个信号的"有效"或"无效"状态,在阻塞信号集中"有效"和"无效"的含义是该信号是否被阻塞,而在未决信号集中"有效"和"无效"的含义是该信号是否处于未决状态。阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的"屏蔽"应该理解为阻塞而不是忽略。
类似权限那里的umask
位图
struct bits
{
int bitmap10;//32*10=320
}
int index=39/32=1----bitmap1
int pos-39%32=7 ---bitmap1第7个比特位
信号集操作函数
#include <signal.h>
int sigemptyset(sigset_t *set); 把一个位图清空
int sigfillset(sigset_t *set); 把位图置1
int sigaddset(sigset_t *set, int signo); 一个信号添加到集合里,这个信号是几就把那个比特位置1
int sigdelset(sigset_t *set, int signo); 删掉,置0
int sigismember(const sigset_t *set, int signo); 判断是否在集合里,判断第几个信号是否为1
sigprocmask
调用这个函数就是用来设置,更新自己的block表
调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
输入型参数 输出型参数
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
下表说明了how参数的可选值。
|-------------|------------------------------------------------|
| SIG_BLOCK | set包含了我们希望添加到当前信号屏蔽字的信号,相当于mask=mask|set |
| SIG_UNBLOCK | set包含了我们希望从当前信号屏蔽字中解除阻塞的信号,相当于mask=mask&~set |
| SIG_SETMASK | 设置当前信号屏蔽字为set所指向的值,相当于mask=set |RETURN VALUE
sigprocmask() returns 0 on success and -1 on error. In the event of an error, errno is set to indicate the cause.
返回值:若成功则为0,若出错则为-1
sigprocmask(SIG_SETMASK, &block, &oblock);
模式 含义 SIG_SETMASK直接覆盖 。把内核的屏蔽字完全替换 成 &block的内容(你当前用的这个)。SIG_BLOCK追加阻塞 。将 &block里的信号添加到当前的屏蔽字中(不覆盖其他已屏蔽信号)。SIG_UNBLOCK解除阻塞 。从当前的屏蔽字中移除 &block里的信号。
sigpending
获取当前pending信号集
NAME
sigpending, rt_sigpending - examine pending signals
SYNOPSIS
#include <signal.h>
int sigpending(sigset_t *set);
输出型参数
修改pending位图
1.键盘 2.系统调用 3.系统命令 4.硬件异常 5.软件条件
整合demo

sigismember
int sigemptyset(sigset_t *set);//清空位图结构
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
#include <iostream>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
int main()
{
//1.屏蔽2号信号
sigset_t block;
sigemptyset(&block);//清空位图
sigaddset(&block,SIGINT);//将2号的SIGINT添加到block里
// 那么当前已经对2号信号进行屏蔽了吗?没有!
//这个sigset_t类型是在栈上开辟的,将SIGINT添加到block就只是把这个类型中的比特位置1了。
//并没有设到当前进程的block表里
}
必须使用 sigprocmask 系统调用
sigprocmask(SIG_SETMASK, &block, &oblock);
将 block 里的信号列表,直接覆盖为当前进程要屏蔽的信号列表,同时把旧的屏蔽列表保存到 oblock 里
1.
#include <iostream> #include <cstdio> #include <vector> #include <functional> #include <unistd.h> #include <signal.h> #include <sys/types.h> void PrintPending(sigset_t &pending) { printf("我是一个进程(%d),pending:", getpid()); for (int signo = 31; signo >= 1; signo--) { if (sigismember(&pending, signo)) { std::cout << "1"; } else { std::cout << "0"; } } std::cout << std::endl; } int main() { // 1.屏蔽2号信号 sigset_t block, oblock; sigemptyset(&block); // 清空位图 sigemptyset(&oblock); // 清空位图 sigaddset(&block, SIGINT); // 将2号的SIGINT添加到block里 // 那么当前已经对2号信号进行屏蔽了吗?没有! // 这个sigset_t类型是在栈上开辟的,将SIGINT添加到block就只是把这个类型中的比特位置1了。 // 并没有设到当前进程的block表里 int n = sigprocmask(SIG_SETMASK, &block, &oblock); (void)n; // 4.重复获取打印过程 while (true) { // 2.获取pending信号集合 sigset_t pending; int m = sigpending(&pending); // 3.打印 PrintPending(pending); sleep(1); } return 0; }终端1
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# ./testsig 我是一个进程(123099),pending:0000000000000000000000000000000 我是一个进程(123099),pending:0000000000000000000000000000000 我是一个进程(123099),pending:0000000000000000000000000000000 我是一个进程(123099),pending:0000000000000000000000000000000 我是一个进程(123099),pending:0000000000000000000000000000000 我是一个进程(123099),pending:0000000000000000000000000000000 我是一个进程(123099),pending:0000000000000000000000000000000 我是一个进程(123099),pending:0000000000000000000000000000010 我是一个进程(123099),pending:0000000000000000000000000000010 ^C我是一个进程(123099),pending:0000000000000000000000000000010 我是一个进程(123099),pending:0000000000000000000000000000010 ^\Quit终端2
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# kill -2 123099
2.
#include <iostream> #include <cstdio> #include <vector> #include <functional> #include <unistd.h> #include <signal.h> #include <sys/types.h> void PrintPending(sigset_t &pending) { printf("我是一个进程(%d),pending:", getpid()); for (int signo = 31; signo >= 1; signo--) { if (sigismember(&pending, signo)) { std::cout << "1"; } else { std::cout << "0"; } } std::cout << std::endl; } int main() { // 1.屏蔽2号信号 sigset_t block, oblock; sigemptyset(&block); // 清空位图 sigemptyset(&oblock); // 清空位图 //sigaddset(&block, SIGINT); // 将2号的SIGINT添加到block里 // 那么当前已经对2号信号进行屏蔽了吗?没有! // 这个sigset_t类型是在栈上开辟的,将SIGINT添加到block就只是把这个类型中的比特位置1了。 // 并没有设到当前进程的block表里 for(int i = 1; i<32;i++) sigaddset(&block,i); int n = sigprocmask(SIG_SETMASK, &block, &oblock); (void)n; // 4.重复获取打印过程 while (true) { // 2.获取pending信号集合 sigset_t pending; int m = sigpending(&pending); // 3.打印 PrintPending(pending); sleep(1); } return 0; }终端1
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# ./testsig 我是一个进程(122914),pending:0000000000000000000000000000000 我是一个进程(122914),pending:0000000000000000000000000000000 我是一个进程(122914),pending:0000000000000000000000000000000 我是一个进程(122914),pending:0000000000000000000000000000000 我是一个进程(122914),pending:0000000000000000000000000000000 我是一个进程(122914),pending:0000000000000000000000000000000 我是一个进程(122914),pending:0000000000000000000000000000010 我是一个进程(122914),pending:0000000000000000000000000000010 我是一个进程(122914),pending:0000000000000000000000000000010 我是一个进程(122914),pending:0000000000000000000000000000011 我是一个进程(122914),pending:0000000000000000000000000000011 我是一个进程(122914),pending:0000000000000000000000000000011 我是一个进程(122914),pending:0000000000000000000000000000011 我是一个进程(122914),pending:0000000000000000000000000000011 我是一个进程(122914),pending:0000000000000000000000000000011 我是一个进程(122914),pending:0000000000000000000000000000011 我是一个进程(122914),pending:0000000000000000000000010000011 我是一个进程(122914),pending:0000000000000000000000010000011 我是一个进程(122914),pending:0000000000000000000000010000011 我是一个进程(122914),pending:0000000000000000000000010000011 Killed终端2
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# kill -2 122914 root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# kill -1 122914 root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# kill -8 122914 root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# kill -9 122914
9号、19号信号,不可被捕捉,不可被阻塞
3.
想看到pending位再由1变为0,加一个计数器
#include <iostream>
#include <cstdio>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void PrintPending(sigset_t &pending)
{
printf("我是一个进程(%d),pending:", getpid());
for (int signo = 31; signo >= 1; signo--)
{
if (sigismember(&pending, signo))
{
std::cout << "1";
}
else
{
std::cout << "0";
}
}
std::cout << std::endl;
}
int main()
{
// 1.屏蔽2号信号
sigset_t block, oblock;
sigemptyset(&block); // 清空位图
sigemptyset(&oblock); // 清空位图
sigaddset(&block, SIGINT); // 将2号的SIGINT添加到block里
// 那么当前已经对2号信号进行屏蔽了吗?没有!
// 这个sigset_t类型是在栈上开辟的,将SIGINT添加到block就只是把这个类型中的比特位置1了。
// 并没有设到当前进程的block表里
// for(int i = 1; i<32;i++)
// sigaddset(&block,i);
int n = sigprocmask(SIG_SETMASK, &block, &oblock);
(void)n;
// 4.重复获取打印过程
int cnt = 0;
while (true)
{
// 2.获取pending信号集合
sigset_t pending;
int m = sigpending(&pending);
// 3.打印
PrintPending(pending);
if(cnt == 10)
{
//5.恢复对2号信号的block情况
sigprocmask(SIG_SETMASK, &oblock,nullptr);
std::cout<< "解除对2号的屏蔽"<<std::endl;
}
sleep(1);
cnt++;
}
return 0;
}
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# ./testsig
我是一个进程(123367),pending:0000000000000000000000000000000
我是一个进程(123367),pending:0000000000000000000000000000000
我是一个进程(123367),pending:0000000000000000000000000000000
^C我是一个进程(123367),pending:0000000000000000000000000000010
我是一个进程(123367),pending:0000000000000000000000000000010
我是一个进程(123367),pending:0000000000000000000000000000010
我是一个进程(123367),pending:0000000000000000000000000000010
我是一个进程(123367),pending:0000000000000000000000000000010
我是一个进程(123367),pending:0000000000000000000000000000010
我是一个进程(123367),pending:0000000000000000000000000000010
我是一个进程(123367),pending:0000000000000000000000000000010
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2#
我们当前对2号是屏蔽的,对2号信号的默认动作是终止进程。当解除屏蔽,2号动作就立即被递达。
对2号信号做一下自定义捕捉
#include <iostream>
#include <cstdio>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void PrintPending(sigset_t &pending)
{
printf("我是一个进程(%d),pending:", getpid());
for (int signo = 31; signo >= 1; signo--)
{
if (sigismember(&pending, signo))
{
std::cout << "1";
}
else
{
std::cout << "0";
}
}
std::cout << std::endl;
}
void handler(int sig)
{
std::cout<<"递达"<<sig<<"信号!"<<std::endl;
}
int main()
{
signal(SIGINT,handler);
// 1.屏蔽2号信号
sigset_t block, oblock;
sigemptyset(&block); // 清空位图
sigemptyset(&oblock); // 清空位图
sigaddset(&block, SIGINT); // 将2号的SIGINT添加到block里
// 那么当前已经对2号信号进行屏蔽了吗?没有!
// 这个sigset_t类型是在栈上开辟的,将SIGINT添加到block就只是把这个类型中的比特位置1了。
// 并没有设到当前进程的block表里
// for(int i = 1; i<32;i++)
// sigaddset(&block,i);
int n = sigprocmask(SIG_SETMASK, &block, &oblock);
(void)n;
// 4.重复获取打印过程
int cnt = 0;
while (true)
{
// 2.获取pending信号集合
sigset_t pending;
int m = sigpending(&pending);
// 3.打印
PrintPending(pending);
if(cnt == 10)
{
//5.恢复对2号信号的block情况
std::cout<< "解除对2号的屏蔽"<<std::endl;
sigprocmask(SIG_SETMASK, &oblock,nullptr);
}
sleep(1);
cnt++;
}
return 0;
}
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# ./testsig
我是一个进程(123526),pending:0000000000000000000000000000000
我是一个进程(123526),pending:0000000000000000000000000000000
我是一个进程(123526),pending:0000000000000000000000000000000
^C我是一个进程(123526),pending:0000000000000000000000000000010
我是一个进程(123526),pending:0000000000000000000000000000010
我是一个进程(123526),pending:0000000000000000000000000000010
我是一个进程(123526),pending:0000000000000000000000000000010
我是一个进程(123526),pending:0000000000000000000000000000010
我是一个进程(123526),pending:0000000000000000000000000000010
我是一个进程(123526),pending:0000000000000000000000000000010
我是一个进程(123526),pending:0000000000000000000000000000010
递达2信号!
解除对2号的屏蔽
我是一个进程(123526),pending:0000000000000000000000000000000
我是一个进程(123526),pending:0000000000000000000000000000000
我是一个进程(123526),pending:0000000000000000000000000000000
^C递达2信号!
我是一个进程(123526),pending:0000000000000000000000000000000
我是一个进程(123526),pending:0000000000000000000000000000000
我是一个进程(123526),pending:0000000000000000000000000000000
我是一个进程(123526),pending:0000000000000000000000000000000
^\Quit
一旦开始执行对pending的捕捉了,pending表中的1是在执行之前恢复为0还是在处理完了再恢复为0
#include <iostream>
#include <cstdio>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void PrintPending(sigset_t &pending)
{
printf("我是一个进程(%d),pending:", getpid());
for (int signo = 31; signo >= 1; signo--)
{
if (sigismember(&pending, signo))
{
std::cout << "1";
}
else
{
std::cout << "0";
}
}
std::cout << std::endl;
}
void handler(int sig)
{
std::cout<<"#########################"<<std::endl;
std::cout << "递达" << sig << "信号!" << std::endl;
sigset_t pending;
int m = sigpending(&pending);
PrintPending(pending);//如果是0000 0010(处理完,2号才会被设置为0),如果是0000 0000(执行handler方法之前,2对应的pending已经被清理了)
std::cout<<"#########################"<<std::endl;
}
int main()
{
signal(SIGINT, handler);
// 1.屏蔽2号信号
sigset_t block, oblock;
sigemptyset(&block); // 清空位图
sigemptyset(&oblock); // 清空位图
sigaddset(&block, SIGINT); // 将2号的SIGINT添加到block里
// 那么当前已经对2号信号进行屏蔽了吗?没有!
// 这个sigset_t类型是在栈上开辟的,将SIGINT添加到block就只是把这个类型中的比特位置1了。
// 并没有设到当前进程的block表里
// for(int i = 1; i<32;i++)
// sigaddset(&block,i);
int n = sigprocmask(SIG_SETMASK, &block, &oblock);
(void)n;
// 4.重复获取打印过程
int cnt = 0;
while (true)
{
// 2.获取pending信号集合
sigset_t pending;
int m = sigpending(&pending);
// 3.打印
PrintPending(pending);
if (cnt == 10)
{
// 5.恢复对2号信号的block情况
std::cout << "解除对2号的屏蔽" << std::endl;
sigprocmask(SIG_SETMASK, &oblock, nullptr);
}
sleep(1);
cnt++;
}
return 0;
}
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.2# ./testsig
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
^C我是一个进程(123729),pending:0000000000000000000000000000010
我是一个进程(123729),pending:0000000000000000000000000000010
我是一个进程(123729),pending:0000000000000000000000000000010
我是一个进程(123729),pending:0000000000000000000000000000010
我是一个进程(123729),pending:0000000000000000000000000000010
我是一个进程(123729),pending:0000000000000000000000000000010
解除对2号的屏蔽
#########################
递达2信号!
我是一个进程(123729),pending:0000000000000000000000000000000
#########################
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
^C#########################
递达2信号!
我是一个进程(123729),pending:0000000000000000000000000000000
#########################
我是一个进程(123729),pending:0000000000000000000000000000000
我是一个进程(123729),pending:0000000000000000000000000000000
^\Quit
当我们准备递达的时候,要首先清空pending信号集中对应的信号位图 1->0
结
细节1:
如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?POSIX.1允许系统递送该信
号⼀次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计⼀次,而实时信号在递达之前产生多次可以依次放在⼀个队列里。
细节2:Core Term
Core 核心
会在当前路径下形成一个文件,进程异常退出的时候。进程在内存中的核心数据,从内存拷贝到磁盘,形成一个文件--这种机制叫做核心转储 ---**支持debug调试,**然后进程退出
Term不做任何转储功能直接退出
为什么没见到过Core的?
云服务器上,core dump功能是被禁止掉的!
为什么禁止掉了?
磁盘空间耗尽:core 文件通常很大(与进程占用内存相当)
敏感信息泄露等
#include <iostream> int main() { printf("hello world!\n"); printf("hello world!\n"); printf("hello world!\n"); printf("hello world!\n"); int a = 10; a /= 0; printf("hello world!\n"); printf("hello world!\n"); printf("hello world!\n"); printf("hello world!\n"); } root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.3# ./testsig hello world! hello world! hello world! hello world! Floating point exception
如何查看?如何临时打开?
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.3# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7226
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7226
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
可以看到core file size为0,可以知道这个是被关掉的
打开
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.3# ulimit -c 40960
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.3# ulimit -a
core file size (blocks, -c) 40960
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7226
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7226
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.3# ./testsig
hello world!
hello world!
hello world!
hello world!
Floating point exception (core dumped)
会发现多一个core文件

为什么会核心转储??
支持debug
开启core dump,直接运行崩溃,gdb,core-file core,直接帮助我们定位到出错行---事后调试!

低7位表示退出时的退出信号,signal = 0表示正常退出
低8位还有一个标志位是core dump标志,是否core dump
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.4# ulimit -c 40960
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.4# ulimit -a
core file size (blocks, -c) 40960
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7226
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7226
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.4# make
make: 'testsig' is up to date.
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.4# ./testsig
hello world!
hello world!
hello world!
hello world!
signal:8,exit code:0,core dump:1
root@iZ5waahoxw3q2bZ:~/linux-learning/linux/26-6-18.4# ll
total 268
drwxr-xr-x 2 root root 4096 Jun 18 18:43 ./
drwxr-xr-x 43 root root 4096 Jun 18 17:23 ../
-rw------- 1 root root 499712 Jun 18 18:43 core
-rw-r--r-- 1 root root 78 Jun 18 17:23 Makefile
-rwxr-xr-x 1 root root 17408 Jun 18 18:41 testsig*
-rw-r--r-- 1 root root 731 Jun 18 18:41 testSig.cc
感谢你的观看,期待我们下次再见!