سؤال

#include <iostream>
#include <sys/mman.h>
#include <unistd.h>

void signal_handler(int signal) {
    using namespace std;

    cout << "WE GET SIGNAL!" << endl; 
    exit(0);
}

int main() {
    using namespace std;

    int over_9000 = 9001;

    signal(SIGSEGV, signal_handler);
    int* mem_location = (int*)mmap(nullptr, getpagesize(), 
        PROT_READ, MAP_ANON | MAP_PRIVATE, -1, 0);

    int value = *((int*)0x20);      // This sends sig segv as expected
    *(mem_location) = over_9000;    // This sends something else?
}

In the program above, trying to read 0x20 sends a SIGSEGV as expected - which the signal handler catches. But when I try the same thing with a mapped page, it doesn't send a SIGSEGV? It sends something else and exits the application with code 138.

Debugger says that it's a EXEC_BAD_ACCESS as expected, but doesn't seem to send a catchable signal. What am I doing wrong?

Also: (Osx Mavericks if that makes a difference).

هل كانت مفيدة؟

المحلول

Maybe I got it this time :) on my system (linux), "bash -c 'kill -l 138'" says SIGUSR1; Based on https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/signal.3.html, it seems that on a mac it should return SIGBUS. Is that it?

نصائح أخرى

The "working" line:

int value = *((int*)0x20);      // This sends sig segv as expected

in your latest version wouldn't work for me unless I added volatile int value = .... I presume (but haven't checked) that this is because otherwise the compiler just optimizes the line out.

So perhaps if you add volatile to int* mem_location, you would get a signal.

For what it is worth, the second signal works for me, as expected.

You have "exit(0);" in the signal handler; try adding some write() after each instruction and you'll see for yourself :)

edit: after reading Joseph Quinsey's answer, I feel the need to specify that I used "gcc -O0 -ggdb" (you know, when in debugging mode...)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top