为什么映射页面没有发送sigsegv?

时间:2014-04-03 14:48:24

标签: c++ c linux mmap

#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如果有所作为)。

3 个答案:

答案 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,您可能会收到信号。

对于它的价值,第二个信号对我有用,正如预期的那样。