mirror of
https://github.com/isc-projects/bind9.git
synced 2026-02-24 02:10:30 -05:00
We should drop the HISTORY file because it's confusing and the same information is covered by the release notes for .0 releases (or at least they should be). Remove references to the HISTORY file, update the README to tell people go look somewhere else.
59 lines
1.8 KiB
Text
59 lines
1.8 KiB
Text
Magic Numbers
|
|
|
|
A number of data structures in the ISC and DNS libraries have an unsigned int
|
|
magic number as the first field. The purpose of the magic number is
|
|
principally to validate that a pointer a subroutine has gotten really points
|
|
to the type it claims to be. This helps detect problems caused by resources
|
|
being freed prematurely, that have been corrupted, or that have not been
|
|
properly initialized. It can also be handy in debugging.
|
|
|
|
Magic numbers should always be the first field. They never require locking
|
|
to access. As to the actual value to be used, something mnemonic is good:
|
|
|
|
#define TASK_MAGIC 0x5441534BU /* TASK. */
|
|
#define VALID_TASK(t) ((t) != NULL && \
|
|
(t)->magic == TASK_MAGIC)
|
|
|
|
#define TASK_MANAGER_MAGIC 0x54534B4DU /* TSKM. */
|
|
#define VALID_MANAGER(m) ((m) != NULL && \
|
|
(m)->magic ==
|
|
TASK_MANAGER_MAGIC)
|
|
|
|
Unless the memory cost is critical, most objects should have a magic number.
|
|
|
|
The magic number should be the last field set in a creation routine, so that
|
|
an object will never be stamped with a magic number unless it is valid.
|
|
|
|
The magic number should be set to zero immediately before the object is
|
|
freed.
|
|
|
|
Magic values are generally private to the implementation of the type. I.e.
|
|
they are defined in the .c file, not the .h file.
|
|
|
|
Validation of magic numbers is done by routines that manipulate the type,
|
|
not by users of the type. Indeed, user validation is usually not possible
|
|
because the magic number is not public.
|
|
|
|
Magic number checking may become a build option in a future release. E.g.
|
|
|
|
struct foo {
|
|
ISC_MAGIC_DECLARATION
|
|
/* ... */
|
|
}
|
|
|
|
foo_create() {
|
|
/* ... */
|
|
ISC_MAGIC_SET(value);
|
|
}
|
|
|
|
foo_destroy() {
|
|
/* ... */
|
|
ISC_MAGIC_CLEAR(value);
|
|
}
|
|
|
|
#define FOO_MAGIC 0x00010203U
|
|
#define VALID_FOO(f) ISC_MAGIC_VALIDATE(f, FOO_MAGIC)
|
|
|
|
foo_dosomething(foo *f) {
|
|
REQUIRE(VALID_FOO(f));
|
|
}
|