2012-03-14 35 views
0

除了最後一個溝渠「發生了什麼事情」之外,是否有很多處理SIGSEGV的生產用途?對SIGSEGV的生產性使用

SIGSEGV wiki page,調試器使用它來捕捉用戶程序中的錯誤,並通知用戶發生了什麼。我看到它的方式,它是查詢虛擬內存系統的一種方式,而且由於我們有一個虛擬內存系統,所以我覺得SIGSEGV可以以更高效的方式使用。我想到的一件事是,你可以在某處放置一個堆棧,嘗試將其放入它,然後當你捕獲一個SIGSEGV時,增加堆棧的大小,然後重試該操作。例如,如果您正在處理郵件,但不知道郵件的大小,但由於速度的原因,您希望將它們寫入內存,我覺得這樣做可能很有用。

這是信號的合法使用嗎?有沒有其他方法可以將它作爲控制流程和執行的一種方法併入您的軟件設計中,而不是作爲錯誤處理的最後一種方法?

+2

在你的例子中,你可能已經知道堆棧大小和堆棧指針的當前位置,所以你會提前知道給定的操作是否會溢出堆棧。 – 2012-03-14 17:12:48

+0

@OliCharlesworth:我可能弄錯了,但我不認爲他的例子假設知道堆棧大小。事實上,我認爲這種方法已經被某些操作系統用於堆棧。 – 2012-03-14 17:22:45

+1

segfault的有效性在於它允許操作系統終止一個程序,該程序的內部狀態如此受損以至於處理器無法有效地繼續執行代碼。將狀態腐敗轉化爲程序功能並不富有成效。 – 2012-03-14 17:25:06

回答

1

典型的用法是捕獲對特定內存位置的訪問。

您使用mprotect設置了內存訪問權限,然後處理故障,授予訪問權限並繼續執行。這可用於調試,創意日誌記錄,自定義I/O內存映射......

+0

你可以給出一些示例代碼,從中可以看出這將如何工作?我特別感興趣的是如何在信號處理程序記錄對特定內存頁面的訪問後正常繼續執行。 – Marc 2016-10-22 12:22:48

+0

http://stackoverflow.com/questions/11142951/how-can-i-protect-a-heap-memory-in-linux – 2016-10-22 12:50:32

+0

這很有幫助。謝謝。 – Marc 2016-10-22 15:18:35

3

調試器不會「使用」SIGSEGV來捕獲用戶程序中的故障。調試器會捕獲事件,以便您(程序員)可以看到發生了什麼。

你真的不想使用這樣的SIGSEGV。這將是非常緩慢。當發生內存衝突時,O/S必須檢查它是否是對當前從系統中分出的內存的有效訪問,而不是您應該訪問的內容。

在操作系統決定不應該這樣做之後,您必須進行類似的檢查,檢查您是否訪問堆棧中的錯誤位置,並確定是否是因爲堆棧需要擴展。此外,您不可能返回導致訪問衝突的指令重新執行它。你通常必須是O/S來做到這一點。

如果確實有效,所需的代碼將是高度編譯器,O/S和特定體系結構。

基本上,不要這樣做。

1

由於便攜性問題,SIGSEGV和其他信號的生產用途通常在生產環境中受到限制。在信號處理程序中可以安全執行的事情列表非常短,線程和信號之間的交互在很大程度上是未指定的。

由於這個原因,SIGSEGV的使用通常侷限於調試器和類似的程序,它們必須運行未知的代碼而不改變它。

1

在生產環境中,處理SIGSEGV - 記錄消息並正常處理關閉(關閉網絡連接等,可能需要重新啓動)非常有用。

+0

在SIGSEGV之後執行任何操作是否安全? – 2012-03-14 17:56:43

+0

@ R.MartinhoFernandes - 是的。在開始時創建一個空間來放置該信息。然後設置處理程序。即在開始時可能需要的文件描述符的'struct'。它使程序更加優雅地關閉,並且可能會給你更多的信息,有時你無法從開發環境中獲得 – 2012-03-14 18:00:02

相關問題