2015-06-23 52 views
1

我的程序使用環境變量DBG_MSG值來確定調試消息的級別。 DBG_MSG=3打印最大調試信息。在linux中爲正在運行的程序設置環境變量

但是,每當程序以奇怪的方式行事時,環境變量未設置爲打印完整的調試信息。當程序重新運行環境設置時,它不會顯示相同的錯誤。

我正在考慮爲SIGUSR1實現一個信號處理程序,以便在運行時使用putenv(3)來設置此環境變量。這樣我可以將信號發送到掛起的作業,以使其打印更多的調試信息。

做這件事時要採取什麼安全措施?

有沒有其他方法可以從外部改變正在運行的程序的環境?

+1

我很困惑。其他人可能也會如此。 – user3344003

+2

問題在於,當打印調試消息時,這個錯誤消失了,這意味着你的程序調用了未定義的行爲,所以調試器會有很大的幫助,像[valgrind](http://www.valgrind.org)這樣的內存調試器甚至會幫助更多,發佈有問題的代碼將對可能幫助你的人有幫助。 –

+1

@iharob你說的是真實的,除了這更可能是導致死鎖而不是內存損壞問題的競爭條件(所以'helgrind',而不是'valgrind'也許),並且描述讓我覺得我們是談論一個非常龐大,複雜的網絡守護進程,即使是精簡版的發佈也不太實際。 – zwol

回答

3

putenvasync-signal-safe,因此應從未從一個SIGUSR1處理程序調用。此外,putenv所做的更改不一定會在另一個線程中被getenv調用發現。

您應該改爲在啓動時只讀取一次DBG_MSG環境變量一次,並將該值存儲在類型爲volatile sig_atomic_t的全局變量中。你的調試日誌例程應該查看這個變量來決定打印多少信息。然後你有你的信號處理器調整變量的值。

我會建議,還有,SIGUSR1應該增加變量,而SIGUSR2應該減少它。這樣可以根據需要提高和降低日誌級別。

sig_atomic_t可能非常小,並且不能保證是有符號或無符號的:便攜式程序只能用它來存儲0到127之間的值。因此,確保您的信號處理程序將值限制在對您的程序有意義的範圍內(也就是說,不要將日誌級別增加到超過最大值或將其降低到超過最小值)。

1

安全措施是:不要這樣做。

putenv(3)不是異步信號安全的(主要是因爲它可以調用malloc(3)),所以你不應該真的從信號處理程序調用它。

+0

從'gdb'調用任意函數也是不安全的;實際上,根據你進入程序的位置,它可能會像從異步信號處理程序中調用它們一樣冒險。 – zwol

+0

@zwol哦,我不知道。那很有意思。謝謝你讓我知道!我要更新我的答案。 –

+0

我知道這個黑客攻擊,並已用於開發。但我正在尋找一種更加用戶友好的方式來做到這一點。用戶可以根據需要激活的東西。 – punekr12

0

您需要確保您沒有在程序中使用env變量。 Env變量應該從shell中設置一次,然後單獨運行。畢竟,他們是環境變量。他們只是爲您的程序設置或定義一個環境。

0

還有一個辦法.... 可以實現ioctl()調用也..

甚至很多司機都在做同樣的事情..

+0

您能詳細說明一下嗎? – punekr12