当前位置:  开发笔记 > 编程语言 > 正文

最有效的替代IsBadReadPtr?

如何解决《最有效的替代IsBadReadPtr?》经验,为你挑选了3个好方法。

我有一些Visual C++代码接收指向缓冲区的指针,该缓冲区包含需要由我的代码处理的数据和该缓冲区的长度.由于我的控制之外的错误,有时这个指针未初始化我的代码或者不适合阅读(即当我尝试访问缓冲区中的数据时它会导致崩溃.)

所以,我需要在使用它之前验证这个指针.我不想使用IsBadReadPtr或IsBadWritePtr,因为每个人都认为他们是错误的.(谷歌他们的例子.)他们也不是线程安全的 - 在这种情况下可能不是一个问题,虽然线程安全的解决方案会很好.

我已经看到了通过使用VirtualQuery实现这一点的建议,或者只是在异常处理程序中执行memcpy.但是,需要进行此检查的代码是时间敏感的,因此我需要最有效的检查,这也是100%有效.任何想法,将不胜感激.

为了清楚起见:我知道最好的做法是只读坏指针,让它引起异常,然后追溯到源并修复实际问题.但是,在这种情况下,坏指针来自我无法控制的Microsoft代码,所以我必须验证它们.

另请注意,我不关心指向的数据是否有效.我的代码正在寻找特定的数据模式,如果没有找到它们将忽略它们.我只是想防止在对这些数据运行memcpy时发生崩溃,并且在尝试memcpy时处理异常需要在我的代码中更改十几个地方(但如果我有像IsBadReadPtr这样的东西来调用我只会必须在一个地方更改代码).



1> 小智..:
bool IsBadReadPtr(void* p)
{
    MEMORY_BASIC_INFORMATION mbi = {0};
    if (::VirtualQuery(p, &mbi, sizeof(mbi)))
    {
        DWORD mask = (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY);
        bool b = !(mbi.Protect & mask);
        // check the page is not a guard page
        if (mbi.Protect & (PAGE_GUARD|PAGE_NOACCESS)) b = true;

        return b;
    }
    return true;
}


解释你的答案,不要只写代码.
我个人认为这段代码非常有用且易懂.

2> ChrisW..:

一个线程安全的解决方案会很好

我猜它只是IsBadWritePtr不是线程安全的.

只是在异常处理程序中执行memcpy

这实际上是IsBadReadPtr正在做的...如果你在你的代码中做了,那么你的代码将与IsBadReadPtr实现具有相同的错误:http://blogs.msdn.com/oldnewthing/archive/2006/09/ 27/773741.aspx

- 编辑: -

我读过的IsBadReadPtr唯一的问题是坏指针可能指向(因此你可能不小心碰到)堆栈的防护页面.也许你可以通过以下方式避免这个问题(因此安全地使用IsBadReadPtr):

了解您的流程中正在运行的线程

知道线程堆栈的位置,以及它们的大小

走开每个堆栈,在开始调用isBadReadPtr之前,至少触摸一次堆栈的每个页面

此外,与上述URL相关的一些注释也建议使用VirtualQuery.



3> jalf..:

这些功能使用不好的原因是问题无法可靠地解决.

如果您正在调用的函数返回指向已分配的内存的指针,那么它看起来有效,但是它指向其他不相关的数据,并且如果您使用它将损坏您的应用程序.

最有可能的是,您调用的函数实际上表现正常,并且您正在滥用它.(不保证,但通常就是这种情况.)

它的功能是什么?

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有