问题描述
我有一些 Visual C++ 代码,它接收一个指向缓冲区的指针,该缓冲区包含需要由我的代码处理的数据以及该缓冲区的长度.由于我无法控制的错误,有时这个指针会在未初始化或不适合读取的情况下进入我的代码(即,当我尝试访问缓冲区中的数据时,它会导致崩溃.)
I have some Visual C++ code that receives a pointer to a buffer with data that needs to be processed by my code and the length of that buffer. Due to a bug outside my control, sometimes this pointer comes into my code uninitialized or otherwise unsuitable for reading (i.e. it causes a crash when I try to access the data in the buffer.)
所以,我需要在使用之前验证这个指针.我不想使用 IsBadReadPtr 或 IsBadWritePtr,因为每个人都认为它们有问题.(谷歌他们的例子.)他们也不是线程安全的——在这种情况下这可能不是问题,尽管线程安全的解决方案会很好.
So, I need to verify this pointer before I use it. I don't want to use IsBadReadPtr or IsBadWritePtr because everyone agrees that they're buggy. (Google them for examples.) They're also not thread-safe -- that's probably not a concern in this case, though a thread-safe solution would be nice.
我在网上看到了通过使用 VirtualQuery 或仅在异常处理程序中执行 memcpy 来完成此操作的建议.但是,需要执行此检查的代码对时间很敏感,因此我需要尽可能高效且 100% 有效的检查.任何想法将不胜感激.
I've seen suggestions on the net of accomplishing this by using VirtualQuery, or by just doing a memcpy inside an exception handler. However, the code where this check needs to be done is time sensitive so I need the most efficient check possible that is also 100% effective. Any ideas would be appreciated.
澄清一下:我知道最好的做法是只读取坏指针,让它引发异常,然后追溯到源头并解决实际问题.但是,在这种情况下,坏指针来自我无法控制的 Microsoft 代码,因此我必须验证它们.
Just to be clear: I know that the best practice would be to just read the bad pointer, let it cause an exception, then trace that back to the source and fix the actual problem. However, in this case the bad pointers are coming from Microsoft code that I don't have control over so I have to verify them.
还要注意,我不在乎指向的数据是否有效.我的代码正在寻找特定的数据模式,如果没有找到它们,将忽略这些数据.我只是想防止在对这些数据运行 memcpy 时发生崩溃,并且在尝试 memcpy 时处理异常需要更改遗留代码中的十几个地方(但如果我有类似 IsBadReadPtr 的东西要调用,我只会必须在一处更改代码).
Note also that I don't care if the data pointed at is valid. My code is looking for specific data patterns and will ignore the data if it doesn't find them. I'm just trying to prevent the crash that occurs when running memcpy on this data, and handling the exception at the point memcpy is attempted would require changing a dozen places in legacy code (but if I had something like IsBadReadPtr to call I would only have to change code in one place).
推荐答案
线程安全的解决方案会很好
a thread-safe solution would be nice
我猜只有 IsBadWritePtr 不是线程安全的.
I'm guessing it's only IsBadWritePtr that isn't thread-safe.
只是在异常处理程序中做一个 memcpy
just doing a memcpy inside an exception handler
这实际上是 IsBadReadPtr 正在做的......如果你在你的代码中这样做了,那么你的代码将有与 IsBadReadPtr 实现相同的错误:http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx
This is effectively what IsBadReadPtr is doing ... and if you did it in your code, then your code would have the same bug as the IsBadReadPtr implementation: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx
----
我读过的 IsBadReadPtr 的唯一问题是坏指针可能指向(因此您可能会不小心触及)堆栈的保护页.也许您可以通过以下方式避免此问题(因此可以安全地使用 IsBadReadPtr):
The only problem with IsBadReadPtr that I've read about is that the bad pointer might be pointing to (and so you might accidentally touch) a stack's guard page. Perhaps you could avoid this problem (and therefore use IsBadReadPtr safely), by:
- 了解进程中正在运行的线程
- 知道线程的堆栈在哪里,以及它们有多大
- 在开始调用 isBadReadPtr 之前,走下每个堆栈,故意触摸堆栈的每一页至少一次
此外,与上述 URL 相关的一些评论也建议使用 VirtualQuery.
Also, the some of the comments associated with the URL above also suggest using VirtualQuery.
这篇关于IsBadReadPtr 的最有效替代品?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!