简体   繁体   English

为什么映射的页面不发送sigsegv?

[英]Why doesn't a mapped page send a sigsegv?

#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. 在上面的程序中,尝试读取0x20将按预期发送SIGSEGV信号处理程序捕获了该信号。 But when I try the same thing with a mapped page, it doesn't send a SIGSEGV ? 但是,当我尝试使用映射页面进行相同操作时,它不会发送SIGSEGV吗? It sends something else and exits the application with code 138 . 它发送其他内容并使用代码138退出应用程序。

Debugger says that it's a EXEC_BAD_ACCESS as expected, but doesn't seem to send a catchable signal. 调试器说这是预期的EXEC_BAD_ACCESS ,但似乎未发送可捕获的信号。 What am I doing wrong? 我究竟做错了什么?

Also: (Osx Mavericks if that makes a difference). 另外:(如果有区别,请使用Osx小牛)。

Maybe I got it this time :) on my system (linux), "bash -c 'kill -l 138'" says SIGUSR1; 也许这次是我:)在我的系统(Linux)上,SIGUSR1说“ bash -c'kill -l 138'”; 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. 基于https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/signal.3.html ,似乎在Mac上应该返回SIGBUS。 Is that it? 是吗

You have "exit(0);" 您有“ exit(0);” in the signal handler; 在信号处理程序中; try adding some write() after each instruction and you'll see for yourself :) 尝试在每条指令后添加一些write(),您将自己看到:)

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...) 编辑:阅读约瑟夫·昆西的答案后,我觉得有必要指定我使用的是“ gcc -O0 -ggdb”(您知道,在调试模式下...)

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 = ... . 除非我添加了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. 因此,如果将volatile添加到int* mem_location ,则可能会收到信号。

For what it is worth, the second signal works for me, as expected. 就其价值而言,第二个信号对我有效,正如预期的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM