Reputation: 11439
#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).
Upvotes: 0
Views: 205
Reputation: 1357
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?
Upvotes: 3
Reputation: 1357
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...)
Upvotes: 1
Reputation: 9962
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.
Upvotes: 1