代码之家  ›  专栏  ›  技术社区  ›  Nick

如何调试C类库中的堆错误?

  •  1
  • Nick  · 技术社区  · 16 年前

    通过C++中的COM调用,我在C语言库模块中得到了一个堆损坏错误。具体错误是:

    堆:空闲堆块4b61bb8已修改
    ...
    这可能是由于 堆损坏,并指示 或者它加载的任何DLL。

    调用堆栈的顶部是:

    CustomMarshalers.dll!System.Runtime.InteropServices.CustomMarshalers.EnumeratorViewOfEnumVariant.MoveNext() + 0x168 bytes
    

        IVCCollection CollectionFiles = (IVCCollection)FolderInProject.Files;
        foreach (VCFile File in CollectionFiles)
        {
            [...]
        }
    

    我怎样才能调试这个呢?

    更新:

    类型为的未处理异常 'System.AccessViolationException异常'

    附加 信息:试图读取或 写保护内存。这是经常发生的 表示其他存储器是 腐败的。

    还是不知道我该怎么调试这个。显然某个地方发生了内存错误。。。但是,在内存模型甚至没有公开的情况下,如何在纯托管代码中跟踪它呢?

    1 回复  |  直到 16 年前
        1
  •  1
  •   user7116    16 年前

    看起来您的COM接口没有正确封送参数/返回变量,导致托管内存被GC意外释放,或者非托管内存由于某些不正确的封送处理而被丢弃。您可以通过构建自己的COM接口来获得对COM接口的更细粒度的控制 Primary Interop Assembly

    现在,另一种可能是您正确地封送所有内容,但是您没有完全正确地调用接口,表现为对参数的不当使用,最终会破坏非托管内存。追踪这些内容就不那么有趣了,尤其是如果您没有访问COM源代码的权限。

    一个技巧是允许程序在调试器之外崩溃,单击Debug,这将打开pick JIT debugger窗口。然后选中“选择调试引擎”(或其他类似的选项),并确保已勾选托管和本机复选框。出现的VS实例应该在实际死亡的代码中被破坏,而不是最接近死亡的托管代码。