На заступ надо провериться -- вдруг данных пишется больше, чем ожидалось (или железо пинается не на те адреса, выгрузка "в молоко"), портятся системные области, а там уже и "рух" недалеко.
Если нет такого "системного" средства в ОС, надо как-то "встрять" в каждое выделение/освобождение памяти, выделять на 16 байт больше, заливать первые 8 чем-то "особым", типа "DEADBEAF", последние 8 аналогично и возвращать указатель +8, ну а при возврате -- проверять на "особость". Обычно "вдаль" сразу никто не заступает, и так ловится большинство проблем.
Если этот заступ, конечно, был давно, определить причину будет трудно, ибо придётся отмотать момент выделения данного куска, кому он был нужен и для чего.
Тогда нужно стабилизировать наступление глюка: например, "принимать" пакеты не из физики, а из рандомного генератора. Вдруг при его стабильном стартовом значении и дальше всё будет повторяться 1в1...
Исходники если есть -- при первом же неуспехе memp_malloc_fn можно ставить точку останова, прыгать там на повторный вызов и разглядывать по шагам, отчего же не вышло. Вдруг ОС не будет "в фоне" бяки делать в процессе этого.
Реентерабельность вдруг где хромает, семафор где-то "застреливают" аппаратной выгрузкой, возвращаемое значение при захвате не анализируют полностью...
Абсолютно детерминированная "повторябельность на N-м такте" при лечении глюков может сильно помочь, её надо добиваться в первую очередь. Тогда, в принципе, можно остановиться на любом предыдущем и проследить всё остальное. Где-то и "назад" могут степать отладчики, но жить в эту пору прекрасную...
Передачу "из" тоже можно задействовать в крайнем случае -- в те пакеты писать трассировку выделений/освобождений адресов, она не должна сильно изменить "приёмное" направление, чтобы глюк совсем исчез, но позволит на персоналке потом декодировать и проводить анализы нелогичностей, добавлять новую трассировку в целях отладки...
То, что обрасывается, тоже можно проверять "на подлинность" -- слалось такое вообще снаружи, или мусор.
Тело выделяемого пакета при такой проверке тоже должно иметь детерминированную заливку, чтобы не было "повторного использования" принятых 3 мин назад данных как "более-менее валидных".
TCP в данном случае достаточно нехороший протокол (там много форматных излишеств ради восстановления пропавших пакетов, которые в локалке очень трудно сейчас "задушить"), легче через UDP попытаться вести "обстрел".