debugobjects.tmpl 15.5 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>

<book id="debug-objects-guide">
 <bookinfo>
  <title>Debug objects life time</title>

  <authorgroup>
   <author>
    <firstname>Thomas</firstname>
    <surname>Gleixner</surname>
    <affiliation>
     <address>
      <email>tglx@linutronix.de</email>
     </address>
    </affiliation>
   </author>
  </authorgroup>

  <copyright>
   <year>2008</year>
   <holder>Thomas Gleixner</holder>
  </copyright>

  <legalnotice>
   <para>
     This documentation is free software; you can redistribute
     it and/or modify it under the terms of the GNU General Public
     License version 2 as published by the Free Software Foundation.
   </para>

   <para>
     This program is distributed in the hope that it will be
     useful, but WITHOUT ANY WARRANTY; without even the implied
     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     See the GNU General Public License for more details.
   </para>

   <para>
     You should have received a copy of the GNU General Public
     License along with this program; if not, write to the Free
     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     MA 02111-1307 USA
   </para>

   <para>
     For more details see the file COPYING in the source
     distribution of Linux.
   </para>
  </legalnotice>
 </bookinfo>

<toc></toc>

  <chapter id="intro">
    <title>Introduction</title>
    <para>
      debugobjects is a generic infrastructure to track the life time
      of kernel objects and validate the operations on those.
    </para>
    <para>
      debugobjects is useful to check for the following error patterns:
	<itemizedlist>
	  <listitem><para>Activation of uninitialized objects</para></listitem>
	  <listitem><para>Initialization of active objects</para></listitem>
	  <listitem><para>Usage of freed/destroyed objects</para></listitem>
	</itemizedlist>
    </para>
    <para>
      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.
    </para>
  </chapter>

  <chapter id="howto">
    <title>Howto use debugobjects</title>
    <para>
      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.
    </para>
    <para>
      The debug calls provided by debugobjects are:
      <itemizedlist>
	<listitem><para>debug_object_init</para></listitem>
	<listitem><para>debug_object_init_on_stack</para></listitem>
	<listitem><para>debug_object_activate</para></listitem>
	<listitem><para>debug_object_deactivate</para></listitem>
	<listitem><para>debug_object_destroy</para></listitem>
	<listitem><para>debug_object_free</para></listitem>
	<listitem><para>debug_object_assert_init</para></listitem>
      </itemizedlist>
      Each of these functions takes the address of the real object and
      a pointer to the object type specific debug description
      structure.
    </para>
    <para>
      Each detected error is reported in the statistics and a limited
      number of errors are printk'ed including a full stack trace.
    </para>
    <para>
      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.
    </para>
  </chapter>
  <chapter id="debugfunctions">
    <title>Debug functions</title>
    <sect1 id="prototypes">
      <title>Debug object function reference</title>
!Elib/debugobjects.c
    </sect1>
    <sect1 id="debug_object_init">
      <title>debug_object_init</title>
      <para>
	This function is called whenever the initialization function
	of a real object is called.
      </para>
      <para>
	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.
      </para>
      <para>
	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.
      </para>
    </sect1>

    <sect1 id="debug_object_init_on_stack">
      <title>debug_object_init_on_stack</title>
      <para>
	This function is called whenever the initialization function
	of a real object which resides on the stack is called.
      </para>
      <para>
	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.
      </para>
      <para>
	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.
      </para>
      <para>
	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.
      </para>
    </sect1>

    <sect1 id="debug_object_activate">
      <title>debug_object_activate</title>
      <para>
	This function is called whenever the activation function of a
	real object is called.
      </para>
      <para>
	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.
      </para>
      <para>
	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.
      </para>
      <para>
	When the activation is legitimate, then the state of the
	associated tracker object is set to ODEBUG_STATE_ACTIVE.
      </para>
    </sect1>

    <sect1 id="debug_object_deactivate">
      <title>debug_object_deactivate</title>
      <para>
	This function is called whenever the deactivation function of
	a real object is called.
      </para>
      <para>
	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.
      </para>
      <para>
	When the deactivation is legitimate, then the state of the
	associated tracker object is set to ODEBUG_STATE_INACTIVE.
      </para>
    </sect1>

    <sect1 id="debug_object_destroy">
      <title>debug_object_destroy</title>
      <para>
	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.
      </para>
      <para>
	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.
      </para>
      <para>
	When the destruction is legitimate, then the state of the
	associated tracker object is set to ODEBUG_STATE_DESTROYED.
      </para>
    </sect1>

    <sect1 id="debug_object_free">
      <title>debug_object_free</title>
      <para>
	This function is called before an object is freed.
      </para>
      <para>
	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.
      </para>
      <para>
	Note that debug_object_free removes the object from the
	tracker. Later usage of the object is detected by the other
	debug checks.
      </para>
    </sect1>

    <sect1 id="debug_object_assert_init">
      <title>debug_object_assert_init</title>
      <para>
	This function is called to assert that an object has been
	initialized.
      </para>
      <para>
	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.
      </para>
      <para>
	When the real object is already tracked by debugobjects it is
	ignored.
      </para>
    </sect1>
  </chapter>
  <chapter id="fixupfunctions">
    <title>Fixup functions</title>
    <sect1 id="debug_obj_descr">
      <title>Debug object type description structure</title>
!Iinclude/linux/debugobjects.h
    </sect1>
    <sect1 id="fixup_init">
      <title>fixup_init</title>
      <para>
	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.
      </para>
      <para>
	Called from debug_object_init when the object state is:
	<itemizedlist>
	  <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
	</itemizedlist>
      </para>
      <para>
	The function returns 1 when the fixup was successful,
	otherwise 0. The return value is used to update the
	statistics.
      </para>
      <para>
	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.
      </para>
    </sect1>

    <sect1 id="fixup_activate">
      <title>fixup_activate</title>
      <para>
	This function is called from the debug code whenever a problem
	in debug_object_activate is detected.
      </para>
      <para>
	Called from debug_object_activate when the object state is:
	<itemizedlist>
	  <listitem><para>ODEBUG_STATE_NOTAVAILABLE</para></listitem>
	  <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
	</itemizedlist>
      </para>
      <para>
	The function returns 1 when the fixup was successful,
	otherwise 0. The return value is used to update the
	statistics.
      </para>
      <para>
	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.
      </para>
      <para>
	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 0 because this is not a real fixup.
      </para>
    </sect1>

    <sect1 id="fixup_destroy">
      <title>fixup_destroy</title>
      <para>
	This function is called from the debug code whenever a problem
	in debug_object_destroy is detected.
      </para>
      <para>
	Called from debug_object_destroy when the object state is:
	<itemizedlist>
	  <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
	</itemizedlist>
      </para>
      <para>
	The function returns 1 when the fixup was successful,
	otherwise 0. The return value is used to update the
	statistics.
      </para>
    </sect1>
    <sect1 id="fixup_free">
      <title>fixup_free</title>
      <para>
	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.
      </para>
      <para>
	Called from debug_object_free() or debug_check_no_obj_freed()
	when the object state is:
	<itemizedlist>
	  <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
	</itemizedlist>
      </para>
      <para>
	The function returns 1 when the fixup was successful,
	otherwise 0. The return value is used to update the
	statistics.
      </para>
    </sect1>
    <sect1 id="fixup_assert_init">
      <title>fixup_assert_init</title>
      <para>
	This function is called from the debug code whenever a problem
	in debug_object_assert_init is detected.
      </para>
      <para>
	Called from debug_object_assert_init() with a hardcoded state
	ODEBUG_STATE_NOTAVAILABLE when the object is not found in the
	debug bucket.
      </para>
      <para>
	The function returns 1 when the fixup was successful,
	otherwise 0. The return value is used to update the
	statistics.
      </para>
      <para>
	Note, this function should make sure debug_object_init() is
	called before returning.
      </para>
      <para>
	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 0 because this is not
	a real fixup.
      </para>
    </sect1>
  </chapter>
  <chapter id="bugs">
    <title>Known Bugs And Assumptions</title>
    <para>
	None (knock on wood).
    </para>
  </chapter>
</book>