2009-08-11 96 views
5

有沒有辦法在linux機器上用隨機數據填充空閒內存?用隨機數據填充內存

我問這個問題的原因:我正在一個我們在Fortran中進行數值編程的小組工作。有時候,人們會用雙精度實數工作,所以那些應該給出雙精度結果的程序只能提供單精度。

如果我的理解是正確的,那麼在這樣的程序中,單精度限制之後會出現結果的隨機波動。也就是說,如果多次使用相同的輸入運行相同的程序,則每次都會得到隨機的不同結果。你看到的(隨機部分)取決於機器可用RAM中的隨機值。但在實踐中,如果您在同一臺機器上反覆運行程序,則會重複使用相同的內存部分,這些內存中隨機數據相同,每次都會產生相同的輸出。

我的想法是,如果您可以用隨機數據覆蓋內存,您實際上會看到程序輸出中的隨機波動。這將使它更容易找到這些錯誤。

這個想法是否重要,或者如果不是,我該如何填充內存?我可以將/ dev/random插入RAM中嗎?

+0

給予進程的內存在使用前被初始化(使用來自磁盤的數據)或歸零。沒有例外。所以你可以在這裏做的是從有問題的程序中隨機化內存。 – bdonlan 2009-08-11 14:02:22

+0

我有點確定它不是......特別是在沒有初始化的字符串中,我始終看到「二進制垃圾」......它可能是內存在開始時初始化的,而垃圾是從內存在程序內部重用,但無論如何,都可以有隨機數據。 – 2009-08-11 20:59:12

+0

找過問題之後,我看到傻冒處理遺留應用程序,你需要調試它,最好你想調試「到位」了,和一個簡單的,創造性的辦法是隨機的數據。不過,我不知道這是否可能。你可能會變得更好,通過中斷代碼來完成它自己的模塊的數字雙/單返回,將其連接到單元測試框架,並以此方式運行。這可能需要很多工作,但是你可以證明這些數字是以這種方式準確地返回的。我只是不認爲這很容易。 – 2009-08-14 13:53:06

回答

2

Linux爲您提供/proc/pid/maps/proc/pid/mem,爲您帶來快樂。在那裏寫作時你必須格外小心。另外,請記住每個進程可用的唯一內存段是它自己的,因此您可能需要執行一些附加和代碼修補以獲得所需的位置。好運,反正。 :)

編輯:它仍然比代碼審計複雜得多 - 它也有更大的機會揭示問題的實際來源。

1

我會認爲隨機數據會使調試更加困難。記憶中的隨機值或計算錯誤導致答案中的隨機性是什麼?我會固定已知值會更好。

在FORTRAN方面,你是否說'混合精度'數字可互換使用?我並不清楚實際的問題。

但我不知道如何在Linux中用任何東西填充空閒內存。

+0

例如,如果您進行了轉換,並且忘記將精度顯式化,則可能會出現該問題。例如(對於雙精度,idp = 8): real(idp):: a; complex(idp):: b; a = 1.0_idp; b = cmplx(a,idp); 如果您在調用cmplx(很容易發生)中忘記了'idp',b的結果值只會是單個精度限制的副本。其餘數字可能會有隨機波動,這取決於以前如何使用內存。還有其他類似的問題的例子。如果實際上可以強制實施波動,則調試起來會更容易。 – 2009-08-11 20:38:01

3

如果你有一個最近的(> = 2.4,看起來)glibc,你可以使用設置環境變量MALLOC_PERTURB_使malloc()返回設置爲某個值的內存。請參閱http://udrepper.livejournal.com/11429.htmlhttp://people.redhat.com/drepper/defprogramming.pdf

然後問題是如果您的Fortran程序使用glibc malloc(),我想它取決於Fortran編譯器。

+1

還要注意,與許多人似乎相信的內容相反,您從malloc()(或Fortran中的allocate()獲得的內存不保證爲零,儘管許多操作系統都提供此選項作爲選項。 – uekstrom 2009-08-11 14:23:05

2

我會嘗試使用諸如fUnit之類的東西來編寫單元測試,以確保雙精度值始終按預期工作,通過編寫一些需要雙精度結果的測試,在經常出現單精度結果的情況下顯示結果。例如:編寫一個測試,用一個應該生成雙精度輸出的各種輸入來調用一個函數,然後測試它是否與assert()一起工作。

5

你的理解是不正確的。在開始執行之前,您無法使用隨機數據填充程序內存,即使可以,也不能解決您的問題。

如果您的Fortran程序聲明瞭單精度浮點變量,編譯器將在內存中分配一個32位單元來保存該值。每次程序從變量中讀取數據時,處理器都會從單元中讀取一個32位值。每次分配給變量時,處理器都會向單元寫入一個32位的值。在任何情況下,隨機比特都不應該在單元格之前或之後「滲入」單元格的值。

雖然浮點運算並不精確,但它也不是隨機的。如果您計算1.0/3.0 + 1.0/3.0 + 1.0/3.0)一千次,則每次都會得到0.99999...

第二點是當在Linux上執行程序時,操作系統將所有數據內存預先初始化爲零。這樣做是爲了避免你的程序在每次運行時都有不同的表現:這將是一件壞事。編輯:這樣做的另一個原因是爲了防止私人信息從一個進程泄漏到另一個進程。

(評論者:請注意,我故意在滑冰若干問題作出解釋很簡單。)

+0

我知道浮點算術的不精確性,就像你說明的那樣。這就是要點。如果程序有這些類型的錯誤,結果是不準確的,但不是隨機的。但是,如果存在單/雙精度轉換問題,結果是隨機的。我很確定,在Fortran內存中,除非手動請求它,否則它不會被初始化。這意味着以前使用該內存位置可能會以隨機波動的形式產生影響。這些東西也可以是編譯器依賴的。 – 2009-08-11 20:44:17

+0

「我很確定,除非你手動請求它,否則Fortran內存不會被初始化。」如果你在一個現代的多用戶操作系統上運行,我可以保證任何程序開始執行的內存都將被初始化。否則,一個程序可以在另一個程序退出或死亡時收集留在內存中的私人信息。 – 2009-09-04 12:54:15

1

你尋求幫助ITO實現你的解決問題的辦法,是內存隨機化。不過,我覺得這很奇怪,可能很難調試解決方案。

在我看來,你會從 獲益更多 - 靜代碼分析工具 - 特定的單元測試 - 清單的代碼審查,這個問題專門針對性

有時候,一個能想到的解決方案更簡單;如果沒有單精度數學,你可能會阻止鏈接這樣的庫,所以錯誤會顯示鏈接錯誤;在您的開發過程早期。祝你好運。

2

你想達到什麼樣的目的,雖然意圖崇高,而且有趣,懷念Wile E. Coyote計劃抓住步行者,而步槍和狙擊行動將是最好的選擇。

如果您遇到問題,則表示您的代碼中存在結構性問題,並且您失去了對程序的控制權。儘管我完全知道軟件是如何在學術界以及在Fortran中發展起來的,只是因爲世界其他地區的人才會把自己扔下懸崖,這是有問題的。

你應該做的是審覈你的代碼。然後再打敗一些畢業生。

+0

這實際上並不是我的計劃,它只是我小組中的另一位向我求助的人。他有一個複雜的程序混亂,他發現,如果他改變了一些不相干的東西,他的結果會波動。我很確定這是一個雙精度/單精度問題。此外......我是研究生(但我不是那個搞砸了的人))無論如何,對他的課程進行全面審覈是不可能的,因爲這太麻煩了,太多時間。 – 2009-08-11 20:26:49

+0

取決於他的變化,他如何改變。誰知道 ?可以像你說的那樣,但是誰可以確實說出這一點?我明白你的意思,試圖去調試它,但是,如果你確實發現它是一個精確的問題,你仍然不知道它在哪裏發生,所以你將需要一個審計。 – 2009-08-12 17:35:20