簡體   English   中英

Java應用程序在關閉時被終止而沒有發送信號

[英]java application being abrutply terminated on shutdown without having signal sent

需要明確的是,這是一個新貴/ Linux調試問題,而不是java本身的問題。

我有一個Java應用程序安裝shutdownhook。 它顯示了ubuntu-GNOME中的一些有趣行為,即如果計划了重新啟動或關閉電源,則關閉掛鈎永遠不會運行。 起初我以為這是我的關機鈎的問題,所以我簡化了它,直到它只向文件寫入一行(是的,我知道關機鈎的log4j2記錄器問題,所以我也禁用了它們)。 然后,當那不起作用時,我開始黑客入侵/ etc / init / sendsigs

我將此添加到do_stop函數的開頭:

app="$(jps | grep appname.jar | cut -d' ' -f1)"
echo "$app" >>  "/home/i30817/output.txt"

足夠肯定的是,這表明它不再運行,因此sendigs從未激活過shutdown鈎子。然后,我在這里使用lastcomm替換了sendigs的編輯:

echo `/home/i30817/lastcomm` >  "/home/i30817/output.txt"

它告訴我,java進程以1退出,並且未發出信號:

java X i30817 ?? 10.26 secs Sun Mar 2 12:44 E 1

但這仍然沒有幫助我找到真正殺死它的原因以及原因。 這個問題在較小的示例中是無法重現的,因此它可能是較大的應用程序中的某些問題(但由於沒有最小化,所以沒有關閉鈎子),它不喜歡關閉過程並設法終止該過程,但是我無法弄清楚...將過程輸出重定向到文件也沒有說什么,例如:

java -jar /home/i30817/Documents/projects/app/dist/app.jar > allout.text 2>&1 

除了正常的應用程序輸出外,什么都沒有,您能幫我解決這個問題嗎? 關於同一件事,也有很多重復的問題(但他們認為這是由於shuthooks引起的)。

編輯:更多細節,現在我更好地理解了這個問題。 我認為現在sendigs上不存在該進程是正常的。 Java應用程序(可能還有其他應用程序)使用來自窗口管理器的協議,在其中關閉/注銷時發送SIGHUP,SIGHUP和SIGCONT。 JVM掛鈎SIGHUP以啟動關閉掛鈎。 我用一個很小的示例進行了測試,該示例僅添加了一個shutdownhook並在main上具有無限循環,並在后台使用系統Tap腳本運行了它:

  java -jar app.jar 

而在另一個殼

  sudo stap -o process.txt sigkill.stp

但是,當我嘗試使用我的應用程序時,我認為是罪魁禍首:

  PROCESS: SIGSEGV java.signal_generate sent to java 2280

但是考慮到沒有線程轉儲或任何東西,我真的不知道該怎么辦,而且很難重現(只有我的應用程序,只有在關機期間)。

edit2:現在我懷疑沒有核心轉儲的“突然”終止的原因是關機期間的ulimit。 因此,我正在嘗試解決此問題,以准備錯誤報告。 我編輯了/etc/security/limits.conf以添加它並重新啟動

   *               soft    core            unlimited
   root            hard    core            unlimited
   *               hard    rss             10000

(fs.suid_dumpable = 2是由ubuntu設置的,我認為沒有保護),但是在關機期間,我再次編輯了/etc/init.d/sendsigs來打印ulimit -a並休眠30秒鍾,然后終止進程,這似乎在重新啟動ulimit是否再次重置? 而且,它具有不同的輸出,就像正在使用另一個可執行版本一樣,例如,它不是說“核心文件大小”而是具有“ core(dump)”之類的意思。

edit3:啊,我需要改成fs.suid_dumpable = 1-現在要嘗試。 也許init ulimit對關閉核心轉儲觸發無關緊要。 從用戶env執行完所有jvm之后,因此應該使用用戶ulimit。

edit4:嗯。 在對代碼進行大量注釋之后,我得出以下結論,我可以從RTFM得出結論:

  1. 這些信號是無害的。

  2. 非零退出碼不是。

如果AWT仍在運行,則信號始終為非零,並且關閉掛鈎永遠不會運行。 如果JFrame啟動,即使是一個很小的示例也仍然阻止Linux重新啟動時執行關閉掛鈎(與Windows不同,它們將在其中啟動)。 從源頭上看,應用程序的關閉鈎子是在插槽1上單獨運行的。我敢說插槽'0'是AWT,這以某種方式使系統停止運行。

我想現在是時候檢查軟件包專用信號處理庫,看看我是否可以在JVM決定終止所有操作之前甚至沒有機會運行清理代碼的情況下獲得SIGHUP。

根據文檔

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)

在極少數情況下,虛擬機可能會中止,即在不干凈關閉的情況下停止運行。... 如果虛擬機中止,則無法保證是否將運行任何關閉掛接。

暫無
暫無

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

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