{"record":{"id":"e45a5a11ab341316","repo":"NationalSecurityAgency/ghidra","slug":"trace-bytes-table-is-corrupt","errorCode":null,"errorMessage":"Trace Bytes table is corrupt","messagePattern":"Trace Bytes table is corrupt","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemoryBlockEntry.java","lineNumber":172,"sourceCode":"\tprotected DBTraceMemoryBufferEntry findFreeBuffer() throws IOException {\n\t\tDBTraceMemoryBufferEntry ent = findFreeBufferInPast();\n\t\tif (ent != null) {\n\t\t\treturn ent;\n\t\t}\n\t\tent = findFreeBufferInFuture();\n\t\tif (ent != null) {\n\t\t\treturn ent;\n\t\t}\n\t\treturn allocateNewBuffer();\n\t}\n\n\tprotected DBTraceMemoryBufferEntry findAssignedBuffer() throws IOException {\n\t\tif (bufferKey == -1) {\n\t\t\treturn null;\n\t\t}\n\t\tDBTraceMemoryBufferEntry bufEnt = space.bufferStore.getObjectAt(bufferKey);\n\t\tif (bufEnt == null) {\n\t\t\tthrow new IOException(\"Trace Bytes table is corrupt\");\n\t\t}\n\t\treturn bufEnt;\n\t}\n\n\tprotected static boolean isZeroes(ByteBuffer buf, int len) {\n\t\tint pos = buf.position();\n\t\tfor (int i = 0; i < len; i++) {\n\t\t\tif (buf.get(pos + i) != 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tpublic int setBytes(ByteBuffer buf, int dstOffset, int len) throws IOException {\n\t\tDBTraceMemoryBufferEntry bufEnt = findAssignedBuffer();\n\t\tif (bufEnt == null) {\n\t\t\tif (isZeroes(buf, len)) {","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemoryBlockEntry.java#L154-L190","documentation":"Thrown by DBTraceMemoryBlockEntry.findAssignedBuffer() when the block has a valid bufferKey (!= -1) but the buffer store returns null for that key via space.bufferStore.getObjectAt(bufferKey). This indicates the trace's Bytes table is internally inconsistent: a block references a buffer that no longer exists. An IOException (checked) signals database corruption that cannot be recovered programmatically.","triggerScenarios":"Reading trace memory when a DBTraceMemoryBlockEntry references a bufferKey in the buffer store, but the DBTraceMemoryBufferEntry at that key has been deleted or was never written. This occurs during getBytes(), findAssignedBuffer(), or buffer allocation paths.","commonSituations":"Database file corruption due to improper shutdown, disk failure, or concurrent access issues. Trace database was partially written or interrupted during save. Version mismatch or incomplete upgrade of the trace database format. Manual editing or external corruption of the .gdb database files.","solutions":["Restore the trace database from a known-good backup.","Re-create the trace by re-importing or re-recording the debugging session.","Run Ghidra's database repair/upgrade tools if available.","If the corruption is limited to one block, consider clearing and re-recording memory for that address range."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    byte[] bytes = memory.getBytes(addr, buf);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"corrupt\")) {\n        // trace database corruption — restore from backup or re-record\n        logger.severe(\"Trace database corruption detected: \" + e.getMessage());\n    }\n}","preventionTips":["Maintain backups of trace databases.","Use proper shutdown procedures for Ghidra to avoid database corruption.","Monitor disk health to prevent write corruption.","Re-record traces from the original debugging sessions when corruption occurs."],"tags":["memory","trace-database","corruption","checked-exception","io"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}