2011-04-09 82 views
2

有時我會在我的Delphi程序中遇到隨機崩潰。我的程序暫停,調試器輸出:指定RtlFreeHeap「指定給RtlFreeHeap(06450000,08387460)的無效地址」是什麼意思?

無效的地址(06450000,08387460)

這是什麼意思?什麼可能導致它?

這是CPU停止督察其中:

77BA0845 C6052582BD7700 MOV字節的PTR [$ 77bd8225],$ 00

請注意,他們是非常隨機的(對我來說)。有時他們根本沒有出現。

我正在使用Skype的Skype4COM.dll的- 雖然沒有任何消息來源。

如果你需要它,這裏是代碼。我已經評論了大部分對Synchronize的調用,所以你知道他們做了什麼。

//////////////////////////////////////////////////////////////////////////////// 
/// Execute 
//////////////////////////////////////////////////////////////////////////////// 
procedure TContactDeletor.Execute; 
Var 
    I    : Integer; 
    UserObj  : PUser; 
    User   : IUser; 
    PauseEvent : TEvent; 
begin 
    inherited; 
    FreeOnTerminate  := True; 
    if Terminated then 
    Exit; 

    CoInitialize(Nil); 
    // The F-Flags are to make sure TSkype events do not fire (from my Main Thread) 
    FAllowUI    := False; 
    FUserIsBeingDeleted := False; 
    FUseGroupUsersEvent := False; 
    FUseRenameEvent  := False; 
    SkypeThr    := TSkype.Create(Nil); 
    SkypeThr.Attach(10,False); 
    SkypeThr.Cache  := False; 
    MyList    := TStringList.Create; 
    PauseEvent   := TEvent.Create(True); 
    try 
    // This fills my Stringlist 
    Synchronize(GrabList); 
    if Terminated then Exit; 


    iMax     := MyList.Count; 
    // This sets the Max of my Progressbar 
    Synchronize(SetMax); 
    Try 
    for I := 0 to MyList.Count - 1 do 
    begin 

     {while SkypeThr.AttachmentStatus <> apiAttachSuccess do 
     begin 
     SkypeThr.Attach(10,False); 
     Synchronize(Procedure Begin Log('Skype Unavailable - Trying to reconnect ...'); End); 
     PauseEvent.WaitFor(5000); 
     end; } 

     CurUser := ''; 
     User := SkypeThr.User[MyList[I]]; 
     CurUser := MyList[I]; 

     Try 
     User.IsAuthorized := False; 
     User.BuddyStatus := budDeletedFriend; 
     Except on E:Exception do 
     begin 
     ExErr := E.Message; 
     ExLog := 'Error while deleting contacts: '; 
     ExMsg := 'An Error has occured while deleting contacts: '; 
     Synchronize(
     Procedure 
     Begin 
     Log(ExLog+ExErr+sLineBreak+' - Last logged Handle: '+CurUser); 
     End 
     );  
     end; 
     end; 

     iProgress := I+1; 
     // This updates my log and my progressbar. 
     Synchronize(UpdatePG); 
     PauseEvent.WaitFor(100); 

     if (I mod 200 = 0) and (I > 0) then 
     begin 
      // Calls to Synchronize updates my log 
      Synchronize(SyncPauseBegin); 
      PauseEvent.WaitFor(3000); 
      Synchronize(SyncPauseEnd); 
     end; 


    end; 
    // Except 
    Except on E:Exception do 
    begin 
    ExErr := E.Message; 
    ExLog := 'Error while deleting contacts: '; 
    ExMsg := 'An Error has occured while deleting contacts: '; 
    Synchronize(
    Procedure 
    Begin 
    Log(ExMsg+ExErr+sLineBreak+' - Last logged Handle: '+CurUser); 
    ErrMsg(ExMsg+ExErr+sLineBreak+sLineBreak+' - Last logged Handle: '+CurUser); 
    End 
    ); 
    Exit; 
    end; 
    end; 
    // This synchronizes my visual list. 
    Synchronize(SyncList); 
    finally 
    FUserIsBeingDeleted := False; 
    FUseGroupUsersEvent := True; 
    FUseRenameEvent  := True; 
    FAllowUI    := True; 
    Synchronize(
    Procedure 
    Begin 
    frmMain.UpdateStatusBar; 
    PleaseWait(False); 
    ToggleUI(True); 
    end); 
    PauseEvent.Free; 
    SkypeThr.Free; 
    MyList.Free; 
    CoUninitialize; 
    end; 


end; 
+0

聽起來就像你在一個堆中分配內存並試圖將它釋放到另一堆中一樣。我的猜測是,它是如何驅動這個COM控件的一個缺陷,這就是我猜測的RtlFreeHeap。當你需要從同一個線程調用它們時,你是否從不同的線程調用方法? – 2011-04-10 19:43:19

+1

意味着你損壞了你的堆。堆損壞很難追查和調試。但是,由於您隨機遇到此錯誤,您可以開始查找競爭條件。 – Najem 2011-04-10 23:32:56

+0

@David - 我使用TThread的幾個後代,但他們都有自己的TSkype控件。另外,一次只能運行一個後代 – Jeff 2011-04-21 12:13:51

回答

0

Najem是正確的,這是因爲你的堆已損壞。爲了更容易地進行調試,您應該啓用PageHeap,並且儘可能使用調試CRT(或調試delphi運行時),直到您找出破壞內存的東西。

很多時候,腐敗可能只會溢出幾個字節。然後你的應用程序可以運行很長時間,所以你不會注意到任何錯誤,直到很久以後,如果有的話。

嘗試徹底退出您的應用程序,當您尋找內存損壞錯誤時,不要停止調試器,當您的進程退出時,它應該「觸摸」它早先分配的大部分內存,它會給你一個機會檢測故障。