2017-02-15 15 views
1

我正在使用twisted來產生本地進程,這可能會在某種情況下終止。如何獲取可能會意外終止的扭曲spawn過程的退出代碼?

我有一個自定義twisted.internet.protocol.ProcessProtocol類的反應堆。如果本地進程突然終止,我無法獲得processEnded的返回值。 exitCode設置爲None

一個MCV的例子是這樣的:

from twisted.internet import error,protocol,reactor 

class MyPP(protocol.ProcessProtocol): 
    def processEnded(self, reason): 
     if reason.check(error.ProcessTerminated): 
      err_info = "wrong termination: %s; exitCode: %s; signal: %s" % \ 
         (reason, reason.value.exitCode, reason.value.signal) 
      print(err_info) 
     else: 
      print("processEnded, status %d" % (reason.value.exitCode,)) 
      print("quitting") 
     reactor.stop() 

pp = MyPP() 
reactor.spawnProcess(pp, "throw_exception", ["throw_exception"], {}) 
reactor.run() 

而且throw_exception可執行文件可以從編譯:

#include <iostream> 
int main() { 
    throw std::runtime_error("some exception"); 
    return 0; 
} 

執行Python的例子將打印

錯誤終止:失敗實例:回溯(失敗,沒有 幀)::進程 已經以可能的​​錯誤條件結束:進程以信號6結束。 ]; exitCode:無;信號:6

如果在shell中運行C++示例,則返回值爲134,即發送SIGABRT(6)。 (我也測試過發送SIGINT終止並且仍然沒有退出代碼。)

我怎樣才能得到它在ProcessProtocal實例?或者這是不可能的?

+0

所以......你想134而不是6?或者是什麼? –

+0

@ Jean-PaulCalderone我想在這個扭曲的過程協議實例中獲得134或任何其他返回值,而不是上面例子中的'None'。 – halfelf

回答

1

在你的例子中,134是「等待狀態」(或者在手冊頁中是「wstatus」)。它編碼關於正在進行的運行狀態轉換的一些信息片段wait()

的可能轉換是:

  • 退出與代碼(即,稱爲exit(2)
  • 被信號
  • 核心轉儲是否製作
  • 被停止(例如,通過殺死(例如SIGCONT

POSIX提供宏從等待狀態中提取的細節:os.WIFEXITED

os.WIFEXITED(134)計算爲FalseWIFEXITEDWIFSIGNALEDWTERMSIGWEXITSTATUS

的Python通過os模塊公開這些。 os.WIFSIGNALED(134)評估爲真,os.WTERMSIG(134)評估爲6

ProcessDoneProcessTerminated使用這些宏來提取信息,並在一個稍微更有用的形式呈現它 - exitCodesignal屬性。

POSIX不提供一種方法去其他方式,雖然。沒有用於構建「等待狀態」的標準API,例如「該進程被信號6殺死」。

幸運的是,部分原因是由於無法倒退,Twisted將異常的原始等待狀態保留爲status屬性。如果您檢查傳遞到ProcessProtocolFailure中包含的異常的屬性,則應該找到您要查找的等待狀態。

+0

謝謝!我終於在「ProcessTerminated」類中找到它。這是一個特定於平臺的值,我總是在我的mac上得到一個'6',這會導致很多混淆,直到在我的linux服務器上測試它並最終得到134。 – halfelf

+0

是的,平臺特定性是爲什麼使用'exitCode'和'signal'通常是一個更好的主意。 :) –