我有一些生產關鍵代碼必須繼續運行。
把代碼想象成
while (true){
init();
do_important_things(); //segfault here
clean();
}
我不能相信代碼沒有錯誤,我需要能夠記錄問題以便以后調查。
這一次,我知道代碼中某處的一個事實是拋出了一個分段錯誤,我需要至少能夠記錄它,然后重新開始一切。
在這里閱讀有一些解決方案,但在每個解決方案之后都是一場激烈的戰爭,聲稱該解決方案實際上弊大于利,沒有真正的解釋。我還找到了我考慮使用的這個答案,但我不確定它是否適合我的用例。
那么,從 C 上的分段錯誤中恢復的最佳方法是什么?
uj5u.com熱心網友回復:
我建議你創建一個非常小的程式,你可以真正安全地監控有問題的程式。如果有問題的程式以您不喜歡的方式退出,請重新啟動程式。
Posix 示例:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdio>
#include <iostream>
int main(int argc, char* argv[]) {
if(argc < 2) {
std::cerr << "USAGE: " << argv[0] << " program_to_monitor <arguments...>\n";
return 1;
}
while(true) {
pid_t child = fork(); // create a child process
if(child == -1) {
std::perror("fork");
return 1;
}
if(child == 0) {
execvp(argv[1], argv 1); // start the buggy program
perror(argv[1]); // starting failed
std::exit(0); // exit with 0 to not trigger a retry
}
// Wait for the buggy program to terminate and check the status
// to see if it should be restarted.
if(int wstatus; waitpid(child, &wstatus, 0) != -1) {
if(WIFEXITED(wstatus)) {
if(WEXITSTATUS(wstatus) == 0) return 0; // normal exit, terminate
std::cerr << argv[0] << ": " << argv[1] << " exited with "
<< WEXITSTATUS(wstatus) << '\n';
}
if(WIFSIGNALED(wstatus)) {
std::cerr << argv[0] << ": " << argv[1]
<< " terminated by signal " << WTERMSIG(wstatus);
if(WCOREDUMP(wstatus)) std::cout << " (core dumped)";
std::cout << '\n';
}
std::cout << argv[0] << ": Restarting " << argv[1] << '\n';
} else {
std::perror("wait");
break;
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/381016.html
下一篇:如何將例外記錄到檔案中?
