2014-04-03 30 views
1
#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的應用程序。爲什麼沒有映射的頁面發送sigsegv?

調試器說,它是一個EXEC_BAD_ACCESS如預期的,但似乎並沒有發送可捕獲的信號。我究竟做錯了什麼?

另外:(奧斯克斯小牛隊如果這有所作爲)。

+0

假設正確的標題等,它在這裏產生一個SIGSEGV。也許你會生成一個自包含的測試用例,人們可以採取這些測試用例,編譯並重現。 – PlasmaHH

+0

已更新的答案。而且還沒有在我身邊工作。 – sircodesalot

+3

爲什麼有人會投票關閉這個?它顯示了試圖提出一個好問題的嘗試。如果需要更多信息,請詢問! –

回答

4

也許我這次得到了:) 在我的系統(linux)上,「bash -c'kill -l 138'」說SIGUSR1; 基於https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/signal.3.html,它似乎在Mac上它應該返回SIGBUS。 是嗎?

+2

贏家,就是這樣。爲什麼這會是一個巴士錯誤? – sircodesalot

+0

linux手冊頁說寫入只讀內存得到一個SIGSEGV; posix什麼都沒說(除非我錯過了),並且mac manpage似乎沒有說什麼(至少不是在https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/mmap .2.html);我的猜測是,你應該得到**一些**信號(SIGBUS,SIGSEGV,不管),但這只是猜測 - 有人知道更好嗎? – loreb

+0

我自從發現針對未映射頁面('SIGSEGV')的錯誤與針對映射*但受保護*('PROT_NONE')頁面的錯誤不同。至少在OSX上,這可能會導致一個'SIGBUS'的區別? – sircodesalot

1

你有「exit(0);」在信號處理程序中;嘗試加入一些寫()每條指令後,你會看到自己:)

編輯:讀約瑟夫Quinsey的回答後,我覺得有必要指定我用「的gcc -O0 -ggdb」(你知道,當在調試模式下......)

+0

我想OP是tryinig說的是,他試圖編譯和運行兩個程序,在每個只有一行的段錯誤被激活。 – PlasmaHH

+0

這是可能的;我試圖評論出第一個不良訪問並按預期得到sigsegv後寫了我的答案(刪除「exit(0)」並不好笑) – loreb

+0

本來,我把這行作爲pause(),但後來我將其更改爲exit 0)爲了理智的目的。但處理程序仍然不會在第二個版本中觸發。 – sircodesalot

1

「工作」行:

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

在最新版本不會爲我工作,除非我加volatile int value = ...。我假設(但沒有檢查),這是因爲否則編譯器只是優化線路。

所以,如果你添加volatileint* mem_location,你會得到一個信號。

爲了什麼是值得的,第二個信號適合我,正如所料。

+0

按照你的期望,還是按照他的期望?你是否看到與他一樣的東西或其他東西? – PlasmaHH

+0

@PlasmaHH:爲了澄清,我無法再現OP的問題。 '*(mem_location)= over_9000'確實在我的系統上提供了一個'SIGSEGV',而不是Osx Mavericks,就像後來的OP一樣。 –

+1

同樣在這裏(linux);使用clang3.3,-O0以上的任何東西都會優化掉該行 – loreb