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

使用AcquirePointer时,处理安全内存AppedViewHandle的正确方法是什么?

  •  0
  • Polynomial  · 技术社区  · 7 年前

    ReadOnlySlice<T> 用于许多解析操作。简化课程代码如下:

    public MemoryMappedViewAccessor Accessor { get; }
    public SafeMemoryMappedViewHandle Handle { get; }
    public byte* Memory;
    private long _size;
    
    public Parser(MemoryMappedFile mappedFile, long offset, long size)
    {
        _size = size;
        Accessor = mappedFile.CreateViewAccessor(offset, _size, MemoryMappedFileAccess.Read);
        Handle = Accessor.SafeMemoryMappedViewHandle;
        unsafe
        {
            Handle.AcquirePointer(ref Memory);
        }
    }
    
    public ReadOnlySlice<T> GetSpan<T>(int offset, int size)
    {
        return new ReadOnlySpan<T>(chunk.Memory, _size).Slice(offset, size);
    }
    
    /* other functions exposing various Slice<T> over this */
    

    显然,这需要我的类来实现 IDisposable ,但我不确定不安全资源和安全资源之间的界限在哪里。一 reference I found 说 SafeMemoryMappedViewHandle ReleasePointer ,或是否 释放指针 甚至应该提前打电话 Dispose .

    在我看来,以下两个 处置 模式是我的选择:

    选项1-将一切视为管理

    private bool _isDisposed = false;
    
    protected virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                Accessor.Dispose();
                Handle.ReleasePointer(); // is this even needed?
                Handle.Dispose();
            }
    
            _isDisposed = true;
        }
    }
    
    public void Dispose()
    {
        Dispose(true);
    }
    

    选项2-将指针释放视为非托管

    private bool _isDisposed = false;
    
    protected virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                Accessor.Dispose();
            }
    
            Handle.ReleasePointer();
            Handle.Dispose();
    
            _isDisposed = true;
        }
    }
    
    ~FileChunk()
    {
        Dispose(false);
    }
    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    

    在这两种情况下,我都会在解析逻辑中添加一个检查以抛出 ObjectDisposedException _isDisposed 是真的,以避免UAF错误和内存损坏。

    安全记忆体appedviewhandle ? 此外,是否值得设置 Memory

    0 回复  |  直到 7 年前