Лабы, Разумовский / 5_lab / ООПЛинукс_5л
.docx
МИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра ВТ
отчет
по лабораторной работе №5
по дисциплине «Организация процессов и программирование в среде Linux»
Тема: Обработка сигналов
Студент гр. |
|
|
Преподаватель |
|
Разумовский Г.В. |
Санкт-Петербург
2026
Цель работы
Знакомство с механизмом сигналов и способами их обработки.
Задание
Написать программу, которая реагирует на ошибки при выполнении операции деления и неверном использовании указателя. При обнаружении ошибки программа должна передать управление функции, которая выведет сообщение и завершит работу программы с кодом ошибки. Тип ошибки, который должна зафиксировать программа, задается как параметр при ее запуске. Откомпилировать программу и дважны запустить ее с разными значениями типа ошибки.
Распечатка тестовой программы
own_prog.cpp
#include <iostream>
#include <csignal>
#include <cstdlib>
#include <unistd.h>
#include <string.h>
using namespace std;
void safe_write(const char* msg) {
write(STDERR_FILENO, msg, strlen(msg));
}
void errorHandler(int signum) {
if (signum == SIGFPE) {
safe_write("Обнаружена ошибка: Деление на ноль (SIGFPE)!\n");
_exit(1);
}
else if (signum == SIGSEGV) {
safe_write("️Обнаружена ошибка: Нарушение защиты памяти (SIGSEGV)!\n");
_exit(2);
}
}
int main(int argc, char* argv[]) {
if (argc != 2) {
cerr << "Использование: " << argv[0] << " <тип_ошибки>" << endl;
cerr << " 1 - Деление на ноль" << endl;
cerr << " 2 - Нарушение защиты памяти" << endl;
return 0;
}
// Используем sigaction
struct sigaction sa;
sa.sa_handler = errorHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGFPE, &sa, NULL);
sictigaon(SIGSEGV, &sa, NULL);
int errorType = atoi(argv[1]);
if (errorType == 1) {
cout << "Генерация ошибки деления на ноль..." << endl;
int a = 10;
int b = 0;
int c = a / b; //SIGFPE
}
else if (errorType == 2) {
cout << "Генерация ошибки нарушения защиты памяти..." << endl;
int* ptr = nullptr;
*ptr = 42; //SIGSEGV
}
else {
cout << "Неизвестный тип ошибки. Используйте 1 или 2." << endl;
}
return 0;
}
Вывод
В ходе выполнения лабораторной работы были изучены механизмы обработки асинхронных сигналов в ОС Linux. В результате была разработана и отлажена программа, демонстрирующая реакция на критические ошибки выполнение, такие как деление на ноль и нарушение защиты памяти.
Для надежной регистрации обработчиков сигналов был использован системный вызов sigaction, который позволяет корректно управлять маской блокируемых сигналов и гарантирует сохранение обработчика после его срабатывания. В соответствии с лекционным материалом, внутри обработчика использовались только асинхронно-сигнально-безопасные функции, такие как системный вызов write для вывода сообщений и функция _exit для немедленного завершения процесса, что исключает возникновение состояний гонки и неопределенного поведения при асинхронном прерывании основного потока выполнения.
Было установлено, что при возникновении аппаратных или программных исключений (деление на ноль генерирует сигнал SIGFPE, а разыменование нулевого указателя — SIGSEGV) ядро операционной системы немедленно прерывает выполнение процесса и передает управление зарегистрированному обработчику. Это позволяет программе не завершаться аварийно со стандартным системным сообщением об ошибке, а корректно обработать исключительную ситуацию, вывести информативное сообщение и завершить работу с заданным кодом возврата (1 или 2), который задается через аргументы командной строки.
