程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi系統變量:IsMultiThread對MM的影響,

Delphi系統變量:IsMultiThread對MM的影響,

編輯:Delphi

Delphi系統變量:IsMultiThread對MM的影響,


   前幾日,調試一BUG,過程先不說,最後調試到MM,即Debug dcu,然後進入到GetMem.inc中的Get/FreeMem函數處後,出現AV。

   然後一通找。。。郁悶了N天,後來發現將MM切換到QMM後,一切正常,然後再切回原MM,BUG出現。。。

   按經驗,此類問題一般由於線程未有鎖保護引起,但就是沒找到。

   好吧,也不怎麼滴,突然想起IsMultiThread變量,想起MM的Get/Free/Realloc都需要這個玩意進行保護,而VCL中,只有一個地方對這變量進行操作: Classes.TThread.Create->System.BeginThread

   然後才想起自己未使用TThread,使用API.CreateThread進行創建線程,而它未對IsMultiThread進行置true操作,問題找到,BUG解除。

 

遂,本文記錄此問題。

 

BUG形成:

   1:程序未使用TThread或BeginThread進行創建線程,這樣,它就不會對IsMultiThread進行操作

   2:自行使用API.Windows.CreateThread創建線程,且未對IsMultiThread置true

   3:在創建的線程中,進行Get/Free/ReallocMem,並與其它線程(如主線程)進行交互該內存塊

 

BUG展現:

  1:該BUG將會引起MM數據結構錯誤,問題就大了去。

       出現AV時,watch查看的數據是錯誤的,且隨機的給你不一樣的數據

      call stack也傻了,定位到無邊際的代碼。。。

     總之,一切都傻掉了,不可信了。

 

BUG避免:

   1:慎用API.Windows.CreateThread,如果要對它操作,請記得IsMultiThread := True;

         如果不記得,請參照代碼: System.BeginThread

        或者直接使用System.BeginThread進行創建線程。

   2:使用QMM,QMM是自動維護IsMultiThread,有線程數N(N>1)時, IsMultiThread=true, N=1時, IsMultiThread = false;

         這點,其它MM,俺所查看的,都未做處理。(偶在打廣告哩)

         個人建議是:開發環境必備兩套以上MM,以作備用,遇到一些莫名問題,切換一下,用以確認是否MM問題引起。


注:

  MM=Memory Manager, D2005版本開始集成FastMM。

  不過,從D7(D5沒注意看,應該也是)的GetMem.Inc,一直到FastMM4.991都依賴於IsMultiThread標志進行線程保護,未進行自維護該標志。 

 

    所以,當出現此BUG條件形成時,就會出現:我知道因為線程保護引起的BUG,但就是找不著在哪裡觸發的,怎麼去解決。

    這才是最坑爹的。 :)

 

完。

2014.10.15 by qsl

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved