311 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			311 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| ============================================
 | |
| 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).
 |