Gunnar Dalsnes wrote:
Additional
proposal: invariant ASSERTs in list manipulation routines,
What does invariant mean?
invariant = something that doesn't vary. All algorithms have invariants
of some sort, and they are usually assumed (i.e. checking the invariants
isn't part of the algorithm, and checks, if expressed in code, are
usually only compiled in debug builds - see ASSERT). The invariant of
all helper functions manipulating LIST_ENTRYs is that the LIST_ENTRYs
are valid, i.e.:
ASSERT(ListEntry && ListEntry->Flink && ListEntry->Blink &&
ListEntry->Flink->Blink == ListEntry && ListEntry->Blink->Flink ==
ListEntry)
You need to ensure this is always true: before manipulating the object
and (especially!) after you're done with it (i.e. it should be the first
and last line of every LIST_ENTRY helper function)
especially the
precondition that inputs are valid LIST_ENTRYs. Saved
my ass so many times
Yeah. I miss those. I think we had something like that before(?). If
noone objects lets readd list asserts (and no, not the "insane"
variant that walks and validated the entire list, allthou that is very
handy sometimes too;-)
the "insane" checks can be performed once in N times, if they are too
much of a performance hit. And please don't hardcode calls to
KeBugCheckEx in ASSERT - RtlAssert is where you're supposed to implement
assertion failure logic, the ASSERT macro is just candy coating on it