Я хочу написать обработчик сигнала, чтобы поймать SIGSEGV. я защитить блок памяти для чтения или записи с использованиемКак написать обработчик сигнала, чтобы поймать SIGSEGV?
char *buffer;
char *p;
char a;
int pagesize = 4096;
mprotect(buffer,pagesize,PROT_NONE)
Это защищает PAGESIZE байт памяти, начиная с буфера против любого чтения или записи.
Во-вторых, я пытаюсь прочитать память:
p = buffer;
a = *p
Это будет генерировать SIGSEGV, и мой обработчик будет вызываться. Пока все хорошо. Моя проблема заключается в том, что, когда вызывается обработчик, я хочу, чтобы изменить запись доступа к памяти, делая
mprotect(buffer,pagesize,PROT_READ);
и продолжить нормальное функционирование моего кода. Я не хочу выходить из функции. В будущем, записывая в ту же память, я хочу снова поймать сигнал и изменить права записи, а затем записать это событие.
Вот the code:
#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
char *buffer;
int flag=0;
static void handler(int sig, siginfo_t *si, void *unused)
{
printf("Got SIGSEGV at address: 0x%lx\n",(long) si->si_addr);
printf("Implements the handler only\n");
flag=1;
//exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
char *p; char a;
int pagesize;
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
handle_error("sigaction");
pagesize=4096;
/* Allocate a buffer aligned on a page boundary;
initial protection is PROT_READ | PROT_WRITE */
buffer = memalign(pagesize, 4 * pagesize);
if (buffer == NULL)
handle_error("memalign");
printf("Start of region: 0x%lx\n", (long) buffer);
printf("Start of region: 0x%lx\n", (long) buffer+pagesize);
printf("Start of region: 0x%lx\n", (long) buffer+2*pagesize);
printf("Start of region: 0x%lx\n", (long) buffer+3*pagesize);
//if (mprotect(buffer + pagesize * 0, pagesize,PROT_NONE) == -1)
if (mprotect(buffer + pagesize * 0, pagesize,PROT_NONE) == -1)
handle_error("mprotect");
//for (p = buffer ; ;)
if(flag==0)
{
p = buffer+pagesize/2;
printf("It comes here before reading memory\n");
a = *p; //trying to read the memory
printf("It comes here after reading memory\n");
}
else
{
if (mprotect(buffer + pagesize * 0, pagesize,PROT_READ) == -1)
handle_error("mprotect");
a = *p;
printf("Now i can read the memory\n");
}
/* for (p = buffer;p<=buffer+4*pagesize ;p++)
{
//a = *(p);
*(p) = 'a';
printf("Writing at address %p\n",p);
}*/
printf("Loop completed\n"); /* Should never happen */
exit(EXIT_SUCCESS);
}
Проблема заключается в том, что только работает обработчик сигнала, и я не могу вернуться к основной функции после ловли сигнала.
спасибо за редактирование..Я ценю это. Мне нужно потратить некоторое время, чтобы научиться редактировать свои вопросы. – Adi
при компиляции всегда включайте все предупреждения, а затем исправляйте эти предупреждения. (для 'gcc', при минимальном использовании:' -Wall -Wextra -pedantic' Я также использую: '-Wconversion -std = gnu99') Компилятор скажет вам: 1) параметр' argc' unused 2) parameter ' argv' unused (предложите использовать main() подпись: 'int main (void)' 3) локальная переменная 'p', используемая в блоке кода' else', без инициализации. 4) параметр 'unused' unused, предложите: добавить оператор:' (void) unused; 'как первая строка в этой функции. 5) локальная переменная 'a' установлена, но не используется. – user3629249
НИКОГДА не используйте 'printf()' в обработчике сигналов! Функция 'write()' была бы удобна в использовании, но лучше не делать никаких операций ввода-вывода в обработчике сигнала, просто установите флаг и пусть основная строка кода будет проверять этот флаг – user3629249