#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?
}
在上面的程序中,尝试阅读0x20
按预期发送SIGSEGV
- 信号处理程序捕获。但是当我使用映射页面尝试相同的操作时,它不会发送SIGSEGV
?它发送其他内容并使用代码138
退出应用程序。
调试器说它是预期的EXEC_BAD_ACCESS
,但似乎没有发送捕获信号。我做错了什么?
另外:( Osx Mavericks如果有所作为)。
答案 0 :(得分:4)
也许我这次得到了:) 在我的系统(linux)上,“bash -c'kill -l 138'”说SIGUSR1; 基于https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/signal.3.html,似乎在mac上它应该返回SIGBUS。 是吗?
答案 1 :(得分:1)
你有“退出(0);”在信号处理程序中;尝试在每条指令后添加一些write(),你会亲眼看到:)
编辑:在阅读了Joseph Quinsey的回答之后,我觉得需要指定我使用“gcc -O0 -ggdb”(你知道,当处于调试模式时......)
答案 2 :(得分:1)
“工作”行:
int value = *((int*)0x20); // This sends sig segv as expected
除非我添加volatile int value = ...
,否则在您的最新版本中将不适用于我。我假设(但尚未检查)这是因为否则编译器只会优化线路。
因此,如果您将volatile
添加到int* mem_location
,您可能会收到信号。
对于它的价值,第二个信号对我有用,正如预期的那样。