{"record":{"id":"1bcfc176135e3fe3","repo":"microsoft/FASTER","slug":"attempting-to-allocate-an-already-allocated-block","errorCode":null,"errorMessage":"Attempting to allocate an already-allocated block","messagePattern":"Attempting to allocate an already-allocated block","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"error","filePath":"cs/src/core/Utilities/BufferPool.cs","lineNumber":85,"sourceCode":"\n        internal SectorAlignedBufferPool pool;\n\n#if CHECK_FREE\n        internal bool Free\n        {\n            get => (level & kFreeBitMask) != 0;\n            set \n            {\n                if (value)\n                {\n                    if (Free)\n                        throw new FasterException(\"Attempting to return an already-free block\");\n                    this.level |= kFreeBitMask;\n                }\n                else\n                {\n                    if (!Free)\n                        throw new FasterException(\"Attempting to allocate an already-allocated block\");\n                    this.level &= ~kFreeBitMask;\n                }\n            }\n        }\n#endif // CHECK_FREE\n\n        /// <summary>\n        /// Default constructor\n        /// </summary>\n        public SectorAlignedMemory(int level = default)\n        {\n            this.level = level;\n            // Assume ctor is called for allocation and leave Free unset\n        }\n\n        /// <summary>\n        /// Create new instance of SectorAlignedMemory\n        /// </summary>","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/Utilities/BufferPool.cs#L67-L103","documentation":"FasterException thrown by the DEBUG-only (CHECK_FREE) guard in BufferPool's SectorAlignedMemory state setter. Each pooled block carries a free/allocated bit; this fires when code calls Allocate() on a block whose kFreeBitMask indicates it is already allocated, i.e. a double-acquire of the same buffer. It indicates broken ownership tracking of pooled sector-aligned memory.","triggerScenarios":"Calling SectorAlignedMemory.Allocate() (via BufferPool.Get/GetBufferPool) on a block that is already marked allocated — typically handing the same SectorAlignedMemory object to two consumers, or calling Allocate twice without a matching Free in between.","commonSituations":"Refactoring code that returns buffers to the pool while keeping a reference to the old buffer; sharing a buffer across threads without synchronization; custom checkpoint/replay code re-acquiring a saved buffer reference; only surfaces in CHECK_FREE builds so it appears after enabling debug checks.","solutions":["Audit ownership so each SectorAlignedMemory is allocated by exactly one consumer at a time","Ensure every Allocate is paired with exactly one Free and the reference is not reused after freeing","Guard shared buffers with synchronization or per-thread pools instead of sharing one pool entry","Enable/keep CHECK_FREE in tests to catch double allocation before production"],"exampleFix":"// before\nvar buf = pool.Get(0);\nUse(buf);\nbuf.Allocate(); // throws: already allocated\n// after\nvar buf = pool.Get(0);\nUse(buf);\nbuf.Free();\nvar buf2 = pool.Get(0); // allocate a fresh block instead","handlingStrategy":"validation","validationCode":"if (buffer.Free) buffer.Allocate(); else throw new InvalidOperationException(\"Buffer already allocated; fix ownership\");","typeGuard":"bool IsAllocatable(SectorAlignedMemory m) => m != null && m.Free;","tryCatchPattern":null,"preventionTips":["Treat pooled buffers as single-owner resources; never share references across consumers","Pair every Get/Allocate with exactly one Free in a using or try/finally","Run CHECK_FREE builds in CI to catch double allocation early"],"tags":["memory","buffer-pool","double-allocation","csharp"],"backgroundTag":"internal-invariant-violation","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}