访问违规 - 如何追查原因?

Mic*_*ent 2 delphi debugging access-violation delphi-10.1-berlin

当我在我的应用程序中关闭表单时,我收到了访问冲突.它似乎只是在我访问数据库几次之后才会发生,但这似乎没有意义.

我已经跟踪并将outputdebugstring消息放在所有相关的OnDestroy()方法中,但AV似乎不在我的代码中.

这是消息的文本:

模块"MySoopaApplication.exe"中地址00405F7C的访问冲突.读取地址00000008.

如何找到应用程序00405F7C中的位置?

Delphi 10.1柏林有哪些工具可以帮助我解决这个问题?

编辑:添加了更多信息...当点击"Break"时,IDE总是带我到GETMEM.INC中的这段代码:

@SmallPoolWasFull:
  {Insert this as the first partially free pool for the block size}
  mov ecx, TSmallBlockType[ebx].NextPartiallyFreePool
Run Code Online (Sandbox Code Playgroud)

进一步编辑:好吧,我找到了罪魁祸首,虽然我不能老实说调试工具让我在那里 - 他们似乎只是表明它不在我的代码中.

我曾经使用网络中的代码来查找Windows登录用户 - 这就是:

function GetThisComputerName: string;
var
  CompName: PChar;
  maxlen: cardinal;
begin
  maxlen := MAX_COMPUTERNAME_LENGTH +1;
  GetMem(CompName, maxlen);
  try
    GetComputerName(CompName, maxlen);
    Result := CompName;
  finally
    FreeMem(CompName);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

一旦我用简单的结果替换了代码:='12345'AV停止了.我没有改变它到这个代码:

function GetThisComputerName: string;
var
  nSize: DWord;
  CompName: PChar;
begin
  nSize := 1024;
  GetMem(CompName, nSize);
  try
    GetComputerName(CompName, nSize);
    Result := CompName;
  finally
    FreeMem(CompName);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这似乎有效,作为奖励,不会导致AVs.

谢谢你的帮助,非常感谢.

Mar*_*ynA 5

Tools|OptionsIDE 下,转到Embarcadero Debuggers | Language Exceptions并确保Notify on Language Exceptions已选中.同样在Project Options | Compiling,确保Debugging | Use debug DCUs选中.

允许异常发生,然后转到View | Debug Windows | Call stack,您应该能够确切地看到它发生的位置.它在db访问之后发生的事实可能是因为它导致创建一些在销毁时生成AV的对象.可能是因为它被Free()编辑了两次.

如果这没有解决它,您可能需要像DavidH提到的madExcept之类的异常日志记录工具.

读取地址00000008.

这个地址数量较少这一事实暗示它是一个对象成员的地址(因为它们通常与对象的基地址相差很小).

如何找到应用程序00405F7C中的位置?

运行您的应用程序后,在IDE中转到Search | Go to Address.如果异常在您的应用程序中而不是在某个相关模块(例如它正在使用的.DLL)中,则应该找到它.应用程序在IDE中运行并在断点处停止后,将启用该菜单项.还有一个编译器命令行开关,用于按地址查找错误.