簡體   English   中英

是否可以捕獲分段錯誤?

[英]Is it possible to trap a segmentation fault?

我的應用程序依賴於ghostscript將一些 pdf 文件轉換為文檔每一頁的一系列圖像。 這是一個簡化版本:

import locale

from ghostscript import Ghostscript as gs
from ghostscript import cleanup
from cv2 import imread, IMREAD_GRAYSCALE as GRAY
from multiprocessing import cpu_count

args = [
  "",
  "-q", "-r300", "-dNOPAUSE",
  "-sDEVICE=pgmraw",
  "-sOutputFile=%d.pgm",
  "-dNumRenderingThreads=" + str(cpu_count()),
  "-f", "_.pdf" #filename will always be "_.pdf"
]
encoding = locale.getpreferredencoding()
args = [a.encode(encoding) for a in args]

def pdftoimarray():
    cleanup()
    gs(*args)
    imarray = []
    for filename in os.listdir():
        imarray.append(imread(filename, GRAY))
    return imarray

(我特意在最后刪除了文件系統的清理:這對這個問題並不重要)

問題是,我不能真正相信這些文件的來源,其中一些文件可能有問題。 運行一些測試,我發現其中一些不良文檔導致 ghostscript 實際上出現段錯誤,從而使我的整個應用程序崩潰。

通常,段錯誤是一個非常嚴重的事件,我們無法真正從中恢復,所以我懷疑是否真的有可能捕獲它。 但在我的情況下,它不應該真的那么嚴重:假設我的程序仍處於有效狀態,我可以將該文檔標記為錯誤並繼續。

問題:我能否以某種方式將這個分段錯誤捕獲在我的依賴項中,並從中恢復?

之前在Segmentation Fault Catch 中有人問過這個問題,但唯一的答案是錯誤的(它建議用signal.signal捕獲它,但文檔清楚地表明,使用它來捕獲同步信號(例如 SIGSEGV)沒有多大意義。相同的文檔指向faulthandler ,但它不能真正捕獲信號:它只是在發生時提供更好的錯誤消息)。

這留下了這個問題如何獨特而不是重復的問題:我的限制較少:我根本不打算處理這個問題:我只想忽略它並繼續前進。 任何關於首先在 ghostscript 中實際避免段錯誤的觀點也將很受歡迎。

這個問題有點老了,但我想我應該分享這個:我正在觀看一個關於一個很酷的新內存分配器的視頻,並且在觀眾提出的一個問題上,作者解釋說他“安裝了一個段錯誤處理程序”,其中是我非常感興趣的。我仍然不知道他到底是怎么做的,所以這並不能完全回答我的問題,但它給了我一個開始研究的好地方。 如果我自己設法解決這個問題,我會在這里發布答案。

這是視頻(鏈接是在他回答我正在談論的問題時) https://youtu.be/c1UBJbfR-H0?t=2058

我有一個類似的問題,通過 pythonocc 渲染 cad 文件。 有時,當打開文件時,腳本會出現段錯誤。 真的很煩。 您必須手動刪除文件並重新啟動批處理。

所以基本上這個想法是為任務啟動一個額外的進程並檢查它的退出代碼

import multiprocessing as mp


def do_stuff_that_segfaults(param):
    call_shitty_library(param)

def main():
    p = mp.Process(target=do_stuff_that_segfaults, args=param)            
    p.start()            
    p.join()
    if p.exitcode == -11:  # Segmentation fault
        do_stuff_in_case_of_segfault()

我還嘗試了其他建議,例如您鏈接的 Segmentation Fault Catch,但無濟於事。 我真的很想使用mp.pool()來使用所有內核,但是您沒有從 mp.pool() 獲得退出狀態

到目前為止,代碼運行良好,我通過do_stuff_in_case_of_segfault()將導致段錯誤的文件移動到另一個文件夾中,而沒有殺死我的主腳本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM