{"record":{"id":"ad224e42d110f968","repo":"kovidgoyal/kitty","slug":"failed-to-unmap-history-buffer-segment-s","errorCode":null,"errorMessage":"Failed to unmap history buffer segment: %s","messagePattern":"Failed to unmap history buffer segment: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/history.c","lineNumber":47,"sourceCode":"    // https://github.com/kovidgoyal/kitty/pull/10254\n    char *mem = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);\n    if (mem == MAP_FAILED) fatal(\"Out of memory allocating new history buffer segment\");\n    char *needs_free = mem;\n    for (HistoryBufSegment *s = self->segments + self->num_segments; s < self->segments + self->num_segments + num; s++, mem += segment_size) {\n        s->cpu_cells = (CPUCell *)mem;\n        s->gpu_cells = (GPUCell *)(((uint8_t *)s->cpu_cells) + cpu_cells_size);\n        s->line_attrs = (LineAttrs *)(((uint8_t *)s->gpu_cells) + gpu_cells_size);\n        s->mem = NULL;\n        s->mmap_size = 0;\n    }\n    self->segments[self->num_segments].mem = needs_free;\n    self->segments[self->num_segments].mmap_size = mmap_size;\n    self->num_segments += num;\n}\n\nstatic void\nfree_segment(HistoryBufSegment *s) {\n    if (s->mem && munmap(s->mem, s->mmap_size) != 0) log_error(\"Failed to unmap history buffer segment: %s\", strerror(errno));\n    zero_at_ptr(s);\n}\n\nstatic index_type\nsegment_for(HistoryBuf *self, index_type y) {\n    index_type seg_num = y / SEGMENT_SIZE;\n    while (UNLIKELY(seg_num >= self->num_segments && SEGMENT_SIZE * self->num_segments < self->ynum)) add_segment(self, 1);\n    if (UNLIKELY(seg_num >= self->num_segments)) fatal(\"Out of bounds access to history buffer line number: %u\", y);\n    return seg_num;\n}\n\n#define seg_ptr(which, stride)                             \\\n    {                                                      \\\n        index_type seg_num = segment_for(self, y);         \\\n        y -= seg_num * SEGMENT_SIZE;                       \\\n        return self->segments[seg_num].which + y * stride; \\\n    }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/history.c#L29-L65","documentation":"munmap of a scrollback (history buffer) segment failed; strerror(errno) explains why. The segment metadata is still zeroed, so this is a leak warning rather than a crash. Almost always indicates an internal bug or memory corruption.","triggerScenarios":"free_segment during historybuf_clear or HistoryBuf dealloc when munmap(s->mem, s->mmap_size) returns non-zero - corrupted mmap_size, double unmap, or VM subsystem inconsistency.","commonSituations":"Essentially never seen in practice; would indicate memory corruption, a kitty bug, or unusual allocator/libc environments.","solutions":["Report upstream to kitty with reproduction steps - this indicates an internal bug","Upgrade kitty to the latest version","Rule out LD_PRELOAD allocator overrides or sanitizers","Restart kitty if it recurs"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Nothing user-side to guard - internal munmap failure; keep kitty updated"],"tags":["kitty","munmap","scrollback","internal"],"backgroundTag":"munmap-failed","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}