# Битая память, одна общая DLL и badmemorylist

Опубликовано 2026-08-14 · Windows, BSOD, оперативная память, MemTest86, bcdedit · https://home.tigran.manukyan.dev/ru/notes/bad-ram-badmemorylist.html

**TL;DR:** Случайные синие экраны Windows без единой ошибки WHEA оказались одним битым чипом на DDR4 без ECC. Одинаковые падения ILLEGAL_INSTRUCTION в одной общей DLL в разных процессах указали на плохую физическую страницу, MemTest86 это подтвердил, а `bcdedit /set {badmemory} badmemorylist` исключил эти страницы.

Два месяца случайных синих экранов, и у каждого свой stop-код: битые PTE, CRITICAL_PROCESS_DIED, порча LIST_ENTRY, page fault'ы. Плюс несколько жёстких перезагрузок вообще без bugcheck. И ни одной ошибки WHEA.

## Два неверных предположения

- **«Событий WHEA нет — значит, не память».** У обычной памяти без ECC нет обнаружения ошибок. Перевёрнутый бит до WHEA просто не доходит.
- **«Падения идут пачками, а не нарастают постепенно — значит, не железо».** Одна битая ячейка даёт пачку падений, как только на неё попадает активно используемая страница, и затихает, когда страница переезжает.

## Что выдало проблему

Три не связанных между собой сервиса упали с `ILLEGAL_INSTRUCTION` по одному и тому же смещению в одной и той же общей DLL, а хэш DLL на диске сходился. Windows отображает одну физическую копию кода DLL во все процессы. Если этот фрейм битый, каждый процесс декодирует один и тот же мусор. После перезагрузки страница переехала, и падения прекратились.

## Подтверждение

Windows Memory Diagnostic (mdsched) нашёл ошибки уже на первом проходе. MemTest86 насчитал 3278 ошибок за 4 прохода даже на медленной штатной частоте. На тест row hammer пришлось только 12%, так что дело не в пограничных таймингах. 148 битых адресов легли в 16 страниц тремя кластерами, и сбоили всегда одни и те же два бита. Это один чип.

## Огораживаем битые страницы

Windows умеет не использовать конкретные номера физических страниц (PFN):

```
bcdedit /set {badmemory} badmemorylist 0x5EF3E0 0x5EF3E1 ...
bcdedit /enum {badmemory}
```

Каждый кластер я расширил до блока в 16 страниц, всего вышло 48. Потеря, которую не заметишь. Две вещи, которые надо знать:

- `/set` заменяет список целиком. Чтобы потом добавить страницы, заново перечислите и все старые.
- Запишите, где лежат кластеры. Если следующее падение придётся на адрес вне их, чип деградирует, и одного списка уже мало. У меня так и вышло через два месяца, так что новая планка уже в списке покупок.
