2010-10-07 110 views
1

我在C++中編寫了一個Windows服務,需要在每天晚上的午夜重新啓動,因此我對其調用exit(1)以便它可以由SCM重新啓動。問題是它似乎每隔一夜就會部分啓動並掛起。在事件日誌中,我得到:Windows服務不會停止並重新啓動

應用程序彈出 - 應用程序錯誤:「0x0043c145」處的指令引用「0x00000035」處的內存。內存不能被「讀取」。

在打開與SQL Server 2008數據庫的ODBC連接之前,它似乎失敗了。我可以確認服務在重新啓動之前實際退出;儘管如此,當它停止並重新啓動時,我每隔一段時間就會收到一次這個錯誤,但是如果我反覆停止並手動重新啓動服務,我永遠不會讓它失敗,如果我從一個終端端口控制進程並手動退出從那裏它也永遠不會失敗。

如果我嘗試附加一個調試器,該過程就會退出,因此我無法通過這種方式收集任何有用的信息。

我正在試圖弄清楚發生了什麼事情,但我不知道從哪裏開始。有人有主意嗎?

+0

在exit()後進程是否完全終止?先用SCM的非autorestart cfg進行測試來檢查。 – pinichi 2010-10-07 06:39:43

+1

您不應該使用exit()來退出服務;有一個協議,您必須遵循才能與SCM通信並正常關機。將調試器連接到正在運行的服務不應該導致它意外退出,所以它聽起來像是有些問題。該錯誤消息表明您的代碼可能試圖在某處取消引用NULL指針。 – Luke 2010-10-07 11:17:50

+0

Pinichi,今晚我會試試 – jjacksonRIAB 2010-10-09 00:29:18

回答

0

不是一個直接的答案,但如果你對Vista(和afters我認爲)有一個機會,你可以試試:

"A service notifies the SCM to queue a failure action by entering the SERVICE_STOPPED state and setting SetServiceExitCode function's dwWin32ExitCode parameter to anything other than ERROR_SUCCESS."

Windows Vista introduced a new flag, FailureActionsOnNonCrashFailures, which services set if they want to be able to notify the SCM to initiate a failure action: See more in Vista services

+0

不幸的是我正在使用Windows Server 2003.應該提到那個,對不起,但是這個信息在將來會很有用。 – jjacksonRIAB 2010-10-09 00:40:50

0

設置自動生成過程的轉儲使用Process Dumper這個過程。您應該能夠調試轉儲驗屍以找出這種零星異常發生的原因。

添加關於數據庫訪問的診斷信息以查看發生異常之前已經取得了哪些進展也很有用。我想知道,如果您計劃在午夜關閉服務清理任務,並在關閉完成後再次啓動服務,您的退出/重新啓動策略會更好。

在使用exit(1)之前關閉之後,盒子上的ODBC可能正處於一種奇怪的狀態。當你嘗試重新制作這個時,你說你停下來並開始它 - 在這種情況下退出模式是否相同?您能否在目標服務器上退出和重新啓動之間引入一個短暫的延遲,以允許清理ODBC連接狀態?

+0

我在機器上安裝了進程資源管理器,並且在它掛起並將其加載到Visual Studio中之後,我將盡力獲得完整轉儲。它在我測試完成後似乎可以工作,現在我只需要在正確的時間抓住它並查看出錯的地方。 – jjacksonRIAB 2010-10-09 00:33:17

+0

退出模式總是相同。這是一個緩慢的啓動過程,因爲它從數據庫中緩存了很多東西。它可能需要6-10秒才能開始。由於我調用exit(1),因此它應該等待一分鐘才能重新啓動,因爲它認爲出現故障。我可以延長看看會發生什麼,但我不確定,因爲再次如果我通過SCM手動執行操作,無論是重新啓動還是啓動,它都會像應該那樣。 – jjacksonRIAB 2010-10-09 00:45:52