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