以前没有的访问冲突 [英] Access violation where there wasn't one before

查看:18
本文介绍了以前没有的访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 P/调用 Graphviz 如下所示.当我写那篇博文时,代码运行得很好.现在,我正在组合一个 HttpModule,它使用该代码呈现 Graphviz 图形,但是我在 agmemread 处得到了一个 AccessViolationException.

I'm P/Invoking out to Graphviz as shown here. When I wrote that blog entry, the code worked just fine. Now, I'm putting together an HttpModule that renders Graphviz graphs using that code, but I get an AccessViolationException at agmemread.

// Native signature
Agraph_t agmemread(char *);

// P/Invoke Signature
[DllImport(LIB_GRAPH)]
private static extern IntPtr agmemread(string data);

// Usage
IntPtr g = agmemread(data);

就像我说的,这在以前很有效.但是现在,我无法让我的代码在任何地方工作.甚至我基于相同代码的旧 Graphviz 应用程序也无法运行了.

Like I said, this worked perfectly before. But now, I can't get my code to work in anything. Even my old Graphviz apps based on the same code don't work anymore.

我可以改变什么导致这种情况?我什至没有下载新版本的 Graphviz 或任何东西,所以 DLL 都是一样的.

What could I have possibly changed that would cause this? I haven't even downloaded a new version of Graphviz or anything, so the DLLs are all the same.

我尝试将 string 更改为 StringBuilder,但结果相同.然后,我添加了一个 MarshalAs 属性:

I tried changing string to StringBuilder, but that produced the same result. Then, I added a MarshalAs attribute:

static extern IntPtr agmemread([MarshalAs(UnmanagedType.LPWStr)] string data);

这样,我不再收到 AccessViolationException,但 Graphviz 无法正确读取字符串并返回空指针.

With that, I no longer get an AccessViolationException, but Graphviz fails to read the string correctly and returns a null pointer.

推荐答案

非托管代码很少需要 C# 的大量帮助才能开始生成访问冲突.您的 P/Invoke 签名没有问题,这不是原因.

Unmanaged code rarely needs a lot of help from C# to start generating access violations. There's nothing wrong with your P/Invoke signature, that cannot be the cause.

非托管代码中最常见的 AV 来源是堆损坏.C/C++ 代码没有垃圾收集器,必须显式管理内存.它不仅必须注意释放内存(否则会泄漏),它还负责分配正确的大小并确保写入已分配内存的代码不会超过已分配内存块的末尾或写入已经释放的内存.最后一个要求是 C/C++ 代码经常失败的地方.

The most common source of AVs in unmanaged code is heap corruption. C/C++ code doesn't have a garbage collector, memory must be managed explicitly. Not only must it take care of releasing memory (or it will leak), it is also responsible for allocating the correct size and making sure that the code that writes to the allocated memory doesn't write past the end of the allocated memory block or writes into memory that was already freed. That last requirement is where C/C++ code often fails.

堆损坏的问题在于它极难诊断.它可能会在很长一段时间内被忽视.造成的典型损害是内部堆结构被破坏,或者另一个堆分配中的数据被覆盖.这不会导致问题,直到稍后,当堆块被释放或覆盖的数据被使用时.生成异常的代码实际上并不对之前造成的损害负责.这会让您走上错误的轨道,试图找出问题的根源.

The trouble with heap corruption is that it is extremely hard to diagnose. It can go unnoticed for quite a while. The typical damage done is that the internal heap structure is compromised, or the data in another heap allocation is overwritten. That doesn't cause a problem until later, when the heap block is released or the overwritten data is used. The code that generates the exception is not actually responsible for the damage that was done earlier. Which sets you off on the wrong track trying to find the source of the problem.

找到真正的麻烦制造者是非常困难的,您只有几个面包屑就可以找出可能出了什么问题.当您拥有 C/C++ 源代码时,这非常困难,但是在带有调试分配器的调试版本中运行它会有所帮助.没有源代码是不可能的.

Finding the real trouble maker is very hard, you'd have only a few breadcrumbs to figure out what might have gone wrong. It is very hard when you have the C/C++ source code, but running it in a debug build with a debug allocator helps. It is impossible when you don't have the source code.

除非您能从早期调用中找出使用 API 的问题,否则您将需要供应商或支持小组的帮助才能真正解决此问题.祝你好运.

Unless you can pin-point a problem with using the API from earlier calls made, you'll need help from the vendor or support group to really solve this problem. Good luck.

这篇关于以前没有的访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆