学习笔记 9
一、知识点归纳以及自己最有收获的内容
1. 信号和信号处理
进程的概念
- 一个“进程”是一系列活动,包括从事日常事物的人、在用户模式或内核模式下运行的Unix/Linux进程以及执行机器指令的CPU。
中断
- 中断可分为三类:来自硬件的中断、来自其他人的中断、自己造成的中断。
- 人员中断可根据紧急程度分为不可屏蔽(NMI)和可屏蔽。
- 进程中断分为来自硬件、其他进程、自己造成的中断。
- 硬件中断可来自硬件、其他处理器、进程的陷阱错误。
进程的陷阱错误
- 进程可能自己造成中断,由CPU识别为异常的错误引起,如除以0、无效地址等。
- 进程遇到异常时会陷入操作系统内核,将陷阱原因转换为信号编号,并将信号发送给自己。
- 如果在用户模式下发生异常,则进程的默认操作是终止,可选地进行内存转储进行调试。
- 如果在内核模式下发生陷阱,原因可能是硬件错误或内核代码中的漏洞,这时内核无法处理。
2. Unix/Linux中的信号处理
信号类型
- Unix/Linux支持31种不同的信号,每种信号在
signal.h
文件中都有定义,每种信号都有一个符号名。
信号来源
- 来自硬件的中断信号,来自异常的信号,来自其他进程的信号。
信号处理步骤
- 当某进程处于内核模式时,会检查信号并处理未完成的信号。
- 重置用户安装的信号捕捉函数,用于处理用户代码中的陷阱错误。
- 信号和唤醒:在Unix/Linux内核中有两种SLEEP进程:深度休眠进程和浅度休眠进程。
二、实践内容与截图
实践1
- 运行以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#include <string.h>
jmp_buf env;
int count = 0;
void handler(int sig, siginfo_t *siginfo, void *context)
{
printf("handler: sig=%d from PID=%d UID=%d count=%d\n",
sig, siginfo->si_pid, siginfo->si_uid, ++count);
if (count >= 4) // let it occur up to 4 times
longjmp(env, 1234);
}
int BAD()
{
int *ip = 0;
printf("in BAD(): try to dereference NULL pointer\n");
*ip = 123; // dereference a NULL pointer
printf("should not see this line\n");
}
int main(int argc, char *argv[])
{
int r;
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_sigaction = &handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &act, NULL);
if ((r = setjmp(env)) == 0)
BAD();
else
printf("proc %d survived SEGMENTATION FAULT: r=%d\n", getpid(), r);
printf("proc %d looping\n", getpid());
while (1)
;
}
标签:int,信息安全,笔记,学习,中断,信号,act,进程,include
From: https://www.cnblogs.com/gd1220/p/17827126.html