123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- ============================================
- The object-lifetime debugging infrastructure
- ============================================
- :Author: Thomas Gleixner
- Introduction
- ============
- debugobjects is a generic infrastructure to track the life time of
- kernel objects and validate the operations on those.
- debugobjects is useful to check for the following error patterns:
- - Activation of uninitialized objects
- - Initialization of active objects
- - Usage of freed/destroyed objects
- debugobjects is not changing the data structure of the real object so it
- can be compiled in with a minimal runtime impact and enabled on demand
- with a kernel command line option.
- Howto use debugobjects
- ======================
- A kernel subsystem needs to provide a data structure which describes the
- object type and add calls into the debug code at appropriate places. The
- data structure to describe the object type needs at minimum the name of
- the object type. Optional functions can and should be provided to fixup
- detected problems so the kernel can continue to work and the debug
- information can be retrieved from a live system instead of hard core
- debugging with serial consoles and stack trace transcripts from the
- monitor.
- The debug calls provided by debugobjects are:
- - debug_object_init
- - debug_object_init_on_stack
- - debug_object_activate
- - debug_object_deactivate
- - debug_object_destroy
- - debug_object_free
- - debug_object_assert_init
- Each of these functions takes the address of the real object and a
- pointer to the object type specific debug description structure.
- Each detected error is reported in the statistics and a limited number
- of errors are printk'ed including a full stack trace.
- The statistics are available via /sys/kernel/debug/debug_objects/stats.
- They provide information about the number of warnings and the number of
- successful fixups along with information about the usage of the internal
- tracking objects and the state of the internal tracking objects pool.
- Debug functions
- ===============
- .. kernel-doc:: lib/debugobjects.c
- :functions: debug_object_init
- This function is called whenever the initialization function of a real
- object is called.
- When the real object is already tracked by debugobjects it is checked,
- whether the object can be initialized. Initializing is not allowed for
- active and destroyed objects. When debugobjects detects an error, then
- it calls the fixup_init function of the object type description
- structure if provided by the caller. The fixup function can correct the
- problem before the real initialization of the object happens. E.g. it
- can deactivate an active object in order to prevent damage to the
- subsystem.
- When the real object is not yet tracked by debugobjects, debugobjects
- allocates a tracker object for the real object and sets the tracker
- object state to ODEBUG_STATE_INIT. It verifies that the object is not
- on the callers stack. If it is on the callers stack then a limited
- number of warnings including a full stack trace is printk'ed. The
- calling code must use debug_object_init_on_stack() and remove the
- object before leaving the function which allocated it. See next section.
- .. kernel-doc:: lib/debugobjects.c
- :functions: debug_object_init_on_stack
- This function is called whenever the initialization function of a real
- object which resides on the stack is called.
- When the real object is already tracked by debugobjects it is checked,
- whether the object can be initialized. Initializing is not allowed for
- active and destroyed objects. When debugobjects detects an error, then
- it calls the fixup_init function of the object type description
- structure if provided by the caller. The fixup function can correct the
- problem before the real initialization of the object happens. E.g. it
- can deactivate an active object in order to prevent damage to the
- subsystem.
- When the real object is not yet tracked by debugobjects debugobjects
- allocates a tracker object for the real object and sets the tracker
- object state to ODEBUG_STATE_INIT. It verifies that the object is on
- the callers stack.
- An object which is on the stack must be removed from the tracker by
- calling debug_object_free() before the function which allocates the
- object returns. Otherwise we keep track of stale objects.
- .. kernel-doc:: lib/debugobjects.c
- :functions: debug_object_activate
- This function is called whenever the activation function of a real
- object is called.
- When the real object is already tracked by debugobjects it is checked,
- whether the object can be activated. Activating is not allowed for
- active and destroyed objects. When debugobjects detects an error, then
- it calls the fixup_activate function of the object type description
- structure if provided by the caller. The fixup function can correct the
- problem before the real activation of the object happens. E.g. it can
- deactivate an active object in order to prevent damage to the subsystem.
- When the real object is not yet tracked by debugobjects then the
- fixup_activate function is called if available. This is necessary to
- allow the legitimate activation of statically allocated and initialized
- objects. The fixup function checks whether the object is valid and calls
- the debug_objects_init() function to initialize the tracking of this
- object.
- When the activation is legitimate, then the state of the associated
- tracker object is set to ODEBUG_STATE_ACTIVE.
- .. kernel-doc:: lib/debugobjects.c
- :functions: debug_object_deactivate
- This function is called whenever the deactivation function of a real
- object is called.
- When the real object is tracked by debugobjects it is checked, whether
- the object can be deactivated. Deactivating is not allowed for untracked
- or destroyed objects.
- When the deactivation is legitimate, then the state of the associated
- tracker object is set to ODEBUG_STATE_INACTIVE.
- .. kernel-doc:: lib/debugobjects.c
- :functions: debug_object_destroy
- This function is called to mark an object destroyed. This is useful to
- prevent the usage of invalid objects, which are still available in
- memory: either statically allocated objects or objects which are freed
- later.
- When the real object is tracked by debugobjects it is checked, whether
- the object can be destroyed. Destruction is not allowed for active and
- destroyed objects. When debugobjects detects an error, then it calls the
- fixup_destroy function of the object type description structure if
- provided by the caller. The fixup function can correct the problem
- before the real destruction of the object happens. E.g. it can
- deactivate an active object in order to prevent damage to the subsystem.
- When the destruction is legitimate, then the state of the associated
- tracker object is set to ODEBUG_STATE_DESTROYED.
- .. kernel-doc:: lib/debugobjects.c
- :functions: debug_object_free
- This function is called before an object is freed.
- When the real object is tracked by debugobjects it is checked, whether
- the object can be freed. Free is not allowed for active objects. When
- debugobjects detects an error, then it calls the fixup_free function of
- the object type description structure if provided by the caller. The
- fixup function can correct the problem before the real free of the
- object happens. E.g. it can deactivate an active object in order to
- prevent damage to the subsystem.
- Note that debug_object_free removes the object from the tracker. Later
- usage of the object is detected by the other debug checks.
- .. kernel-doc:: lib/debugobjects.c
- :functions: debug_object_assert_init
- This function is called to assert that an object has been initialized.
- When the real object is not tracked by debugobjects, it calls
- fixup_assert_init of the object type description structure provided by
- the caller, with the hardcoded object state ODEBUG_NOT_AVAILABLE. The
- fixup function can correct the problem by calling debug_object_init
- and other specific initializing functions.
- When the real object is already tracked by debugobjects it is ignored.
- Fixup functions
- ===============
- Debug object type description structure
- ---------------------------------------
- .. kernel-doc:: include/linux/debugobjects.h
- :internal:
- fixup_init
- -----------
- This function is called from the debug code whenever a problem in
- debug_object_init is detected. The function takes the address of the
- object and the state which is currently recorded in the tracker.
- Called from debug_object_init when the object state is:
- - ODEBUG_STATE_ACTIVE
- The function returns true when the fixup was successful, otherwise
- false. The return value is used to update the statistics.
- Note, that the function needs to call the debug_object_init() function
- again, after the damage has been repaired in order to keep the state
- consistent.
- fixup_activate
- ---------------
- This function is called from the debug code whenever a problem in
- debug_object_activate is detected.
- Called from debug_object_activate when the object state is:
- - ODEBUG_STATE_NOTAVAILABLE
- - ODEBUG_STATE_ACTIVE
- The function returns true when the fixup was successful, otherwise
- false. The return value is used to update the statistics.
- Note that the function needs to call the debug_object_activate()
- function again after the damage has been repaired in order to keep the
- state consistent.
- The activation of statically initialized objects is a special case. When
- debug_object_activate() has no tracked object for this object address
- then fixup_activate() is called with object state
- ODEBUG_STATE_NOTAVAILABLE. The fixup function needs to check whether
- this is a legitimate case of a statically initialized object or not. In
- case it is it calls debug_object_init() and debug_object_activate()
- to make the object known to the tracker and marked active. In this case
- the function should return false because this is not a real fixup.
- fixup_destroy
- --------------
- This function is called from the debug code whenever a problem in
- debug_object_destroy is detected.
- Called from debug_object_destroy when the object state is:
- - ODEBUG_STATE_ACTIVE
- The function returns true when the fixup was successful, otherwise
- false. The return value is used to update the statistics.
- fixup_free
- -----------
- This function is called from the debug code whenever a problem in
- debug_object_free is detected. Further it can be called from the debug
- checks in kfree/vfree, when an active object is detected from the
- debug_check_no_obj_freed() sanity checks.
- Called from debug_object_free() or debug_check_no_obj_freed() when
- the object state is:
- - ODEBUG_STATE_ACTIVE
- The function returns true when the fixup was successful, otherwise
- false. The return value is used to update the statistics.
- fixup_assert_init
- -------------------
- This function is called from the debug code whenever a problem in
- debug_object_assert_init is detected.
- Called from debug_object_assert_init() with a hardcoded state
- ODEBUG_STATE_NOTAVAILABLE when the object is not found in the debug
- bucket.
- The function returns true when the fixup was successful, otherwise
- false. The return value is used to update the statistics.
- Note, this function should make sure debug_object_init() is called
- before returning.
- The handling of statically initialized objects is a special case. The
- fixup function should check if this is a legitimate case of a statically
- initialized object or not. In this case only debug_object_init()
- should be called to make the object known to the tracker. Then the
- function should return false because this is not a real fixup.
- Known Bugs And Assumptions
- ==========================
- None (knock on wood).
|