【问题标题】:What does "Invalid address specified to RtlFreeHeap( 06450000, 08387460 )" mean?“指定给 RtlFreeHeap(06450000, 08387460) 的地址无效”是什么意思?
【发布时间】:2011-08-02 06:34:15
【问题描述】:

有时我在我的 Delphi 程序中遇到随机崩溃。我的程序停止,调试器输出:

为 RtlFreeHeap 指定的地址无效(06450000, 08387460)

这是什么意思?什么可能导致它?

这是 CPU Inspector 停止的地方:

77BA0845 C6052582BD7700 mov byte 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;

【问题讨论】:

  • 听起来你在一个堆中分配内存并试图在另一个堆中释放它。我的猜测是它在驱动这个 COM 控件的方式上存在缺陷,我猜这就是所谓的 RtlFreeHeap。当您需要从同一个线程调用方法时,您是否从不同的线程调用它们?
  • 意味着你已经损坏了你的堆。堆损坏更难追踪和调试。但由于您是随机遇到此错误,您可以开始寻找 Race condition。
  • @David - 我使用了一些 TThread 的后代,但它们都有自己的 TSkype 控件。此外,一次只有一个后代在运行

标签: delphi debugging dll heap-memory


【解决方案1】:

Najem 是正确的,这是因为您的堆已损坏。为了更容易调试,您应该启用PageHeap,同时,尽可能使用调试 CRT(或调试 delphi 运行时),直到找出损坏内存的原因。

很多时候,损坏可能只会溢出几个字节。然后您的应用程序可以在很长一段时间内正常运行,因此直到很久以后您才会注意到任何错误,如果有的话。

当您寻找内存损坏错误时,尝试干净地退出您的应用程序,不要只是停止调试器,当您的进程退出时,它应该“触摸”它之前分配的大部分内存,它会给您一个检测的机会失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2021-12-21
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多