
<!DOCTYPE BOOK [
<!NOTATION eqn SYSTEM "">
<!NOTATION gif87a PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 87a//EN">
<!NOTATION jpeg PUBLIC "ISO/IEC 10918:1993//NOTATION Digital Compression and Coding of Continuous-tone Still Images (JPEG)//EN">
<!NOTATION gif89a PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">
<!NOTATION pcx PUBLIC "+//ISBN 0-7923-9432-1::Graphic Notation//NOTATION ZSoft PCX bitmap//EN">
<!NOTATION tex PUBLIC "+//ISBN 0-201-13448-9::Knuth//NOTATION The TeXbook//EN">
<!NOTATION java PUBLIC "-//Sun Microsystems//NOTATION Java Programming Language V1.1//EN">
<!NOTATION tbl SYSTEM "">
<!NOTATION png PUBLIC "-//W3C//NOTATION Portable Network Graphics (PNG) Version 1.0//EN">
<!NOTATION tiff SYSTEM "">
<!NOTATION eps PUBLIC "+//ISBN 0-201-18127-4::Adobe//NOTATION PostScript Language Ref. Manual//EN">
<!NOTATION mpeg SYSTEM "">
<!NOTATION linespecific SYSTEM "">
<!NOTATION sgml PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language//EN">
<!NOTATION gif SYSTEM "">
<!NOTATION au PUBLIC "-//Sun Microsystems//NOTATION Sun Audio File format//EN">
<!NOTATION pic SYSTEM "">
<!NOTATION bmp PUBLIC "+//ISBN 0-7923-9432-1::Graphic Notation//NOTATION Microsoft Windows bitmap//EN">
<!ENTITY REFMAN3A PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0627//EN" "" NDATA sgml>
<!ENTITY mdb-arch SYSTEM "figures/mdb-arch.epsi.gif" NDATA gif>
<!ENTITY MODDEBUG PUBLIC "-//Sun::SunSoft//DOCUMENT MODDEBUG Version 2.0//EN" "" NDATA sgml>
<!ENTITY REFMAN1 PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0624//EN" "" NDATA sgml>
<!ENTITY REFMAN2 PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0626//EN" "" NDATA sgml>
<!ENTITY REFMAN4 PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0633//EN" "" NDATA sgml>
<!ENTITY REFMAN7 PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0636//EN" "" NDATA sgml>
<!ENTITY DRIVER PUBLIC "-//Sun::SunSoft//DOCUMENT 805-7378//EN" "" NDATA sgml>
<!ENTITY REFMAN9F PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0639//EN" "" NDATA sgml>
<!ENTITY REFMAN9S PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0640//EN" "" NDATA sgml>
<!ENTITY redzone.fig4 SYSTEM "figures/redzone.fig4.epsi.gif" NDATA gif>
<!ENTITY redzone.fig1 SYSTEM "figures/redzone.fig1.epsi.gif" NDATA gif>
<!ENTITY redzone.fig2 SYSTEM "figures/redzone.fig2.epsi.gif" NDATA gif>
<!ENTITY redzone.fig3 SYSTEM "figures/redzone.fig3.epsi.gif" NDATA gif>
<!ENTITY redzone.fig5 SYSTEM "figures/redzone.fig5.epsi.gif" NDATA gif>
<!ENTITY proc-t SYSTEM "figures/proc-t.epsi.gif" NDATA gif>
<!ENTITY LLM PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0641//EN" "" NDATA sgml>
<!ENTITY SOL64TRANS PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0477//EN" "" NDATA sgml>
<!ENTITY STREAMS PUBLIC "-//Sun::SunSoft//DOCUMENT 805-7478//EN" "" NDATA sgml>
<!ENTITY REFMAN1M PUBLIC "-//Sun::SunSoft//DOCUMENT 806-0625//EN" "" NDATA sgml>
]>
<book fpi="-//Sun::SunSoft//DOCUMENT MODDEBUG Version 3.0//en" role="unnumbered" lang="en" userlevel="developer"><title>Solaris Modular Debugger Guide</title><bookinfo><bookbiblio><title>Solaris Modular Debugger Guide</title><authorgroup><author><firstname>Don</firstname><surname>Kawashima</surname></author></authorgroup><isbn></isbn><pubsnumber><gentext type="text">Part No: </gentext>806-6545-11</pubsnumber><releaseinfo></releaseinfo><pubdate>October 2003</pubdate><publisher><publishername>Sun Microsystems, Inc.</publishername><address><street>4150 Network Circle</street><city>Santa Clara<gentext type="text">, </gentext></city><state>CA<gentext type="text"></gentext></state><postcode>95054</postcode><country>U.S.A.</country></address></publisher><copyright><year>2003</year><holder>   Sun Microsystems</holder></copyright><abstract><para> This book describes the Solaris Modular Debugger (MDB),
which is a new general purpose debugging tool for the Solaris operating environment.
The primary feature of MDB is its extensibility.  This book describes how
to use MDB to debug complex software systems, with a particular emphasis on
the facilities available for debugging the Solaris kernel and associated device
drivers and modules.  The book also includes a complete reference for and
discussion of the MDB language syntax, debugger features, and MDB Module Programming
API.</para></abstract></bookbiblio><legalnotice><para>This product or document is protected by copyright and distributed under licenses restricting its use, copying, distribution, and decompilation. No part of this product or document may be reproduced in any form by any means without prior written authorization of Sun and its licensors, if any. Third-party software, including font technology, is copyrighted and licensed from Sun suppliers.</para><para>Parts of the product may be derived from Berkeley BSD systems, licensed from the University of California. UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open Company, Ltd.</para><para>Sun, Sun Microsystems, the Sun logo, docs.sun.com, AnswerBook, AnswerBook2, 
 and Solaris are trademarks, registered trademarks, or service marks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the U.S. and other countries. Products bearing SPARC trademarks are based upon an architecture developed by Sun Microsystems, Inc. </para><para>The OPEN LOOK and <trademark>Sun</trademark> Graphical User Interface was developed by Sun Microsystems, Inc. for its users and licensees. Sun acknowledges the pioneering efforts of Xerox in researching and developing the concept of visual or graphical user interfaces for the computer industry. Sun holds a non-exclusive license from Xerox to the Xerox Graphical User Interface, which license also covers Sun's licensees who implement OPEN LOOK GUIs and otherwise comply with Sun's written license agreements.</para><para>Federal Acquisitions: Commercial Software–Government Users Subject to Standard License Terms and Conditions.</para><para>DOCUMENTATION IS PROVIDED “AS IS” AND ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.</para><para lang="fr"></para><para>Ce produit ou document est protégé par un copyright et distribué avec des licences qui en restreignent l'utilisation, la copie, la distribution, et la décompilation. Aucune partie de ce produit ou document ne peut être reproduite sous aucune forme, par quelque moyen que ce soit, sans l'autorisation préalable et écrite de Sun et de ses bailleurs de licence, s'il y en a. Le logiciel détenu par des tiers, et qui comprend la technologie relative aux polices de caractères, est protégé par un copyright et licencié par des fournisseurs de Sun.</para><para>Des parties de ce produit pourront être dérivées du système Berkeley BSD licenciés par l'Université de Californie. UNIX est une marque déposée aux Etats-Unis et dans d'autres pays et licenciée exclusivement par X/Open Company, Ltd. </para><para>Sun, Sun Microsystems, le logo Sun, docs.sun.com, AnswerBook, AnswerBook2, 
 et Solaris sont des marques de fabrique ou des marques déposées, ou marques de service, de Sun Microsystems, Inc. aux Etats-Unis et dans d'autres pays. Toutes les marques SPARC sont utilisées sous licence et sont des marques de fabrique ou des marques déposées de SPARC International, Inc. aux Etats-Unis et dans d'autres pays. Les produits portant les marques SPARC sont basés sur une architecture développée par Sun Microsystems, Inc.</para><para>L'interface d'utilisation graphique OPEN LOOK et <trademark>Sun</trademark> a été développée par Sun Microsystems, Inc. pour ses utilisateurs et licenciés. Sun reconnaît les efforts de pionniers de Xerox pour la recherche et le développement du concept des interfaces d'utilisation visuelle ou graphique pour l'industrie de l'informatique. Sun détient une licence non exclusive de Xerox sur l'interface d'utilisation graphique Xerox, cette licence couvrant également les licenciés de Sun qui mettent en place l'interface d'utilisation graphique OPEN LOOK et qui en outre se conforment aux licences écrites de Sun.</para><para>CETTE PUBLICATION EST FOURNIE “EN L'ETAT” ET AUCUNE GARANTIE, EXPRESSE OU IMPLICITE, N'EST ACCORDEE, Y COMPRIS DES GARANTIES CONCERNANT LA VALEUR MARCHANDE, L'APTITUDE DE LA PUBLICATION A REPONDRE A UNE UTILISATION PARTICULIERE, OU LE FAIT QU'ELLE NE SOIT PAS CONTREFAISANTE DE PRODUIT DE TIERS. CE DENI DE GARANTIE NE S'APPLIQUERAIT PAS, DANS LA MESURE OU IL SERAIT TENU JURIDIQUEMENT NUL ET NON AVENU.</para></legalnotice><subjectset><subject><subjectterm>Driver Development</subjectterm><subjectterm>Other Reference</subjectterm><subjectterm>Programming &amp; Tools</subjectterm><subjectterm>Troubleshooting</subjectterm></subject></subjectset></bookinfo><preface id="preface-1"><gentext type="text">Preface</gentext><gentext type="toc">Preface</gentext><title>Preface</title><highlights><para>The Modular Debugger (MDB) is a new general purpose debugging
tool for the <trademark>Solaris</trademark> Operating Environment. Its primary
feature is its extensibility. The <citetitle>Solaris Modular Debugger Guide</citetitle> describes how to use MDB to debug complex software systems, with
a particular emphasis on the facilities available for debugging the Solaris
kernel and associated device drivers and modules.  It also includes a complete
reference for and discussion of the MDB language syntax, debugger features,
and MDB Module Programming API. </para></highlights><sect1 id="preface-9"><title id="preface-2">Who Should Use This Book</title><para>If you were a detective and were investigating at the scene of a crime,
you might interview the witnesses and ask them to describe what happened and
who they saw.  However, if there were no witnesses or these descriptions proved
insufficient, you might consider collecting fingerprints and forensic evidence
that could be examined for DNA to help solve the case. Often, software program
failures divide into analogous categories: problems that can be solved with
source-level debugging tools, and problems that require low-level debugging
facilities, examination of core files, and knowledge of assembly language
to diagnose and correct.  MDB is a debugger designed to facilitate analysis
of this second class of problems.</para><para>It might not be necessary to use MDB in every case, just as a detective
doesn't need a microscope and DNA evidence to solve every crime. However,
when programming a complex low-level software system such as an operating
system, these situations can occur frequently.  As a result, MDB is designed
as a debugging framework that allows you to construct your own custom analysis
tools to aid in the diagnosis of these problems.  MDB also provides a powerful
set of built-in commands that allow you to analyze the state of your program
at the assembly language level.</para><para>If you are not familiar with assembly language programming and debugging, <link linkend="preface-5">Related Books and Papers</link> provides references to materials that you might find
useful.  </para><para>You should also disassemble various functions of interest in the programs
you will be debugging in order to familiarize yourself with the relationship
between your program's source code and the corresponding assembly language
code.  If you are planning to use MDB for debugging Solaris kernel software,
you should read carefully <link linkend="modules-1">Chapter 7, Kernel Debugging Modules</link> and <link linkend="kmem-1">Chapter 8, Debugging With the Kernel Memory Allocator</link>.
 These chapters provide more detailed information on the MDB commands and
facilities provided for debugging Solaris kernel software.</para></sect1><sect1 id="preface-4"><title>How This Book Is Organized</title><para><link linkend="intro-1">Chapter 1, Modular Debugger Overview</link> provides an overview of the debugger. This
chapter is intended for all users.</para><para><link linkend="concepts-1">Chapter 2, Debugger Concepts</link> describes the MDB architecture and explains
the terminology for the debugger concepts used throughout this book.  This
chapter is intended for all users.</para><para><link linkend="syntax-7">Chapter 3, Language Syntax</link> describes the syntax, operators and evaluation
rules for the MDB language.  This chapter is intended for all users.</para><para><link linkend="interaction-3">Chapter 4, Interaction</link> describes the MDB interactive command-line
editing facilities and output pager.  This chapter is intended for all users.</para><para><link linkend="commands-1">Chapter 5, Built-in Commands</link> describes the set of built-in debugger commands
that are always available.  This chapter is intended for all users.</para><para><link linkend="exec-ctrl-7">Chapter 6, Execution Control</link> describes the MDB facilities for controlling
the execution of live running user processes. This chapter is intended for
user    application programmers and system administrators.</para><para><link linkend="modules-1">Chapter 7, Kernel Debugging Modules</link> describes the set of loadable debugger commands
that are provided for debugging the Solaris kernel.  This chapter is intended
for users who intend to examine Solaris kernel crash dumps and for kernel
software developers.</para><para><link linkend="kmem-1">Chapter 8, Debugging With the Kernel Memory Allocator</link> describes the debugging features of the Solaris
kernel memory allocator and the MDB commands provided to take advantage of
these features.  This chapter is intended for advanced programmers and kernel
software developers.</para><para><link linkend="api-5">Chapter 9, Module Programming API</link> describes the facilities for writing loadable
debugger modules.  This chapter is intended for advanced programmers and software
developers who intend to develop custom debugging support for MDB.</para><para><link linkend="options-1">Appendix A, Options</link> provides a reference for MDB command-line
options.</para><para><link linkend="notes-1">Appendix B, Notes</link> provides warnings and notes about using the
debugger.</para><para><link linkend="adb-trans-1">Appendix C, Transition From <command>adb</command></link> provides a reference for <literal>adb(1M)</literal> commands and their MDB equivalents.</para><para><link linkend="crash-4">Appendix D, Transition From <command>crash</command></link> provides a reference for <literal>crash(1M)</literal> commands and their MDB equivalents.</para></sect1><sect1 id="preface-5"><title>Related Books and Papers</title><para>These books and papers are recommended and related to the tasks that
you need to perform:</para><para><itemizedlist><listitem><para>Vahalia, Uresh. <citetitle>UNIX Internals: The New Frontiers</citetitle>. Prentice Hall, 1996. ISBN 0-13-101908-2</para></listitem><listitem><para>Mauro, Jim and McDougall, Richard. <citetitle>Solaris Internals:
Core Kernel Components</citetitle>. Sun Microsystems Press, 2001. ISBN 0-13-022496-0</para></listitem><listitem><para><citetitle>The SPARC Architecture Manual, Version 9</citetitle>.
Prentice Hall, 1998. ISBN 0–13–099227–5</para></listitem><listitem><para><citetitle>The SPARC Architecture Manual, Version 8</citetitle>.
Prentice Hall, 1994.  ISBN 0-13-825001-4</para></listitem><listitem><para><citetitle>Pentium Pro Family Developer's Manual, Volumes
1-3</citetitle>. Intel Corporation, 1996. ISBN 1-55512-259-0 (Volume 1) ,
ISBN 1-55512-260-4 (Volume 2) , ISBN 1-55512-261-2 (Volume 3) </para></listitem><listitem><para>Bonwick, Jeff. <citetitle>The Slab Allocator: An Object-Caching
Kernel Memory Allocator</citetitle>. Proceedings of the Summer 1994 Usenix
Conference, 1994. ISBN 9–99–452010–5</para></listitem><listitem><para><citetitle>SPARC Assembly Language Reference Manual</citetitle>.
Sun Microsystems, 1998.</para></listitem><listitem><para><citetitle>x86 Assembly Language Reference Manual</citetitle>.
Sun Microsystems, 1998.</para></listitem><listitem><para><olink targetdocent="DRIVER" type="v-only"><citetitle>Writing
Device Drivers</citetitle></olink>. Sun Microsystems, 2000.</para></listitem><listitem><para><olink targetdocent="STREAMS" type="v-only"><citetitle>STREAMS
Programming Guide</citetitle></olink>. Sun Microsystems, 2000.</para></listitem><listitem><para><olink targetdocent="SOL64TRANS" type="v-only"><citetitle>Solaris 64-bit Developer's Guide</citetitle></olink>. Sun Microsystems, 2000.</para></listitem><listitem><para><olink targetdocent="LLM" type="v-only"><citetitle>Linker
and Libraries Guide</citetitle></olink>. Sun Microsystems, 2000.</para></listitem></itemizedlist></para><note><gentext type="text">Note &#8211; </gentext><para>In this document, the term “IA” refers to the Intel
32–bit processor architecture, which includes the Pentium, Pentium Pro,
Pentium II, Pentium II Xeon, Celeron, Pentium III, and Pentium III Xeon processors,
and compatible microprocessor chips made by AMD and Cyrix.</para></note><note><gentext type="text">Note &#8211; </gentext><para>The Solaris operating environment runs on two types of hardware,
or platforms—<trademark>SPARC</trademark> and IA. The Solaris operating
environment also runs on both 64–bit and 32–bit address spaces.
The information in this document pertains to both platforms and address spaces
unless called out in a special chapter, section, note, bullet, figure, table,
example, or code example.</para></note></sect1><sect1 id="preface-7"><title>Accessing Sun Documentation Online</title><para>The <trademark class="service">docs.sun.com</trademark> Web site enables
you to access Sun technical documentation online. You can browse the docs.sun.com
archive or search for a specific book title or subject. The URL is <ulink url="http://docs.sun.com"><literal>http://docs.sun.com</literal></ulink>.</para></sect1><sect1 id="preface-10"><title>What Typographic Conventions Mean</title><para>The following table describes the typographic changes used in this book.</para><table frame="all" id="preface-tbl-11"><gentext type="text">Table P&#8211;1 </gentext><title>Typographic Conventions</title><tgroup cols="3" colsep="1" rowsep="1"><colspec colwidth="80*"/><colspec colwidth="179*"/><colspec colwidth="137*"/><thead><row><entry align="left" valign="top"><para>Typeface or Symbol</para></entry><entry align="left" valign="bottom"><para>Meaning</para></entry><entry align="left" valign="bottom"><para>Example</para></entry></row></thead><tbody><row><entry align="left" valign="top"><para><literal>AaBbCc123</literal></para></entry><entry align="left" valign="top">The names of commands, files, and directories; on-screen computer output</entry><entry align="left" valign="top"><para>Edit your <filename>.login</filename> file. </para><para>Use <command>ls <option><gentext type="text">-</gentext>a</option> </command>to
list all files. </para><para><computeroutput>machine_name% you have mail.</computeroutput></para></entry></row><row><entry align="left" valign="top"><para><userinput>AaBbCc123</userinput></para></entry><entry align="left" valign="top">What you type, contrasted with on-screen computer output</entry><entry align="left" valign="top"><computeroutput>machine_name%</computeroutput> <userinput>su</userinput>
<computeroutput>Password:</computeroutput></entry></row><row><entry align="left" valign="top"><para><replaceable>AaBbCc123</replaceable></para></entry><entry align="left" valign="top">Command-line placeholder: replace with a real name or value</entry><entry align="left" valign="top"><para>To delete a file, type <userinput>rm</userinput> <replaceable>filename</replaceable>.</para></entry></row><row><entry align="left" valign="top"><para><emphasis>AaBbCc123</emphasis></para></entry><entry align="left" valign="top"><para>Book titles, new words, or terms, or
words to be emphasized.</para></entry><entry align="left" valign="top"><para>Read Chapter 6 in <citetitle>User's Guide</citetitle>. </para><para>These
are called <firstterm>class</firstterm> options. </para><para>You must be <emphasis>root</emphasis> to do this.</para></entry></row></tbody></tgroup></table></sect1><sect1 id="preface-12"><title>Shell Prompts in Command Examples</title><para>The following table shows the default system prompt and superuser prompt
for the C shell, Bourne shell, and Korn shell, as well as the MDB debugger
prompt.</para><table frame="all" id="preface-tbl-13"><gentext type="text">Table P&#8211;2 </gentext><title>Shell Prompts</title><tgroup cols="2" colsep="1" rowsep="1"><colspec colwidth="198*"/><colspec colwidth="198*"/><thead><row><entry align="left" valign="top"><para>Shell</para></entry><entry align="left" valign="top"><para>Prompt</para></entry></row></thead><tbody><row><entry align="left" valign="top">C shell prompt</entry><entry align="left" valign="top"><computeroutput>machine_name%</computeroutput></entry></row><row><entry align="left" valign="top">C shell superuser prompt</entry><entry align="left" valign="top"><computeroutput>machine_name#</computeroutput></entry></row><row><entry align="left" valign="top">Bourne shell and Korn shell prompt</entry><entry align="left" valign="top"><computeroutput>$</computeroutput></entry></row><row><entry align="left" valign="top">Bourne shell and Korn
shell superuser prompt</entry><entry align="left" valign="top"><computeroutput>#</computeroutput></entry></row><row><entry align="left" valign="top">MDB prompt</entry><entry align="left" valign="top"><computeroutput>&gt;</computeroutput></entry></row></tbody></tgroup></table></sect1></preface><chapter id="intro-1"><gentext type="text">Chapter 1</gentext><gentext type="toc">1.&#160;&#160;Modular Debugger Overview</gentext><title>Modular Debugger Overview</title><highlights><para>The Modular Debugger (MDB) is a general purpose
debugging tool for Solaris whose primary feature is its extensibility.  This
book describes how to use MDB to debug complex software systems, with a particular
emphasis on the facilities available for debugging the Solaris kernel and
associated device drivers and modules.  The book also includes a complete
reference for and discussion of the MDB language syntax, debugger features,
and MDB Module Programming API. </para></highlights><sect1 id="chapter-2"><title>Introduction</title><para>Debugging is the process of analyzing the execution and state of a software
program in order to remove defects.  Traditional debugging tools provide facilities
for execution control so that programmers can re-execute programs in a controlled
environment and display the current state of program data or evaluate expressions
in the source language used to develop the program. Unfortunately, these techniques
are often inappropriate for debugging complex software systems such as:<itemizedlist><listitem><para>An operating system, where bugs might not be reproducible
and program state is massive and distributed</para></listitem><listitem><para>Programs that are highly optimized or have had their debug
information removed</para></listitem><listitem><para>Programs that are themselves low-level debugging tools</para></listitem><listitem><para>Customer situations where the developer can only access post-mortem
information</para></listitem></itemizedlist></para><para>MDB is a tool that provides a completely customizable environment for
debugging these programs and scenarios, including a dynamic module facility
that programmers can use to implement their own debugging commands to perform
program-specific analysis. Each MDB module can be used to examine the program
in several different contexts, including live and post-mortem. The Solaris
Operating Environment includes a set of MDB modules designed to aid programmers
in debugging the Solaris kernel and related device drivers and kernel modules.
Third-party developers might find it useful to develop and deliver their own
debugging modules for supervisor or user software. </para></sect1><sect1 id="chapter-8"><title>MDB Features</title><para>MDB provides an extensive collection of features for analyzing the Solaris
kernel and other target programs. You can:</para><itemizedlist><listitem><para>Perform post-mortem analysis of Solaris kernel crash dumps
and user process core dumps:  MDB includes a collection of debugger modules
that facilitate sophisticated analysis of kernel and process state, in addition
to standard data display and formatting capabilities.  The debugger modules
allow you to formulate complex queries to:<itemizedlist><listitem><para>Locate all the memory allocated by a particular thread</para></listitem><listitem><para>Print a visual picture of a kernel STREAM</para></listitem><listitem><para>Determine what type of structure a particular address refers
to </para></listitem><listitem><para>Locate leaked memory blocks in the kernel</para></listitem><listitem><para>Analyze memory to locate stack traces</para></listitem></itemizedlist></para></listitem><listitem><para>Use a first-class programming API to implement your own debugger
commands and analysis tools without having to recompile or modify the debugger
itself: In MDB, debugging support is implemented as a set of loadable modules
(shared libraries that the debugger can <olink targetdocent="REFMAN3A" localinfo="DLOPEN-3DL" type="v-only"><citerefentry><refentrytitle>dlopen</refentrytitle><manvolnum><gentext type="text">(</gentext>3DL<gentext type="text">)</gentext></manvolnum></citerefentry></olink>), each of which provides a set of commands
that extends the capabilities of the debugger itself. The debugger in turn
provides an API of core services, such as the ability to read and write memory
and access symbol table information. MDB provides a framework for developers
to implement debugging support for their own drivers and modules; these modules
can then be made available for everyone to use. </para></listitem><listitem><para>Learn to use MDB if you are already familiar with the legacy
debugging tools <literal>adb(1)</literal> and <literal>crash(1M)</literal>:
 MDB provides backward compatibility with these existing debugging solutions.
The MDB language itself is designed as a superset of the adb language; all
existing adb macros and commands work within MDB so developers who use adb
can immediately use MDB without knowing any MDB-specific commands.  MDB also
provides commands that surpass the functionality available from the crash
utility.</para></listitem><listitem><para>Benefit from enhanced usability features.  MDB provides a
host of usability features, including: <itemizedlist><listitem><para>Command-line editing</para></listitem><listitem><para>Command history</para></listitem><listitem><para>Built-in output pager</para></listitem><listitem><para>Syntax error checking and handling</para></listitem><listitem><para>Online help</para></listitem><listitem><para>Interactive session logging</para></listitem></itemizedlist></para></listitem></itemizedlist></sect1><sect1 id="chapter-26"><title>Future Enhancements</title><para>MDB provides a stable foundation for developing advanced post-mortem
analysis tools. In the future, the Solaris operating environment will include
additional MDB modules that provide even more sophisticated functionality
for debugging the kernel and other software programs. You can use MDB to debug
existing software programs, and develop your own modules to improve your ability
to debug your own Solaris drivers and applications. </para></sect1></chapter><chapter id="concepts-1"><gentext type="text">Chapter 2</gentext><gentext type="toc">2.&#160;&#160;Debugger Concepts</gentext><title>Debugger Concepts</title><highlights><para>This section discusses the significant aspects of MDB's
design, and the benefits derived from this architecture.</para></highlights><sect1 id="chapter-9"><title>Architecture</title><figure id="chapter-fig-10"><gentext type="text">Figure 2&#8211;1 </gentext><title>MDB architecture</title><graphic entityref="mdb-arch" width="444" depth="323"><![CDATA[The MDB architecture is represented as a series of layers. The user and adb macros use the MDB language. The unix and nfs modules use the MDB module API. The debugger engine uses the disassembler, the llbkvm target, and the /proc target.]]></graphic></figure></sect1><sect1 id="chapter-11"><title>Building Blocks</title><para>The <emphasis role="strong">target</emphasis> is the program being inspected
by the debugger.  MDB currently provides support for the following types of
targets: <itemizedlist><listitem><para>User processes</para></listitem><listitem><para>User process core files</para></listitem><listitem><para>Live operating system (through <literal>/dev/kmem</literal>
and <literal>/dev/ksyms</literal>)</para></listitem><listitem><para>Operating system crash dumps</para></listitem><listitem><para>User process images recorded inside an operating system crash
dump</para></listitem><listitem><para>ELF object files</para></listitem><listitem><para>Raw data files</para></listitem></itemizedlist></para><para>Each target exports a standard set of properties, including one or more
address spaces, one or more symbol tables, a set of load objects, and a set
of threads. <link linkend="chapter-fig-10">Figure 2–1</link> shows an overview of the MDB architecture,
including two of the built-in targets and a pair of sample modules.</para><para>A debugger command, or <emphasis role="strong">dcmd</emphasis> (pronounced <emphasis>dee-command</emphasis>) in MDB terminology, is a routine in the debugger that
can access any of the properties of the current target.  MDB parses commands
from standard input, then executes the corresponding dcmds.  Each dcmd can
also accept a list of string or numerical arguments, as shown in <link linkend="syntax-17">Syntax</link>.
MDB contains a set of built-in dcmds described in <link linkend="commands-1">Chapter 5, Built-in Commands</link>,
that are always available.  The programmer can also extend the capabilities
of MDB itself by writing dcmds using a programming API provided with MDB.<indexterm id="indexterm-1"><primary>dcmd</primary><secondary>definition</secondary></indexterm></para><para>A <emphasis role="strong">walker</emphasis> is a set of routines that
describe how to walk, or iterate, through the elements of a particular program
data structure.  A walker encapsulates the data structure's implementation
from dcmds and from MDB itself.  You can use walkers interactively, or use
them as a primitive to build other dcmds or walkers.  As with dcmds, the programmer
can extend MDB by implementing additional walkers as part of a debugger module.<indexterm id="indexterm-2"><primary>walker</primary><secondary>definition</secondary></indexterm></para><para>A debugger module, or <emphasis role="strong">dmod</emphasis> (pronounced <emphasis>dee-mod</emphasis>), is a dynamically loaded library containing a set of dcmds
and walkers.  During initialization, MDB attempts to load dmods corresponding
to the load objects present in the target.  You can subsequently load or unload
dmods at any time while running MDB.  MDB provides a set of standard dmods
for debugging the Solaris kernel.<indexterm id="indexterm-3"><primary>dmod</primary><secondary>definition</secondary></indexterm></para><para>A <emphasis role="strong">macro file</emphasis> is a text file containing
a set of commands to execute. Macro files are typically used to automate the
process of displaying a simple data structure.  MDB provides complete backward
compatibility for the execution of macro files written for adb.   The set
of macro files provided with the Solaris installation can therefore be used
with either tool.<indexterm id="indexterm-4"><primary>macro file</primary><secondary>definition</secondary></indexterm></para></sect1><sect1 id="concepts-10"><title>Modularity</title><para>The benefit of MDB's modular architecture extends beyond the ability
to load a shared library containing additional debugger commands. The MDB
architecture defines clear interface boundaries between each of the layers
shown in <link linkend="chapter-fig-10">Figure 2–1</link>. Macro files execute commands written
in the MDB or adb language. Dcmds and walkers in debugger modules are written
using the MDB Module API, and this forms the basis of an application binary
interface that allows the debugger and its modules to evolve independently. </para><para>The MDB name space of walkers and dcmds also defines a second set of
layers between debugging code that maximizes code sharing and limits the amount
of code that must be modified as the target program itself evolves. For example,
one of the primary data structures in the Solaris kernel is the list of <literal>proc_t</literal> structures representing active processes in the system. The <command>::ps</command> dcmd must iterate over this list in order to produce its output.
However, the code to iterate over the list is not in the <command>::ps</command>
dcmd, it is encapsulated in the <literal>genunix</literal> module's <literal>proc</literal> walker. </para><para>MDB provides both <command>::ps</command> and <command>::ptree</command>
dcmds, but neither has any knowledge of how <literal>proc_t</literal> structures
are accessed in the kernel. Instead, they invoke the <literal>proc</literal>
walker programmatically and format the set of returned structures appropriately.
If the data structure used for <literal>proc_t</literal> structures ever changed,
MDB could provide a new <literal>proc</literal> walker and none of the dependent
dcmds would need to change.  The <literal>proc</literal> walker can also be
accessed interactively using the <command>::walk</command> dcmd in order to
create novel commands as you work during a debugging session. </para><para>In addition to facilitating layering and code sharing, the MDB Module
API provides dcmds and walkers with a single stable interface for accessing
various properties of the underlying target. The same API functions are used
to access information from user process or kernel targets, simplifying the
task of developing new debugging facilities. </para><para>In addition, a custom MDB module can be used to perform debugging tasks
in a variety of contexts. For example, you might want to develop an MDB module
for a user program you are developing. Once you have done so, you can use
this module when MDB examines a live process executing your program, a core
dump of your program, or even a kernel crash dump taken on a system where
your program was executing. </para><para>The Module API provides facilities for accessing the following target
properties: </para><variablelist termlength="medium"><varlistentry><term>Address Spaces</term><listitem><para>The module API provides
facilities for reading and writing data from the target's virtual address
space.  Functions for reading and writing using physical addresses are also
provided for kernel debugging modules. </para></listitem></varlistentry><varlistentry><term>Symbol Tables</term><listitem><para>The module API provides
access to the static and dynamic symbol tables of the target's primary executable
file, its runtime link-editor, and a set of load objects (shared libraries
in a user process or loadable modules in the Solaris kernel).</para></listitem></varlistentry><varlistentry><term>External Data</term><listitem><para>The module API provides
a facility for retrieving a collection of named external data buffers associated
with the target.  For example, MDB provides programmatic access to the <literal>proc(4)</literal> structures associated with a user process or user core file
target.</para></listitem></varlistentry></variablelist><para>In addition, you can use built-in MDB dcmds to access
information about target memory mappings, load objects, register values, and
control the execution of user process targets.</para></sect1></chapter><chapter id="syntax-7"><gentext type="text">Chapter 3</gentext><gentext type="toc">3.&#160;&#160;Language Syntax</gentext><title>Language Syntax</title><highlights><para>This chapter describes the MDB language syntax, operators,
and rules for command and symbol name resolution.</para></highlights><sect1 id="syntax-17"><title>Syntax</title><para>The debugger processes commands from standard input. If standard input
is a terminal, MDB provides terminal editing capabilities. MDB can also process
commands from macro files and from dcmd pipelines, described below. The language
syntax is designed around the concept of computing the value of an expression
(typically a memory address in the target), and applying a dcmd to that address.
The current address location is referred to as <replaceable>dot</replaceable>,
and “.” is used to reference its value.</para><indexterm id="indexterm-5"><primary>Syntax</primary><secondary>dot</secondary></indexterm><para>A <replaceable>metacharacter</replaceable> is one of the following characters:</para><indexterm id="indexterm-6"><primary>Syntax</primary><secondary>metacharacter</secondary></indexterm><para><literal>[   ]   |   !   /   \   ?   =   &gt;   $   :   ;   </literal><symbol>NEWLINE   SPACE   TAB</symbol></para><para>A <replaceable>blank</replaceable> is a <symbol>TAB</symbol> or a <symbol>SPACE</symbol>. A <replaceable>word</replaceable> is a sequence of characters
separated by one or more non-quoted metacharacters. Some of the metacharacters
function only as delimiters in certain contexts, as described below. An <replaceable>identifier</replaceable> is a sequence of letters, digits, underscores, periods,
or back quotes beginning with a letter, underscore, or period. Identifiers
are used as the names of symbols, variables, dcmds, and walkers. Commands
are delimited by a <symbol>NEWLINE</symbol> or semicolon ( <literal>;</literal>
).</para><indexterm id="indexterm-7"><primary>Syntax</primary><secondary>blank</secondary></indexterm><indexterm id="indexterm-8"><primary>Syntax</primary><secondary>word</secondary></indexterm><indexterm id="indexterm-9"><primary>Syntax</primary><secondary>identifier</secondary></indexterm><para>A dcmd is denoted by one of the following words or metacharacters:</para><para><literal>/   \   ?   =   &gt;   $character   :character  ::identifier</literal></para><para>dcmds named by metacharacters or prefixed by a single <literal>$</literal>
or <literal>:</literal> are provided as built-in operators, and implement
complete compatibility with the command set of the legacy <olink targetdocent="REFMAN1" localinfo="ADB-1" type="v-only"><citerefentry><refentrytitle>adb</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink> utility. After a dcmd has
been parsed, the <literal>/</literal>, <literal>\</literal>, <literal>?</literal>, <literal>=</literal>, <literal>&gt;</literal>, <literal>$</literal>, and <literal>:</literal>
characters are no longer recognized as metacharacters until the termination
of the argument list.</para><para>A <replaceable>simple-command</replaceable> is a dcmd followed by a
sequence of zero or more blank-separated words. The words are passed as arguments
to the invoked dcmd, except as specified under <link linkend="syntax-1">Arithmetic Expansion</link> and <link linkend="syntax-2">Quoting</link>. Each dcmd returns an exit status that indicates it was
either successful, failed, or was invoked with invalid arguments.</para><indexterm id="indexterm-10"><primary>Syntax</primary><secondary>simple-command</secondary></indexterm><para>A <replaceable>pipeline</replaceable> is a sequence of one
or more simple commands separated by <literal>|.</literal> Unlike the shell,
dcmds in MDB pipelines are not executed as separate processes. After the pipeline
has been parsed, each dcmd is invoked in order from left to right. Each dcmd's
output is processed and stored as described in <link linkend="syntax-14">dcmd Pipelines</link>.
After the left-hand dcmd is complete, its processed output is used as input
for the next dcmd in the pipeline. If any dcmd does not return a successful
exit status, the pipeline is aborted.</para><indexterm id="indexterm-11"><primary>Syntax</primary><secondary>pipeline</secondary></indexterm><para>An <replaceable>expression</replaceable> is a sequence of words that
is evaluated to compute a 64-bit unsigned integer value. The words are evaluated
using the rules described in <link linkend="syntax-1">Arithmetic Expansion</link>.</para><indexterm id="indexterm-12"><primary>Syntax</primary><secondary>expression</secondary></indexterm></sect1><sect1 id="syntax-11"><title>Commands</title><para>A <replaceable>command</replaceable> is one of the following:</para><indexterm id="indexterm-13"><primary>Commands</primary></indexterm><indexterm id="indexterm-14"><primary>Syntax</primary><secondary>command</secondary></indexterm><variablelist termlength="wholeline"><varlistentry><term>pipeline [ ! word ... ] [ ; ]</term><listitem><para>A
simple-command or pipeline can be optionally suffixed with the <literal>!</literal> character, indicating that the debugger should open a <olink targetdocent="REFMAN2" localinfo="PIPE-2"><citerefentry><refentrytitle>pipe</refentrytitle><manvolnum><gentext type="text">(</gentext>2<gentext type="text">)</gentext></manvolnum></citerefentry></olink> and send the standard output of the last
dcmd in the MDB pipeline to an external process created by executing <command>$SHELL</command> <option><gentext type="text">-</gentext>c</option> followed by the string formed by concatenating
the words after the <literal>!</literal> character. For more details, refer
to <link linkend="syntax-3">Shell Escapes</link>.</para></listitem></varlistentry><varlistentry><term>expression pipeline [ ! word ... ] [ ; ]</term><listitem><para>A simple-command or pipeline can be prefixed with an expression. Before
execution of the pipeline, the value of dot (the variable denoted by “<literal>.</literal>”) is set to the value of the expression.</para></listitem></varlistentry><varlistentry><term>expression , expression pipeline [ ! word ... ] [ ; ]</term><listitem><para>A simple-command or pipeline can be prefixed with two
expressions. The first is evaluated to determine the new value of dot, and
the second is evaluated to determine a repeat count for the first dcmd in
the pipeline. This dcmd will be executed <replaceable>count</replaceable>
times before the next dcmd in the pipeline is executed. The repeat count applies
only to the first dcmd in the pipeline.</para></listitem></varlistentry><varlistentry><term>, expression pipeline [ ! word ... ] [ ; ]</term><listitem><para>If the initial expression is omitted, dot is not modified; however,
the first dcmd in the pipeline will be repeated according to the value of
the expression.</para></listitem></varlistentry><varlistentry><term>expression [ ! word ... ] [ ; ]</term><listitem><para>A command can consist only of an arithmetic expression. The expression is
evaluated and the dot variable is set to its value, then the previous dcmd
and arguments are executed using the new value of dot.</para></listitem></varlistentry><varlistentry><term>expression , expression [ ! word ... ] [ ; ]</term><listitem><para>A command can consist only of a dot expression and repeat count expression.
After dot is set to the value of the first expression, the previous dcmd and
arguments are repeatedly executed the number of times specified by the value
of the second expression.</para></listitem></varlistentry><varlistentry><term>, expression [ ! word ... ] [ ; ]</term><listitem><para>If the initial expression is omitted, dot is not modified but the previous
dcmd and arguments are repeatedly executed the number of times specified by
the  value of the count expression.</para></listitem></varlistentry><varlistentry><term>! word ... [ ; ]</term><listitem><para>If the command
begins with the <literal>!</literal> character, no dcmds are executed and
the debugger executes <command>$SHELL</command> <option><gentext type="text">-</gentext>c</option> followed
by the string formed by concatenating the words after the <literal>!</literal>
character.</para></listitem></varlistentry></variablelist></sect1><sect1 id="syntax-5"><title>Comments</title><para>A word beginning with <literal>//</literal> causes that word and all
the subsequent characters up to a <symbol>NEWLINE</symbol> to be ignored.</para><indexterm id="indexterm-15"><primary>Comments</primary></indexterm><indexterm id="indexterm-16"><primary>Syntax</primary><secondary>Comments</secondary></indexterm><para></para></sect1><sect1 id="syntax-1"><title>Arithmetic Expansion</title><indexterm id="indexterm-17"><primary>Syntax</primary><secondary>Arithmetic Expansion</secondary></indexterm><indexterm id="indexterm-18"><primary>Arithmetic Expansion</primary></indexterm><para>Arithmetic expansion is performed when an MDB command is preceded by
an optional expression representing a start address, or a start address and
a repeat count. Arithmetic expansion can also be performed to compute a numerical
argument for a dcmd. An arithmetic expression can appear in an argument list
enclosed in square brackets preceded by a dollar sign (<literal>$[ expression
]</literal>), and will be replaced by the value of the expression.</para><para>Expressions can contain any of the following special words:</para><variablelist><varlistentry><term><replaceable>integer</replaceable></term><listitem><para>The specified integer value. Integer values can be prefixed with <literal>0i</literal> or <literal>0I</literal> to indicate binary values, <literal>0o</literal> or <literal>0O</literal> to indicate octal values, <literal>0t</literal> or <literal>0T</literal> to indicate decimal values, and <literal>0x</literal> or <literal>0X</literal> to indicate hexadecimal values (the
default).</para></listitem></varlistentry><varlistentry><term>0[tT][0-9]+.[0-9]+</term><listitem><para>The specified
decimal floating point value, converted to its <acronym>IEEE</acronym> double-precision
floating point representation</para></listitem></varlistentry><varlistentry><term>'<replaceable>cccccccc</replaceable>'</term><listitem><para>The integer value computed by converting each character to a byte equal
to its <acronym>ASCII</acronym> value. Up to eight characters can be specified
in a character constant. Characters are packed into the integer in reverse
order (right-to-left), beginning at the least significant byte.</para></listitem></varlistentry><varlistentry><term>&lt;<replaceable>identifier</replaceable></term><listitem><para>The value of the variable named by <replaceable>identifier</replaceable></para></listitem></varlistentry><varlistentry><term><replaceable>identifier</replaceable></term><listitem><para>The value of the symbol named by <replaceable>identifier</replaceable></para></listitem></varlistentry><varlistentry><term>(<replaceable>expression</replaceable>)</term><listitem><para>The value of <replaceable>expression</replaceable></para></listitem></varlistentry><varlistentry><term>.</term><listitem><para>The value of dot</para></listitem></varlistentry><varlistentry><term>&amp;</term><listitem><para>The most recent value of dot
used to execute a dcmd</para></listitem></varlistentry><varlistentry><term>+</term><listitem><para>The value of dot incremented by
the current increment</para></listitem></varlistentry><varlistentry><term>^</term><listitem><para>The value of dot decremented by
the current increment</para></listitem></varlistentry></variablelist><para>The increment is a global variable that stores the total
bytes read by the last formatting dcmd. For more information on the increment,
refer to the discussion of <link linkend="syntax-15">Formatting dcmds</link>.</para><sect2 id="syntax-18"><title>Unary Operators</title><para>Unary operators are right associative and have higher precedence than
binary operators. The unary operators are:</para><indexterm id="indexterm-19"><primary>Arithmetic Expansion</primary><secondary>Unary operators</secondary></indexterm><variablelist><varlistentry><term>#<replaceable>expression</replaceable></term><listitem><para>Logical negation</para></listitem></varlistentry><varlistentry><term>~<replaceable>expression</replaceable></term><listitem><para>Bitwise complement</para></listitem></varlistentry><varlistentry><term>-<replaceable>expression</replaceable></term><listitem><para>Integer negation</para></listitem></varlistentry><varlistentry><term>%<replaceable>expression</replaceable></term><listitem><para>Value of a pointer-sized quantity at the object file location corresponding
to virtual address <replaceable>expression</replaceable> in the target's virtual
address space</para></listitem></varlistentry><varlistentry><term>%/[csil]/<replaceable>expression</replaceable></term><listitem><para>Value of a char-, short-, int-, or long-sized quantity at
the object file location corresponding to virtual address <replaceable>expression</replaceable> in the target's virtual address space</para></listitem></varlistentry><varlistentry><term>%/[1248]/<replaceable>expression</replaceable></term><listitem><para>Value of a one-, two-, four-, or eight-byte quantity at the
object file location corresponding to virtual address <replaceable>expression</replaceable> in the target's virtual address space</para></listitem></varlistentry><varlistentry><term>*<replaceable>expression</replaceable></term><listitem><para>Value of a pointer-sized quantity at virtual address <replaceable>expression</replaceable> in the target's virtual address space</para></listitem></varlistentry><varlistentry><term>*/[csil]/<replaceable>expression</replaceable></term><listitem><para>Value of a char-, short-, int-, or long-sized quantity at
virtual address <replaceable>expression</replaceable> in the target's virtual
address space</para></listitem></varlistentry><varlistentry><term>*/[1248]/<replaceable>expression</replaceable></term><listitem><para>Value of a one-, two-, four-, or eight-byte quantity at virtual
address <replaceable>expression</replaceable> in the target's virtual address
space</para></listitem></varlistentry></variablelist></sect2><sect2 id="syntax-19"><title>Binary Operators</title><para>Binary operators are left associative and have lower precedence than
unary operators. The binary operators, in order of precedence from highest
to lowest, are:</para><indexterm id="indexterm-20"><primary>Arithmetic Expansion</primary><secondary>Binary operators</secondary></indexterm><variablelist><varlistentry><term><literal>*</literal></term><listitem><para>Integer multiplication</para></listitem></varlistentry><varlistentry><term><literal>%</literal></term><listitem><para>Integer division</para></listitem></varlistentry><varlistentry><term><literal>#</literal></term><listitem><para>Left-hand side
rounded up to next multiple of right-hand side</para></listitem></varlistentry><varlistentry><term><literal>+</literal></term><listitem><para>Integer addition</para></listitem></varlistentry><varlistentry><term><literal>-</literal></term><listitem><para>Integer subtraction</para></listitem></varlistentry><varlistentry><term><literal>&lt;&lt;</literal></term><listitem><para>Bitwise
shift left</para></listitem></varlistentry><varlistentry><term><literal>&gt;&gt;</literal></term><listitem><para>Bitwise shift
right</para></listitem></varlistentry><varlistentry><term><literal>==</literal></term><listitem><para>Logical equality</para></listitem></varlistentry><varlistentry><term><literal>!=</literal></term><listitem><para>Logical inequality</para></listitem></varlistentry><varlistentry><term><literal>&amp;</literal></term><listitem><para>Bitwise
AND</para></listitem></varlistentry><varlistentry><term><literal></literal>^</term><listitem><para>Bitwise exclusive
OR</para></listitem></varlistentry><varlistentry><term><literal>|</literal></term><listitem><para>Bitwise inclusive
OR</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="syntax-2"><title>Quoting</title><indexterm id="indexterm-21"><primary>Quoting</primary></indexterm><indexterm id="indexterm-22"><primary>Syntax</primary><secondary>Quoting</secondary></indexterm><para>Each metacharacter
described previously (see <link linkend="syntax-17">Syntax</link>) terminates a word unless
quoted. Characters can be quoted (forcing MDB to interpret each character
as itself without any special significance) by enclosing them in a pair of
single (<literal>'</literal>) or double (<literal>"</literal>) quotation marks.
A single quote cannot appear within single quotes. Inside double quotes, MDB
recognizes the C programming language character escape sequences.</para></sect1><sect1 id="syntax-3"><title>Shell Escapes</title><indexterm id="indexterm-23"><primary>Shell Escapes</primary></indexterm><indexterm id="indexterm-24"><primary>Syntax</primary><secondary>Shell Escapes</secondary></indexterm><para>The <literal>!</literal> character can be used to create a pipeline between an MDB command
and the user's shell. If the <envar>$SHELL</envar> environment variable is
set, MDB will <command>fork</command> and <command>exec</command> this program
for shell escapes; otherwise <command>/bin/sh</command> is used. The shell
is invoked with the <option><gentext type="text">-</gentext>c</option> option followed by a string formed
by concatenating the words after the <literal>!</literal> character. </para><para>The <literal>!</literal> character takes precedence over all other metacharacters,
except semicolon (<literal>;</literal>) and <symbol>NEWLINE</symbol>. After
a shell escape is detected, the remaining characters up to the next semicolon
or <symbol>NEWLINE</symbol> are passed “as is” to the shell. The
output of shell commands cannot be piped to MDB dcmds. Commands executed by
a shell escape have their output sent directly to the terminal, not to MDB.</para></sect1><sect1 id="syntax-4"><title>Variables</title><indexterm id="indexterm-25"><primary>Variables</primary></indexterm><indexterm id="indexterm-26"><primary>Syntax</primary><secondary>Variables</secondary></indexterm><para>A <replaceable>variable</replaceable> is a variable name, a corresponding integer value,
and a set of attributes. A variable name is a sequence of letters, digits,
underscores, or periods. A variable can be assigned a value using the <literal>&gt;</literal> dcmd or <literal>::typeset</literal> dcmd, and its attributes
can be manipulated using the <literal>::typeset</literal> dcmd. Each variable's
value is represented as a 64-bit unsigned integer. A variable can have one
or more of the following attributes: read-only (cannot be modified by the
user), persistent (cannot be unset by the user), and tagged (user-defined
indicator).</para><para>The following variables are defined as persistent:<variablelist><varlistentry><term>0</term><listitem><para>Most recent value printed using
the <literal>/</literal>, <literal>\</literal>, <literal>?</literal>, or <literal>=</literal> dcmd</para></listitem></varlistentry><varlistentry><term>9</term><listitem><para>Most recent count used with the <literal>$&lt;</literal> dcmd</para></listitem></varlistentry><varlistentry><term>b</term><listitem><para>Virtual address of the base of
the data section</para></listitem></varlistentry><varlistentry><term>d</term><listitem><para>Size of the data section in bytes</para></listitem></varlistentry><varlistentry><term>e</term><listitem><para>Virtual address of the entry point</para></listitem></varlistentry><varlistentry><term>hits</term><listitem><para>The count of the number of
times the matched software event specifier has been matched. See <link linkend="exec-ctrl-10">Event Callbacks</link>.</para></listitem></varlistentry><varlistentry><term>m</term><listitem><para>Initial bytes (magic number) of
the target's primary object file, or zero if no object file has been read
yet</para></listitem></varlistentry><varlistentry><term>t</term><listitem><para>Size of the text section in bytes</para></listitem></varlistentry><varlistentry><term>thread</term><listitem><para>The thread identifier of
the current representative thread. The value of the identifier depends on
the threading model used by the current target. See <link linkend="exec-ctrl-11">Thread Support</link>.</para></listitem></varlistentry></variablelist></para><para>In addition, the MDB kernel and process targets export the current values
of the representative thread's register set as named variables. The names
of these variables depend on the target's platform and instruction set architecture.</para></sect1><sect1 id="syntax-16"><title>Symbol Name Resolution</title><indexterm id="indexterm-27"><primary>Symbol Name Resolution</primary></indexterm><indexterm id="indexterm-28"><primary>Syntax</primary><secondary>Symbol Name Resolution</secondary></indexterm><para>As explained in <link linkend="syntax-17">Syntax</link>, a symbol identifier present
in an expression context evaluates to the value of this symbol. The value
typically denotes the virtual address of the storage associated with the symbol
in the target's virtual address space. A target can support multiple symbol
tables including, but not limited to, <itemizedlist><listitem><para>Primary executable symbol table</para></listitem><listitem><para>Primary dynamic symbol table</para></listitem><listitem><para>Runtime link-editor symbol table</para></listitem><listitem><para>Standard and dynamic symbol tables for each of a number of
load objects (such as shared libraries in a user process, or kernel modules
in the Solaris kernel)</para></listitem></itemizedlist></para><para>The target typically searches the primary executable's symbol tables
first, then one or more of the other symbol tables. Notice that <acronym>ELF</acronym> symbol tables contain only entries for external, global, and
static symbols; automatic symbols do not appear in the symbol tables processed
by MDB.</para><para>Additionally, MDB provides a private user-defined symbol table that
is searched prior to any of the target symbol tables. The private symbol table
is initially empty, and can be manipulated using the <command>::nmadd</command>
and <command>::nmdel</command> dcmds. </para><para>The <command>::nm</command> <option><gentext type="text">-</gentext>P</option> option can be used to
display the contents of the private symbol table. The private symbol table
allows the user to create symbol definitions for program functions or data
that were either missing from the original program or stripped out. These
definitions are then used whenever MDB converts a symbolic name to an address,
or an address to the nearest symbol.</para><para>Because targets contain multiple symbol tables, and each symbol table
can include symbols from multiple object files, different symbols with the
same name can exist. MDB uses the backquote “ <literal>`</literal> “
character as a symbol-name scoping operator to allow the programmer to obtain
the value of the desired symbol in this situation. </para><para>You can specify the scope used to resolve a symbol name as either: <replaceable>object</replaceable><literal>`</literal><replaceable>name</replaceable>, or <replaceable>file</replaceable><literal>`</literal><replaceable>name</replaceable>, or <replaceable>object</replaceable><literal>`</literal><replaceable>file</replaceable><literal>`</literal><replaceable>name</replaceable>. The object identifier refers to
the name of a load object. The file identifier refers to the basename of a
source file that has a symbol of type <literal>STT_FILE</literal> in the specified
object's symbol table. The object identifier's interpretation depends on the
target type.</para><para>The MDB kernel target expects <replaceable>object</replaceable> to specify
the base name of a loaded kernel module. For example, the symbol name:</para><para><literal>specfs`_init</literal></para><para>evaluates to the value of the <literal>_init</literal> symbol in the <literal>specfs</literal> kernel module.</para><para>The <command>mdb</command> process target expects <replaceable>object</replaceable> to specify the name of the executable or of a loaded shared
library. It can take any of the following forms:</para><itemizedlist><listitem><para>Exact match (that is, a full pathname): <filename>/usr/lib/libc.so.1</filename></para></listitem><listitem><para>Exact basename match: <literal>libc.so.1</literal></para></listitem><listitem><para>Initial basename match up to a ``<literal>.</literal>'' suffix: <literal>libc.so</literal> or <literal>libc</literal></para></listitem><listitem><para>Literal string <literal>a.out</literal> which is accepted
as an alias for the executable</para></listitem></itemizedlist><para>The process target will also accept any of the four forms described
above preceded by an optional link-map id (<literal>lmid</literal>).  The <literal>lmid</literal> prefix is specified by an initial <literal>LM</literal> followed
by the link-map id in hexadecimal followed by an additional backquote.  For
example, the symbol name:</para><para><literal>LM0`libc.so.1`_init</literal></para><para>will evaluate to the value of the <literal>_init</literal> symbol in
the <filename>libc.so.1</filename> library that is loaded on link-map 0 (<literal>LM_ID_BASE</literal>).  The link-map specifier may be necessary to resolve
symbol naming conflicts in the event that the same library is loaded on more
than one link map.  For more information on link maps, refer to the Linker
and Libraries Guide  and the dlopen(3DL) man page. Link-map identifiers will
be displayed when symbols are printed according to the setting of the <literal>showlmid</literal> option, as described under <link linkend="options-2">Summary of Command-line Options</link>.</para><para>In the case of a naming conflict between symbols and hexadecimal integer
values, MDB attempts to evaluate an ambiguous token as a symbol first, before
evaluating it as an integer value. For example, the token <literal>f</literal>
can refer either to the decimal integer value <literal>15</literal> specified
in hexadecimal (the default base), or to a global variable named <literal>f</literal> in the target's symbol table. If a symbol with an ambiguous name
is present, the integer value can be specified by using an explicit <literal>0x</literal> or <literal>0X</literal> prefix.</para></sect1><sect1 id="syntax-13"><title>dcmd and Walker Name Resolution</title><indexterm id="indexterm-29"><primary>dcmd and Walker Name Resolution</primary></indexterm><indexterm id="indexterm-30"><primary>Syntax</primary><secondary>dcmd and Walker Name Resolution</secondary></indexterm><para>As described earlier, each MDB dmod provides
a set of dcmds and walkers. dcmds and walkers are tracked in two distinct,
global namespaces. MDB also keeps track of a dcmd and walker namespace associated
with each dmod. Identically named dcmds or walkers within a given dmod are
not allowed: a dmod with this type of naming conflict will fail to load. </para><para>Name conflicts between dcmds or walkers from different dmods are allowed
in the global namespace.  In the case of a conflict, the first dcmd or walker
with that particular name to be loaded is given precedence in the global namespace.
Alternate definitions are kept in a list in load order. </para><para>The backquote character “ <literal>`</literal> “ can be
used in a dcmd or walker name as a scoping operator to select an alternate
definition. For example, if dmods <literal>m1</literal> and <literal>m2</literal>
each provide a dcmd <literal>d</literal>, and <literal>m1</literal> is loaded
prior to <literal>m2</literal>, then:<variablelist><varlistentry><term><literal>::d</literal></term><listitem><para>Executes <literal>m1</literal>'s definition of <literal>d</literal></para></listitem></varlistentry><varlistentry><term><literal>::m1`d</literal></term><listitem><para>Executes <literal>m1</literal>'s definition of <literal>d</literal></para></listitem></varlistentry><varlistentry><term><literal>::m2`d</literal></term><listitem><para>Executes <literal>m2'</literal>s definition of <literal>d</literal></para></listitem></varlistentry></variablelist></para><para>If module <literal>m1</literal> were now unloaded, the next dcmd on
the global definition list (<literal>m2`d</literal>) would be promoted to
global visibility. The current definition of a dcmd or walker can be determined
using the <command>::which</command> dcmd, described below. The global definition
list can be displayed using the <command>::which</command> <option><gentext type="text">-</gentext>v</option>
option.</para></sect1><sect1 id="syntax-14"><title>dcmd Pipelines</title><indexterm id="indexterm-31"><primary>Pipelines</primary></indexterm><indexterm id="indexterm-32"><primary>Syntax</primary><secondary>Pipelines</secondary></indexterm><para>dcmds can be composed
into a pipeline using the <literal>|</literal> operator. The purpose of a
pipeline is to pass a list of values, typically virtual addresses, from one
dcmd or walker to another. Pipeline stages might be used to map a pointer
from one type of data structure to a pointer to a corresponding data structure,
to sort a list of addresses, or to select the addresses of structures with
certain properties.</para><para>MDB executes each dcmd in the pipeline in order from left to right.
The left-most dcmd is executed using the current value of dot, or using the
value specified by an explicit expression at the start of the command. When
a <literal>|</literal> operator is encountered, MDB creates a pipe (a shared
buffer) between the output of the dcmd to its left and the MDB parser, and
an empty list of values. </para><para>As the dcmd executes, its standard output is placed in the pipe and
then consumed and evaluated by the parser, as if MDB were reading this data
from standard input. Each line must consist of an arithmetic expression terminated
by a <symbol>NEWLINE</symbol> or semicolon (<literal>;</literal>). The value
of the expression is appended to the list of values associated with the pipe.
If a syntax error is detected, the pipeline is aborted.</para><para>When the dcmd to the left of a <literal>|</literal> operator completes,
the list of values associated with the pipe is then used to invoke the dcmd
to the right of the <literal>|</literal> operator. For each value in the list,
dot is set to this value and the right-hand dcmd is executed. Only the rightmost
dcmd in the pipeline has its output printed to standard output. If any dcmd
in the pipeline produces output to standard error, these messages are printed
directly to standard error and are not processed as part of the pipeline.</para></sect1><sect1 id="syntax-15"><title>Formatting dcmds</title><indexterm id="indexterm-33"><primary>Formatting dcmds</primary></indexterm><indexterm id="indexterm-34"><primary>Syntax</primary><secondary>Formatting dcmds</secondary></indexterm><para>The <literal>/</literal>, <literal>\</literal>, <literal>?</literal>, and <literal>=</literal> metacharacters are used to denote the special output formatting
dcmds. Each of these dcmds accepts an argument list consisting of one or more
format characters, repeat counts, or quoted strings. A format character is
one of the <acronym>ASCII</acronym> characters shown in the table below. </para><para>Format characters are used to read and format data from the target.
A repeat count is a positive integer preceding the format character that is
always interpreted in base 10 (decimal). A repeat count can also be specified
as an expression enclosed in square brackets preceded by a dollar sign (<literal>$[ ]</literal>). A string argument must be enclosed in double-quotes (<literal>" "</literal>). No blanks are necessary between format arguments.</para><para>The formatting dcmds are:</para><variablelist><varlistentry><term><literal>/</literal></term><listitem><para>Display data
from the target's virtual address space starting at the virtual address specified
by dot.</para></listitem></varlistentry><varlistentry><term><literal>\</literal></term><listitem><para>Display data
from the target's physical address space starting at the physical address
specified by dot.</para></listitem></varlistentry><varlistentry><term><literal>?</literal></term><listitem><para>Display data
from the target's primary object file starting at the object file location
corresponding to the virtual address specified by dot.</para></listitem></varlistentry><varlistentry><term><literal>=</literal></term><listitem><para>Display the
value of dot itself in each of the specified data formats. The <literal>=</literal> dcmd is therefore useful for converting between bases and performing
arithmetic.</para></listitem></varlistentry></variablelist><para>In addition to dot, MDB keeps track of another global
value called the <replaceable>increment</replaceable>. The increment represents
the distance between dot and the address following all the data read by the
last formatting dcmd. </para><para>For example, if a formatting dcmd is executed with dot equal to address
A, and displays a 4-byte integer, then after this dcmd completes, dot is still
A, but the increment is set to <literal>4</literal>. The <literal>+</literal>
character, described in <link linkend="syntax-1">Arithmetic Expansion</link>, would now evaluate to the
value <literal>A + 4</literal>, and could be used to reset dot to the address
of the next data object for a subsequent dcmd.</para><para>Most format characters increase the value of the increment by the number
of bytes corresponding to the size of the data format, shown in the table.
The table of format characters can be displayed from within MDB using the <command>::formats</command> dcmd. </para><para>The format characters are:</para><indexterm id="indexterm-35"><primary><command>::formats</command></primary></indexterm><indexterm id="indexterm-36"><primary>dcmds</primary><secondary><command>::formats</command></secondary></indexterm><variablelist><varlistentry><term>+</term><listitem><para>Increment dot by the count (variable
size)</para></listitem></varlistentry><varlistentry><term>-</term><listitem><para>Decrement dot by the count (variable
size)</para></listitem></varlistentry><varlistentry><term>B</term><listitem><para>Hexadecimal int (1 byte)</para></listitem></varlistentry><varlistentry><term>C</term><listitem><para>Character using C character notation
(1 byte)</para></listitem></varlistentry><varlistentry><term>D</term><listitem><para>Decimal signed int (4 bytes)</para></listitem></varlistentry><varlistentry><term>E</term><listitem><para>Decimal unsigned long long (8
bytes)</para></listitem></varlistentry><varlistentry><term>F</term><listitem><para>Double (8 bytes)</para></listitem></varlistentry><varlistentry><term>G</term><listitem><para>Octal unsigned long long (8 bytes)</para></listitem></varlistentry><varlistentry><term>H</term><listitem><para>Swap bytes and shorts (4 bytes)</para></listitem></varlistentry><varlistentry><term>I</term><listitem><para>Address and disassembled instruction
(variable size)</para></listitem></varlistentry><varlistentry><term>J</term><listitem><para>Hexadecimal long long (8 bytes)</para></listitem></varlistentry><varlistentry><term>K</term><listitem><para>Hexadecimal uintptr_t (4 or 8
bytes)</para></listitem></varlistentry><varlistentry><term>N</term><listitem><para>Newline</para></listitem></varlistentry><varlistentry><term>O</term><listitem><para>Octal unsigned int (4 bytes)</para></listitem></varlistentry><varlistentry><term>P</term><listitem><para>Symbol (4 or 8 bytes)</para></listitem></varlistentry><varlistentry><term>Q</term><listitem><para>Octal signed int (4 bytes)</para></listitem></varlistentry><varlistentry><term>R</term><listitem><para>Binary int (8 bytes)</para></listitem></varlistentry><varlistentry><term>S</term><listitem><para>String using C string notation
(variable size)</para></listitem></varlistentry><varlistentry><term>T</term><listitem><para>Horizontal tab</para></listitem></varlistentry><varlistentry><term>U</term><listitem><para>Decimal unsigned int (4 bytes)</para></listitem></varlistentry><varlistentry><term>V</term><listitem><para>Decimal unsigned int (1 byte)</para></listitem></varlistentry><varlistentry><term>W</term><listitem><para>Default radix unsigned int (4
bytes)</para></listitem></varlistentry><varlistentry><term>X</term><listitem><para>Hexadecimal int (4 bytes)</para></listitem></varlistentry><varlistentry><term>Y</term><listitem><para>Decoded time32_t (4 bytes)</para></listitem></varlistentry><varlistentry><term>Z</term><listitem><para>Hexadecimal long long (8 bytes)</para></listitem></varlistentry><varlistentry><term>^</term><listitem><para>Decrement dot by increment * count
(variable size)</para></listitem></varlistentry><varlistentry><term>a</term><listitem><para>Dot as symbol+offset</para></listitem></varlistentry><varlistentry><term>b</term><listitem><para>Octal unsigned int (1 byte)</para></listitem></varlistentry><varlistentry><term>c</term><listitem><para>Character (1 byte)</para></listitem></varlistentry><varlistentry><term>d</term><listitem><para>Decimal signed short (2 bytes)</para></listitem></varlistentry><varlistentry><term>e</term><listitem><para>Decimal signed long long (8 bytes)</para></listitem></varlistentry><varlistentry><term>f</term><listitem><para>Float (4 bytes)</para></listitem></varlistentry><varlistentry><term>g</term><listitem><para>Octal signed long long (8 bytes)</para></listitem></varlistentry><varlistentry><term>h</term><listitem><para>Swap bytes (2 bytes)</para></listitem></varlistentry><varlistentry><term>i</term><listitem><para>Disassembled instruction (variable
size)</para></listitem></varlistentry><varlistentry><term>n</term><listitem><para>Newline</para></listitem></varlistentry><varlistentry><term>o</term><listitem><para>Octal unsigned short (2 bytes)</para></listitem></varlistentry><varlistentry><term>p</term><listitem><para>Symbol (4 or 8 bytes)</para></listitem></varlistentry><varlistentry><term>q</term><listitem><para>Octal signed short (2 bytes)</para></listitem></varlistentry><varlistentry><term>r</term><listitem><para>Whitespace</para></listitem></varlistentry><varlistentry><term>s</term><listitem><para>Raw string (variable size)</para></listitem></varlistentry><varlistentry><term>t</term><listitem><para>Horizontal tab</para></listitem></varlistentry><varlistentry><term>u</term><listitem><para>Decimal unsigned short (2 bytes)</para></listitem></varlistentry><varlistentry><term>v</term><listitem><para>Decimal signed int (1 byte)</para></listitem></varlistentry><varlistentry><term>w</term><listitem><para>Default radix unsigned short (2
bytes)</para></listitem></varlistentry><varlistentry><term>x</term><listitem><para>Hexadecimal short (2 bytes)</para></listitem></varlistentry><varlistentry><term>y</term><listitem><para>Decoded time64_t (8 bytes)</para></listitem></varlistentry></variablelist><para>The <literal>/</literal>, <literal>\</literal>, and <literal>?</literal> formatting dcmds can also be used to write to the target's virtual
address space, physical address space, or object file by specifying one of
the following modifiers as the first format character, and then specifying
a list of words that are either immediate values or expressions enclosed in
square brackets preceded by a dollar sign (<literal>$[ ]</literal>).</para><para>The write modifiers are:</para><indexterm id="indexterm-37"><primary>write modifiers</primary></indexterm><indexterm id="indexterm-38"><primary>Formatting</primary><secondary>write modifiers</secondary></indexterm><variablelist><varlistentry><term>v</term><listitem><para>Write the lowest byte of the value
of each expression to the target beginning at the location specified by dot</para></listitem></varlistentry><varlistentry><term>w</term><listitem><para>Write the lowest 2 bytes of the
value of each expression to the target beginning at the location specified
by dot</para></listitem></varlistentry><varlistentry><term>W</term><listitem><para>Write the lowest 4 bytes of the
value of each expression to the target beginning at the location specified
by dot</para></listitem></varlistentry><varlistentry><term>Z</term><listitem><para>Write the complete 8 bytes of
the value of each expression to the target beginning at the location specified
by dot</para></listitem></varlistentry></variablelist><para>The <literal>/</literal>, <literal>\</literal>, and <literal>?</literal> formatting dcmds can also be used to search for a particular integer
value in the target's virtual address space, physical address space, and object
file, respectively, by specifying one of the following modifiers as the first
format character, then specifying a value and optional mask. The value and
mask are each specified as either immediate values or expressions enclosed
in square brackets preceded by a dollar sign.</para><para>If only a value is specified, MDB reads integers of the appropriate
size and stops at the address containing the matching value. If a value <literal>V</literal> and mask <literal>M</literal> are specified, MDB reads integers
of the appropriate size and stops at the address containing a value <literal>X</literal> where <literal>(X &amp; M) == V</literal>. At the completion of
the dcmd, dot is updated to the address containing the match. If no match
is found, dot is left at the last address that was read.</para><para>The search modifiers are:</para><indexterm id="indexterm-39"><primary>search modifiers</primary></indexterm><indexterm id="indexterm-40"><primary>Formatting</primary><secondary>search modifiers</secondary></indexterm><variablelist><varlistentry><term>l</term><listitem><para>Search for the specified 2-byte
value</para></listitem></varlistentry><varlistentry><term>L</term><listitem><para>Search for the specified 4-byte
value</para></listitem></varlistentry><varlistentry><term>M</term><listitem><para>Search for the specified 8-byte
value</para></listitem></varlistentry></variablelist><para>For both user and kernel targets, an address space is
typically composed of a set of discontiguous segments. It is not legal to
read from an address that does not have a corresponding segment. If a search
reaches a segment boundary without finding a match, it aborts when the read
past the end of the segment boundary fails.</para></sect1></chapter><chapter id="interaction-3"><gentext type="text">Chapter 4</gentext><gentext type="toc">4.&#160;&#160;Interaction</gentext><title>Interaction</title><highlights><para>This chapter describes the MDB interactive command-line
editing and history functions, the output pager, and debugger signal handling.</para></highlights><sect1 id="interaction-4"><title>Command Re-entry</title><para>The text of the last <literal>HISTSIZE</literal> (default 128)  commands <indexterm id="indexterm-41"><primary>command reentry</primary></indexterm>entered from a terminal device
are saved in memory. The in-line editing facility, described next, provides
key mappings for searching and fetching elements from the history list.</para></sect1><sect1 id="interaction-5"><title>In-line Editing</title><para>If standard input is a terminal device, MDB provides some simple emacs-style
facilities for <indexterm id="indexterm-42"><primary>in-line editing</primary></indexterm>editing
the command line. The <literal>search</literal>, <literal>previous</literal>,
and <literal>next</literal> commands in edit mode provide access to the history
list. Only strings, not patterns, are matched when searching. In the list
below, the notation for control characters is caret  (^)  followed by a character
shown in upper case. The notation for escape sequences is M- followed by a
character. For example, M-f (pronounced meta-      eff) is entered by depressing
&lt;ESC&gt; followed by 'f', or by depressing Meta followed by 'f' on keyboards
that support a Meta key. A command line is committed and executed using RETURN
or NEWLINE. The edit commands are:</para><variablelist><varlistentry><term>^F</term><listitem><para>Move cursor forward (right) one
character.</para></listitem></varlistentry><varlistentry><term>M-f</term><listitem><para>Move cursor forward one word.</para></listitem></varlistentry><varlistentry><term>^B</term><listitem><para>Move cursor backward (left) one
character.</para></listitem></varlistentry><varlistentry><term>M-b</term><listitem><para>Move cursor backward one word.</para></listitem></varlistentry><varlistentry><term>^A </term><listitem><para>Move cursor to start of line.</para></listitem></varlistentry><varlistentry><term>^E</term><listitem><para>Move cursor to end of line.</para></listitem></varlistentry><varlistentry><term>^D</term><listitem><para>Delete current character, if
the current line is  not empty. If the current line is empty, ^D denotes EOF
and the debugger will exit.</para></listitem></varlistentry><varlistentry><term>M-^H</term><listitem><para>(Meta-backspace) Delete previous
word.</para></listitem></varlistentry><varlistentry><term>^K </term><listitem><para>Delete from the cursor to the
end of the line.</para></listitem></varlistentry><varlistentry><term>^L </term><listitem><para>Reprint the current line.</para></listitem></varlistentry><varlistentry><term>^T</term><listitem><para>Transpose current character with
next character.</para></listitem></varlistentry><varlistentry><term>^N</term><listitem><para>Fetch the next command from the
history. Each time  ^N is entered, the next command forward  in time is retrieved.</para></listitem></varlistentry><varlistentry><term>^P</term><listitem><para>Fetch the previous command from
the history. Each time ^P is entered, the next command backward in time is
retrieved.</para></listitem></varlistentry><varlistentry><term>^R[string]</term><listitem><para>Search backward in the
history for a previous command line containing string. The string should be
terminated by a RETURN or NEWLINE. If string is  omitted, the previous history
element containing the most            recent string is retrieved.</para></listitem></varlistentry></variablelist><para>The editing mode also interprets the following user-defined
     sequences as editing commands. User defined sequences can be read or
modified using the <literal>stty</literal>(1) command. </para><variablelist><varlistentry><term>erase</term><listitem><para>User defined erase character
 (usually ^H or ^?). Delete previous character.</para></listitem></varlistentry><varlistentry><term>intr</term><listitem><para>User defined interrupt character
(usually  ^C).  Abort the current command and print a new prompt.</para></listitem></varlistentry><varlistentry><term>kill</term><listitem><para>User defined kill character
(usually  ^U).  Kill  the entire current command line.</para></listitem></varlistentry><varlistentry><term>quit</term><listitem><para>User defined quit character
(usually  ^\).  Quit the debugger.</para></listitem></varlistentry><varlistentry><term>suspend</term><listitem><para>User defined suspend character
(usually  ^Z).  Suspend the debugger.</para></listitem></varlistentry><varlistentry><term>werase</term><listitem><para>User defined word erase character
(usually ^W). Erase the preceding word.</para></listitem></varlistentry></variablelist><para>On keyboards that support an <indexterm id="indexterm-43"><primary>extended keypad arrow keys</primary></indexterm>extended keypad with arrow keys, <literal>mdb</literal> will interpret these keystrokes as editing commands: </para><variablelist><varlistentry><term>up-arrow</term><listitem><para>Fetch the previous command
from the history  (same  as ^P).</para></listitem></varlistentry><varlistentry><term>down-arrow</term><listitem><para>Fetch the next command
from the history (same as ^N).</para></listitem></varlistentry><varlistentry><term>left-arrow</term><listitem><para>Move cursor backward
one character (same as ^B).</para></listitem></varlistentry><varlistentry><term>right-arrow</term><listitem><para>Move cursor forward
one character (same as ^F)</para></listitem></varlistentry></variablelist></sect1><sect1 id="interaction-1"><title>Output Pager</title><para><literal>mdb</literal> provides a built-in <indexterm id="indexterm-44"><primary>output pager</primary></indexterm>output pager. The output pager is enabled if the
debugger's standard output is a terminal device. Each time a command is executed, <literal>mdb</literal> will pause after one screenful of output is produced and will
display a pager prompt:</para><screen format="linespecific">&gt;&gt; More [&lt;space&gt;, &lt;cr&gt;, q, n, c, a] ?</screen><para>The following key sequences are recognized by the pager: </para><variablelist><varlistentry><term>SPACE</term><listitem><para>Display the next screenful
of output.</para></listitem></varlistentry><varlistentry><term>a, A</term><listitem><para>Abort the current top-level
command and return to  the prompt.</para></listitem></varlistentry><varlistentry><term>c, C</term><listitem><para>Continue displaying output
without pausing at each screenful until the current top-level command is complete.</para></listitem></varlistentry><varlistentry><term>n, N, NEWLINE, RETURN</term><listitem><para>Display the
next line of output.</para></listitem></varlistentry><varlistentry><term>q, Q, ^C, ^\</term><listitem><para>Quit (abort) the current <literal>dcmd</literal> only.</para></listitem></varlistentry></variablelist></sect1><sect1 id="interaction-2"><title>Signal Handling</title><para>The debugger ignores the PIPE and QUIT <indexterm id="indexterm-45"><primary>signal handling</primary></indexterm>signals. The INT signal aborts the command that is currently
executing. The debugger intercepts and provides special handling for the ILL,
TRAP, EMT, FPE, BUS, and SEGV signals. If any of these signals are generated
asynchronously (that is, delivered from another process using <literal>kill</literal>(2)), mdb will restore the signal to its default disposition and
dump core. However, if any of these signals are generated synchronously by
the debugger process itself and a dcmd from an externally loaded <literal>dmod</literal> is currently executing, and standard input is a terminal, <literal>mdb</literal> will provide a menu of choices allowing the user to force a
core dump, quit without producing a core dump, stop for attach by a debugger,
or attempt to resume.  The resume option will abort all active commands and
unload the <literal>dmod</literal> whose dcmd was active at the time the fault
occurred. It can then be subsequently re-loaded by the user. The resume option
provides limited protection against buggy dcmds. Refer to <link linkend="notes-2">Warnings</link>,
Use of the Error Recovery Mechanism, for information about the risks associated
with the resume option.</para></sect1></chapter><chapter id="commands-1"><gentext type="text">Chapter 5</gentext><gentext type="toc">5.&#160;&#160;Built-in Commands</gentext><title>Built-in Commands</title><highlights><para>MDB provides a set of built-in dcmds that are always defined.
Some of these dcmds are applicable only to certain targets: if a dcmd is not
applicable to the current target, it fails and prints a message indicating “command
is not supported by current target”. </para><para>In many cases, MDB provides a mnemonic equivalent (<command>::identifier</command>) for the legacy <olink targetdocent="REFMAN1" localinfo="ADB-1" type="v-only"><citerefentry><refentrytitle>adb</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink> dcmd names. For example, <command>::quit</command> is provided as the equivalent of <literal>$q</literal>. Programmers
who are experienced with <olink targetdocent="REFMAN1" localinfo="ADB-1" type="v-only"><citerefentry><refentrytitle>adb</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink>
or who appreciate brevity or arcana might prefer the <literal>$</literal>
or <literal>:</literal> forms of the built-ins. Programmers who are new to
MDB might prefer the more verbose <literal>::</literal> form. The built-ins
are shown in alphabetical order. If a <literal>$</literal> or <literal>:</literal>
form has a <command>::identifier</command> equivalent, it is shown under the <command>::identifier</command> form.</para></highlights><sect1 id="commands-2"><title>Built-in dcmds</title><variablelist termlength="wholeline"><varlistentry><term>&gt; <replaceable>variable-name</replaceable></term><term>&gt; /<replaceable>modifier</replaceable>/ <replaceable>variable-name</replaceable></term><listitem><para>Assign the value of dot to the specified named variable. Some
variables are read-only and cannot be modified. If the <literal>&gt;</literal>
is followed by a modifier character surrounded by <literal>//</literal>, then the value is modified as part of the
assignment. The modifier characters are:<variablelist><varlistentry><term><literal>c</literal></term><listitem><para>Unsigned char
quantity (1-byte)</para></listitem></varlistentry><varlistentry><term><literal>s</literal></term><listitem><para>Unsigned short
quantity (2-byte)</para></listitem></varlistentry><varlistentry><term><literal>i</literal></term><listitem><para>Unsigned int
quantity (4-byte)</para></listitem></varlistentry><varlistentry><term><literal>l</literal></term><listitem><para>Unsigned long
quantity (4-byte in 32-bit, 8-byte in 64-bit)</para></listitem></varlistentry></variablelist></para><para>Notice that these operators do not perform a cast; they instead fetch
the specified number of low-order bytes (on little-endian architectures) or
high-order bytes (big-endian architectures). These modifiers are provided
for backward compatibility; the MDB */<replaceable>modifier</replaceable>/
and %/<replaceable>modifier</replaceable>/ syntax should be used instead.</para></listitem></varlistentry><varlistentry><term><literal>$&lt;</literal> <replaceable>macro-name</replaceable></term><listitem><para>Read and execute commands from the specified macro file. The
file name can be given as an absolute or relative path. If the file name is
a simple name (that is, if it does not contain a '<literal>/</literal>'),
MDB searches for it in the macro file include path. If another macro file
is currently being processed, this file is closed and replaced with the new
file.</para></listitem></varlistentry><indexterm id="indexterm-46"><primary>dcmds</primary><secondary><literal>$&lt;</literal></secondary></indexterm><varlistentry><term><literal>$&lt;&lt;</literal> <replaceable>macro-name</replaceable></term><listitem><para>Read and execute commands from the specified macro file (as
with <literal>$&lt;</literal>), but do not close the current open macro file.</para><indexterm id="indexterm-47"><primary>dcmds</primary><secondary><literal>$&lt;&lt;</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term><literal>$?</literal></term><listitem><para>Print the
process-<acronym>ID</acronym> and current signal of the target if it is a
user process or core file, and then print the general register set of the
representative thread.<indexterm id="indexterm-48"><primary>dcmds</primary><secondary><literal>$?</literal></secondary></indexterm></para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <literal>$C</literal>
[ <replaceable>count</replaceable> ]</term><listitem><para>Print a C stack
backtrace, including stack frame pointer information. If the dcmd is preceded
by an explicit <replaceable>address</replaceable>, a backtrace beginning at
this virtual memory address is displayed. Otherwise, the stack of the representative
thread is displayed. If an optional count value is given as an argument, no
more than <replaceable>count</replaceable> arguments are displayed for each
stack frame in the output.<indexterm id="indexterm-49"><primary>dcmds</primary><secondary><literal>$C</literal></secondary></indexterm></para><note arch="sparc" os="solaris64"><gentext type="text">64-bit SPARC only &#8211; </gentext><para>The biased frame pointer value (that
is, the virtual address minus <literal>0x7ff</literal>) should be used as
the address when requesting a stack trace.</para></note></listitem></varlistentry><varlistentry><term>[ <replaceable>base</replaceable> ] <literal>$d</literal></term><listitem><para>Get or set the default output radix. If the dcmd is preceded
by an explicit expression, the default output radix is set to the given <replaceable>base</replaceable>; otherwise, the current radix is printed in base 10 (decimal).
The default radix is base 16 (hexadecimal).</para><indexterm id="indexterm-50"><primary>dcmds</primary><secondary><literal>$d</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term><literal>$e</literal></term><listitem><para>Print a list
of all known external (global) symbols of type object or function, the value
of the symbol, and the first 4 (32-bit <command>mdb</command>) or 8 (64-bit <command>mdb</command>) bytes stored at this location in the target's virtual address
space. The <command>::nm</command> dcmd provides more flexible options for
displaying symbol tables.</para><indexterm id="indexterm-51"><primary>dcmds</primary><secondary><literal>$e</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term><literal>$P</literal> <replaceable>prompt-string</replaceable></term><listitem><para>Set the prompt to the specified <replaceable>prompt-string</replaceable>. The default prompt is ' <literal>&gt;</literal> '. The prompt
can also be set using <command>::set</command> <option><gentext type="text">-</gentext>P</option> or the <option><gentext type="text">-</gentext>P</option> command-line option.</para><indexterm id="indexterm-52"><primary>dcmds</primary><secondary><literal>$P</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term><replaceable>distance</replaceable> <literal>$s</literal></term><listitem><para>Get or set the symbol matching <replaceable>distance</replaceable>
for address-to-symbol-name conversions. The symbol matching distance modes
are discussed along with the <option><gentext type="text">-</gentext>s</option> command-line option in <link linkend="options-1">Appendix A, Options</link>. The symbol matching distance can also be modified using
the <command>::set</command> <option><gentext type="text">-</gentext>s</option> option. If no distance is
specified, the current setting is displayed.</para><indexterm id="indexterm-53"><primary>dcmds</primary><secondary><literal>$s</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term><literal>$v</literal></term><listitem><para>Print a list
of the named variables that have non-zero values. The <command>::vars</command>
dcmd provides other options for listing variables.</para><indexterm id="indexterm-54"><primary>dcmds</primary><secondary><literal>$v</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term><replaceable>width</replaceable> <literal>$w</literal></term><listitem><para>Set the output page <replaceable>width</replaceable> to the
specified value. Typically, this command is not necessary, as MDB queries
the terminal for its width and handles resize events.</para><indexterm id="indexterm-55"><primary>dcmds</primary><secondary><literal>$w</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term><literal>$W</literal></term><listitem><para>Reopen the
target for writing, as if MDB had been executed with the <option><gentext type="text">-</gentext>w</option>
option on the command line. Write mode can also be enabled with the <command>::set</command> <option><gentext type="text">-</gentext>w</option> option.</para><indexterm id="indexterm-56"><primary>dcmds</primary><secondary><literal>$W</literal></secondary></indexterm></listitem></varlistentry><varlistentry><term>[ <replaceable>pid</replaceable> ] <command>::attach </command> [ <replaceable>core</replaceable> | <replaceable>pid</replaceable>
]</term><term>[ <replaceable>pid</replaceable> ] <command>:A</command> [ <replaceable> core</replaceable> | <replaceable>pid</replaceable> ]</term><indexterm id="indexterm-57"><primary>dcmds</primary><secondary><command>::attach</command></secondary></indexterm><indexterm id="indexterm-58"><primary>dcmds</primary><secondary><command>:A</command></secondary></indexterm><listitem><para>If the user process target
is active, attach to and debug the specified process-<acronym>ID</acronym>
or <replaceable>core</replaceable> file. The core file path name should be
specified as a string argument. The process-<acronym>ID</acronym> can be specified
as the string argument, or as the value of the expression preceding the dcmd.
Recall that the default base is hexadecimal, so decimal <acronym>PID</acronym>s
obtained using <olink targetdocent="REFMAN1" localinfo="PGREP-1" type="v-only"><citerefentry><refentrytitle>pgrep</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink>
or <olink targetdocent="REFMAN1" localinfo="PS-1"><citerefentry><refentrytitle>ps</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink> should be
preceded with “<literal>0t</literal>” when specified as expressions.</para></listitem></varlistentry><varlistentry><term><command>::cat</command> <replaceable>filename</replaceable>
... </term><listitem><para>Concatenate and display files. Each file name can
be specified as a relative or absolute path name. The file contents will print
to standard output, but will not pass through the output pager. This dcmd
is intended to be used with the <literal>|</literal> operator; the programmer
can initiate a pipeline using a list of addresses stored in an external file.</para><indexterm id="indexterm-59"><primary>dcmds</primary><secondary><command>::cat</command></secondary></indexterm></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::context</command></term><term><replaceable>address</replaceable> <literal>$p</literal></term><indexterm id="indexterm-60"><primary>dcmds</primary><secondary><command>::context</command></secondary></indexterm><indexterm id="indexterm-61"><primary>dcmds</primary><secondary><literal>$p</literal></secondary></indexterm><listitem><para>Context switch to the
specified process. A context switch operation is valid only when using the
kernel target. The process context is specified using the <replaceable>address</replaceable> of its <literal>proc</literal> structure in the kernel's virtual
address space. The special context address "<literal>0</literal>" is used
to denote the context of the kernel itself. MDB can only perform a context
switch when examining a crash dump if the dump contains the physical memory
pages of the specified user process (as opposed to just kernel pages). The
kernel crash dump facility can be configured to dump all pages or the pages
of the current user process using <olink targetdocent="REFMAN1M" localinfo="DUMPADM-1M"><citerefentry><refentrytitle>dumpadm</refentrytitle><manvolnum><gentext type="text">(</gentext>1M<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.
The <command>::status</command> dcmd can be used to display the contents of
the current crash dump.</para><para>When the user requests a context switch from the kernel target, MDB
constructs a new target representing the specified user process. After the
switch occurs, the new target interposes its dcmds at the global level: thus
the <literal>/</literal> dcmd can now format and display data from the virtual
address space of the user process, the <command>::mappings</command> dcmd
can display the mappings in the address space of the user process, and so
on. The kernel target can be restored by executing <command>0::context</command>.</para></listitem></varlistentry><varlistentry><term><command>::dcmds</command></term><indexterm id="indexterm-62"><primary>dcmds</primary><secondary><command>::dcmds</command></secondary></indexterm><listitem><para>List the available dcmds and print a brief description
for each one.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::dis</command> [ <option><gentext type="text">-</gentext>fw</option> ] [ <option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable> ] [ <replaceable>address</replaceable> ]</term><indexterm id="indexterm-63"><primary>dcmds</primary><secondary><command>::dis</command></secondary></indexterm><listitem><para>Disassemble starting at or around the <replaceable>address</replaceable> specified by the final argument, or the current value
of dot. If the address matches the start of a known function, the entire function
is disassembled; otherwise, a “window” of instructions before
and after the specified address is printed in order to provide context. By
default, instructions are read from the target's virtual address space; if
the <option><gentext type="text">-</gentext>f</option> option is present, instructions are read from the target's
object file instead. The <option><gentext type="text">-</gentext>f</option> option is enabled by default if
the debugger is not currently attached to a live process, core file, or crash
dump. The <option><gentext type="text">-</gentext>w</option> option can be used to force window-mode, even
if the address is the start of a known function. The size of the window defaults
to ten instructions; the number of instructions can be specified explicitly
using the <option><gentext type="text">-</gentext>n</option> option.</para></listitem></varlistentry><varlistentry><term><command>::disasms</command></term><indexterm id="indexterm-64"><primary>dcmds</primary><secondary><command>::disasms</command></secondary></indexterm><listitem><para>List the available disassembler modes. When a
target is initialized, MDB attempts to select the appropriate disassembler
mode. The user can change the mode to any of the modes listed using the <command>::dismode</command> dcmd.</para></listitem></varlistentry><varlistentry><term><command>::dismode</command> [ <replaceable>mode</replaceable>
]</term><term><literal>$V</literal> [ <replaceable>mode</replaceable> ] </term><indexterm id="indexterm-65"><primary>dcmds</primary><secondary><command>::dismode</command></secondary></indexterm><indexterm id="indexterm-66"><primary>dcmds</primary><secondary><literal>$V</literal></secondary></indexterm><listitem><para>Get or set the disassembler
mode. If no argument is specified, print the current disassembler mode. If
a <replaceable>mode</replaceable> argument is specified, switch the disassembler
to the specified mode. The list of available disassemblers can be displayed
using the <command>::disasms</command> dcmd.</para></listitem></varlistentry><varlistentry><term><command>::dmods</command> [ <option><gentext type="text">-</gentext>l</option> ] [ <replaceable>module-name</replaceable> ]</term><indexterm id="indexterm-67"><primary>dcmds</primary><secondary><command>::dmods</command></secondary></indexterm><listitem><para>List the loaded debugger modules.  If the <option><gentext type="text">-</gentext>l</option> option
is specified, the list of the dcmds and walkers associated with each dmod
is printed below its name. The output can be restricted to a particular dmod
by specifying its name as an additional argument.</para></listitem></varlistentry><varlistentry><term><command>[<replaceable>address</replaceable>] ::dump [<option><gentext type="text">-</gentext>eqrstu</option>] [<option><gentext type="text">-</gentext>f</option>|<option><gentext type="text">-</gentext>p</option>] [<option><gentext type="text">-</gentext>g</option> <replaceable>bytes</replaceable>] [<option><gentext type="text">-</gentext>w</option> <replaceable>paragraphs</replaceable>] </command></term><indexterm id="indexterm-68"><primary>dcmds</primary><secondary><command>::dump</command></secondary></indexterm><listitem><para>Print a hexadecimal
and <acronym>ASCII</acronym> memory dump of the 16-byte aligned region of
virtual memory containing the address specified by dot. If a repeat count
is specified for <command>::dump</command>, this is interpreted as a number
of bytes to dump rather than a number of iterations. The <command>::dump</command>
dcmd also recognizes the following options:</para><variablelist><varlistentry><term><option><gentext type="text">-</gentext>e </option></term><listitem><para>Adjust for endian-ness.
 The <option><gentext type="text">-</gentext>e</option> option assumes 4-byte words; the <option><gentext type="text">-</gentext>g</option>
option can be used to change the default word size.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>f </option></term><listitem><para>Read data from
the object file location corresponding to the given virtual address instead
of from the target's virtual address space. The <option><gentext type="text">-</gentext>f</option> option
is enabled by default if the debugger is not currently attached to a live
process, core file, or crash dump.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>g</option> <replaceable>group</replaceable></term><listitem><para>Display bytes in groups of bytes.  The default <replaceable>group</replaceable> size is 4 bytes. The <replaceable>group</replaceable>
size must be a power of two that divides the line width</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>p</option> </term><listitem><para>Interpret <replaceable>address</replaceable> as a physical address location in the              
       target's address space instead of a virtual address. </para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>q</option></term><listitem><para>Do not print
an ASCII decoding of the data.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>r</option></term><listitem><para>Number lines
relative to the start address instead of with the explicit address of each
line. This option implies the <option><gentext type="text">-</gentext>u</option> option.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>s</option></term><listitem><para>Elide repeated
lines.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>t</option></term><listitem><para>Only read from
and display the contents of the specified addresses, instead of reading and
printing entire lines.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>u</option></term><listitem><para>Unalign output
instead of aligning the output at a paragraph boundary. </para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>w</option> <replaceable>paragraphs</replaceable></term><listitem><para>Display paragraphs 16-byte paragraphs per line.  The default
number of paragraphs is one.  The maximum value accepted for <option><gentext type="text">-</gentext>w</option>
is 16.</para></listitem></varlistentry></variablelist></listitem></varlistentry><varlistentry><term><command>::echo</command> [ <replaceable>string</replaceable>
| <replaceable>value</replaceable> ... ]</term><indexterm id="indexterm-69"><primary>dcmds</primary><secondary><command>::echo</command></secondary></indexterm><listitem><para>Print the arguments separated by blanks and terminated by
a <symbol>NEWLINE</symbol> to standard output. Expressions enclosed in <literal>$[ ]</literal> will be evaluated to a value and printed in the default base.</para></listitem></varlistentry><varlistentry><term><command>::eval</command> <replaceable>command</replaceable></term><indexterm id="indexterm-70"><primary>dcmds</primary><secondary><command>::eval</command></secondary></indexterm><listitem><para>Evaluate and execute the
specified string as a command. If the command contains metacharacters or white
space, it should be enclosed in double or single quotes.</para></listitem></varlistentry><varlistentry><term><command>::files</command><indexterm id="indexterm-71"><primary>dcmds</primary><secondary><command>::files</command></secondary></indexterm><literal>$f</literal></term><indexterm id="indexterm-72"><primary>dcmds</primary><secondary><literal>$f</literal></secondary></indexterm><listitem><para>Print a list of the known
source files (symbols of type <symbol>STT_FILE</symbol> present in the various
target symbol tables).</para></listitem></varlistentry><varlistentry><term><command>[<replaceable>address</replaceable>] ::findsym
[<option><gentext type="text">-</gentext>g</option>] [ <replaceable>address</replaceable> | <replaceable>symbol</replaceable> ...]</command></term><listitem><para>Search instruction
text for instructions that refer to the specified symbols or addresses. The
search list should consist of one or more addresses or symbol names specified
as an address preceding the <literal>dcmd</literal> or one or more symbol
names or expressions following the <literal>dcmd</literal>. If the <option><gentext type="text">-</gentext>g</option> option is specified, the search is restricted to instruction text
that is part of a globally visible function in the target's symbol table.</para><note><gentext type="text">Note &#8211; </gentext><para><emphasis>SPARC only</emphasis>. The <command>::findsym</command> <literal>dcmd</literal> is only available when debugging a target that uses the SPARC
instruction set architecture.</para></note></listitem></varlistentry><varlistentry><term><command>::formats</command></term><indexterm id="indexterm-73"><primary>dcmds</primary><secondary><command>::formats</command></secondary></indexterm><listitem><para>List the available output format characters for
use with the <literal>/</literal>, <literal>\</literal>, <literal>?</literal>,
and <literal>=</literal> formatting dcmds. The formats and their use is described
in <link linkend="syntax-15">Formatting dcmds</link>.</para></listitem></varlistentry><varlistentry><term><command>[ thread ] ::fpregs [<option><gentext type="text">-</gentext>dqs</option>]</command> </term><term><command>[ thread ] <literal>$x</literal>, <literal>$X</literal>, <literal>$y</literal>, <literal>$Y</literal></command></term><indexterm id="indexterm-74"><primary>dcmds</primary><secondary><command>::fpregs</command></secondary></indexterm><indexterm id="indexterm-75"><primary>dcmds</primary><secondary><literal>$x</literal></secondary></indexterm><indexterm id="indexterm-76"><primary>dcmds</primary><secondary><literal>$X</literal></secondary></indexterm><indexterm id="indexterm-77"><primary>dcmds</primary><secondary><literal>$y</literal></secondary></indexterm><indexterm id="indexterm-78"><primary>dcmds</primary><secondary><literal>$Y</literal></secondary></indexterm><listitem><para>Print the floating-point register set of the representative
thread. If a thread is specified, the floating point registers of that thread
are displayed.  The thread expression should be one of the thread identifiers
described under <link linkend="exec-ctrl-11">Thread Support</link>.</para><note><gentext type="text">Note &#8211; </gentext><para>SPARC only.  The <option><gentext type="text">-</gentext>d</option>, <option><gentext type="text">-</gentext>q</option>, and <option><gentext type="text">-</gentext>s</option> options can be used to display the floating point registers as
a collection of double-precision (<option><gentext type="text">-</gentext>d</option>), quad-precision (<option><gentext type="text">-</gentext>q</option>), or single-precision (<option><gentext type="text">-</gentext>s</option>) floating point values.</para></note></listitem></varlistentry><varlistentry><term><command>::grep</command> <replaceable>command</replaceable></term><indexterm id="indexterm-79"><primary>dcmds</primary><secondary><command>::grep</command></secondary></indexterm><listitem><para>Evaluate the specified command
string, then print the old value of dot if the new value of dot is non-zero.
If the <replaceable>command</replaceable> contains white space or metacharacters,
it must be quoted. The <command>::grep</command> dcmd can be used in pipelines
to filter a list of addresses.</para></listitem></varlistentry><varlistentry><term><command>::help</command> [ <replaceable>dcmd-name</replaceable>
]</term><indexterm id="indexterm-80"><primary>dcmds</primary><secondary><command>::help</command></secondary></indexterm><listitem><para>With no arguments,
the <command>::help</command> dcmd prints a brief overview of the help facilities
available in MDB. If a <replaceable>dcmd-name</replaceable> is specified,
MDB prints a usage summary for that dcmd.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::list</command> <replaceable>type member</replaceable> [ <replaceable>variable-name</replaceable> ] </term><listitem><para>Walk through the elements of a linked
list data structure and print the address of each element in the list. The
address of the first element in the list can be specified using an optional <replaceable>address</replaceable>; otherwise the list is assumed to start at the current
value of dot. The <replaceable>type</replaceable> parameter must name a C
struct or union type and is used to describe the type of the list elements
so that MDB can read in objects of the appropriate size. The <replaceable>member</replaceable> parameter is used to name the member of <replaceable>type</replaceable> that contains a pointer to the next list element. The <command>::list</command> dcmd will continue iterating until a NULL pointer is encountered,
the first element is reached again (a circular list), or an error occurs while
reading an element. If the optional <replaceable>variable-name</replaceable>
is specified, the specified variable will be assigned the value returned at
each step of the walk when MDB invokes the next stage of a pipeline.</para><note><gentext type="text">Note &#8211; </gentext><para>This dcmd may only be used with objects that contain compressed
symbolic debugging information designed for use with <literal>mdb</literal>.
This information is currently only available for certain Solaris kernel modules.
The SUNWzlib (32-bit) or SUNWzlibx (64-bit) decompression software must be
installed in order to process the symbolic debugging information. </para></note></listitem></varlistentry><varlistentry><term><command>::load</command> [ <option><gentext type="text">-</gentext>s</option>] <replaceable>module-name</replaceable></term><indexterm id="indexterm-81"><primary>dcmds</primary><secondary><command>::load</command></secondary></indexterm><listitem><para>Load the specified dmod. The module name can be given as an absolute
or relative path. If <replaceable>module-name</replaceable> is a simple name
(that is, does not contain a '<literal>/</literal>'), MDB searches for it
in the module library path. Modules with conflicting names cannot be loaded;
the existing module must be unloaded first. If the <literal>-s</literal> option
is present, MDB will remain silent and not issue any error messages if the
module is not found or could not be loaded.</para></listitem></varlistentry><varlistentry><term><command>::log</command> [ <option><gentext type="text">-</gentext>d</option> | [ <option><gentext type="text">-</gentext>e</option> ] <replaceable>filename</replaceable> ]</term><term><literal>$&gt;</literal> [ <replaceable>filename</replaceable> ]</term><indexterm id="indexterm-82"><primary>dcmds</primary><secondary><command>::log</command></secondary></indexterm><indexterm id="indexterm-83"><primary>dcmds</primary><secondary><literal>$&gt;</literal></secondary></indexterm><listitem><para>Enable or disable the output log. MDB provides
an interactive logging facility where both the input commands and standard
output can be logged to a file while still interacting with the user. The <option><gentext type="text">-</gentext>e</option> option enables logging to the specified file, or re-enables logging
to the previous log file if no file name is given. The <option><gentext type="text">-</gentext>d</option>
option disables logging. If the <literal>$&gt;</literal> dcmd is used, logging
is enabled if a file name argument is specified; otherwise, logging is disabled.
If the specified log file already exists, MDB appends any new log output to
the file.</para></listitem></varlistentry><varlistentry><term><command>::map</command> <replaceable>command</replaceable></term><indexterm id="indexterm-84"><primary>dcmds</primary><secondary><command>::map</command></secondary></indexterm><listitem><para>Map the value of dot to
a corresponding value using the <replaceable>command</replaceable> specified
as a string argument, then print the new value of dot. If the command contains
white space or metacharacters, it must be quoted. The <command>::map</command>
dcmd can be used in pipelines to transform the list of addresses into a new
list of addresses.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::mappings </command> [ <replaceable>name</replaceable> ]</term><term>[ <replaceable> address</replaceable> ] <literal>$m</literal> [ <replaceable>name</replaceable>
]</term><indexterm id="indexterm-85"><primary>dcmds</primary><secondary><command>::mappings</command></secondary></indexterm><indexterm id="indexterm-86"><primary>dcmds</primary><secondary><literal>$m</literal></secondary></indexterm><listitem><para>Print
a list of each mapping in the target's virtual address space, including the
address, size, and description of each mapping. If the dcmd is preceded by
an <replaceable>address</replaceable>, MDB shows only the mapping that contains
the given address. If a string <replaceable>name</replaceable> argument is
given, MDB shows only the mapping that matched the description.</para></listitem></varlistentry><varlistentry><term><command>[<replaceable>address</replaceable>] ::nm</command>
[ <option><gentext type="text">-</gentext>DPdghnopuvx</option> ] [ <option><gentext type="text">-</gentext> t</option> <replaceable>types</replaceable> ] [ <option><gentext type="text">-</gentext> f</option> <replaceable>format</replaceable> ]
[ <replaceable>object</replaceable>]</term><indexterm id="indexterm-87"><primary>dcmds</primary><secondary><command>::nm</command></secondary></indexterm><listitem><para>Print the symbol tables associated with the current target. If an optional <replaceable>address</replaceable> preceding the dcmd is specified, only the symbol table
entry for the symbol corresponding to address is displayed. If an <replaceable>object</replaceable> name is specified, only the symbol table for this load
object is displayed. The <command>::nm</command> dcmd also recognizes the
following options:<variablelist><varlistentry><term><option><gentext type="text">-</gentext>D</option></term><listitem><para>Prints <literal>.dynsym</literal> (dynamic symbol table) instead of <literal>.symtab</literal>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>P</option></term><listitem><para>Prints the private
symbol table instead of <literal>.symtab</literal>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>d</option></term><listitem><para>Prints value
and size fields in decimal.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>f</option> format [,format...]</term><listitem><para>Print only the specified symbol information.  The valid format argument
strings are:</para><variablelist><varlistentry><term>ndx</term><listitem><para>symbol table inde</para></listitem></varlistentry><varlistentry><term>val</term><listitem><para>symbol table</para></listitem></varlistentry><varlistentry><term>size</term><listitem><para>size in bytes</para></listitem></varlistentry><varlistentry><term>type</term><listitem><para>symbol type</para></listitem></varlistentry><varlistentry><term>bind</term><listitem><para>binding</para></listitem></varlistentry><varlistentry><term>oth</term><listitem><para>other</para></listitem></varlistentry><varlistentry><term>shndx</term><listitem><para>section index</para></listitem></varlistentry><varlistentry><term>name</term><listitem><para>symbol name</para></listitem></varlistentry><varlistentry><term>ctype</term><listitem><para>C type for symbol (if known)</para></listitem></varlistentry><varlistentry><term>obj</term><listitem><para>object which defines symbol</para></listitem></varlistentry></variablelist></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>g</option></term><listitem><para>Prints only global
symbols.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>h</option></term><listitem><para>Suppresses the
header line.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>n</option></term><listitem><para>Sorts symbols
by name.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>o</option></term><listitem><para>Prints value
and size fields in octal.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>p</option></term><listitem><para>Prints symbols
as a series of <command>::nmadd</command> commands. This option can be used
with <option><gentext type="text">-</gentext>P</option> to produce a macro file that can be subsequently read
into the debugger with <literal>$&lt;</literal>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>t</option> type [,type...]</term><listitem><para>Prints only symbols of the specified type(s).  The valid type argument strings
are:</para><variablelist><varlistentry><term>noty</term><listitem><para>STT_NOTYPE</para></listitem></varlistentry><varlistentry><term>objt</term><listitem><para>STT_OBJECT</para></listitem></varlistentry><varlistentry><term>func</term><listitem><para>STT_FUNC</para></listitem></varlistentry><varlistentry><term>sect</term><listitem><para>STT_SECTION</para></listitem></varlistentry><varlistentry><term>file</term><listitem><para>STT_FILE</para></listitem></varlistentry><varlistentry><term>comm</term><listitem><para>STT_COMMON</para></listitem></varlistentry><varlistentry><term>tls</term><listitem><para>STT_TLS</para></listitem></varlistentry><varlistentry><term>regi</term><listitem><para>STT_SPARC_REGISTER</para></listitem></varlistentry></variablelist></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>u</option></term><listitem><para>Prints only undefined
symbols.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>v</option></term><listitem><para>Sorts symbols
by value.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>x</option></term><listitem><para>Prints value
and size fields in hexadecimal.</para></listitem></varlistentry></variablelist></para></listitem></varlistentry><varlistentry><term><replaceable>value</replaceable> <command>::nmadd</command>
[ <option><gentext type="text">-</gentext>fo</option> ] [ <option><gentext type="text">-</gentext>e</option> <replaceable>end</replaceable>
] [ <option><gentext type="text">-</gentext>s</option> <replaceable>size</replaceable> ] <replaceable>name </replaceable></term><indexterm id="indexterm-88"><primary>dcmds</primary><secondary><command>::nmadd</command></secondary></indexterm><listitem><para>Add the specified
symbol <replaceable>name</replaceable> to the private symbol table. MDB provides
a private, configurable symbol table that can be used to interpose on the
target's symbol table, as described in <link linkend="syntax-16">Symbol Name Resolution</link>. The <command>::nmadd</command> dcmd also recognizes the following options:<variablelist><varlistentry><term><option><gentext type="text">-</gentext>e</option></term><listitem><para>Set the size
of the symbol to <replaceable>end</replaceable> - <replaceable>value</replaceable>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>f</option></term><listitem><para>Set the type
of the symbol to <literal>STT_FUNC</literal>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>o</option></term><listitem><para>Set the type
of the symbol to <literal>STT_OBJECT</literal>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>s</option></term><listitem><para>Set the size
of the symbol to <replaceable>size</replaceable>.</para></listitem></varlistentry></variablelist></para></listitem></varlistentry><varlistentry><term><command>::nmdel</command> <replaceable>name</replaceable></term><indexterm id="indexterm-89"><primary>dcmds</primary><secondary><command>::nmdel</command></secondary></indexterm><listitem><para>Delete the specified symbol <replaceable>name</replaceable> from the private symbol table.</para></listitem></varlistentry><varlistentry><term><command>::objects</command></term><indexterm id="indexterm-90"><primary>dcmds</primary><secondary><command>::objects</command></secondary></indexterm><listitem><para>Print a map of the target's virtual address space,
showing only those mappings that correspond to the primary mapping (usually
the text section) of each of the known load objects.</para></listitem></varlistentry><varlistentry><term><command>::offsetof</command> <replaceable>type member</replaceable></term><listitem><para>Print the offset of the specified member
of the specified type. The type should be the name of a C structure. The offset
is printed in bytes, unless the member is a bit-field in which case the offset
may be printed in bits. The output is always suffixed with the appropriate
units for clarity. The type name may use the backquote (<literal>`</literal>)
scoping operator described in <link linkend="syntax-16">Symbol Name Resolution</link>.</para><note><gentext type="text">Note &#8211; </gentext><para>This dcmd may only be used with objects that contain compressed
symbolic debugging information designed for use with <literal>mdb</literal>.
This information is currently only available for certain Solaris kernel modules.
The SUNWzlib (32-bit) or SUNWzlibx (64-bit) decompression software must be
installed in order to process the symbolic debugging information. </para></note></listitem></varlistentry><varlistentry><term><command>[<replaceable>address</replaceable>] ::print
[<option><gentext type="text">-</gentext>aCdLptx</option>] [<option><gentext type="text">-</gentext>c</option> <replaceable>lim</replaceable>]
[<option><gentext type="text">-</gentext>l</option> <replaceable>lim</replaceable>] [<replaceable>type</replaceable>
[<replaceable>member</replaceable> ... ] ] </command></term><listitem><para>Print the data structure at the specified virtual <replaceable>address</replaceable>
using the given <replaceable>type</replaceable> information. The <replaceable>type</replaceable> parameter may name a C struct, union, enum, fundamental
integer type, or a pointer to any of these types. If the type name contains
whitespace (for example, "struct foo") it must be enclosed in single or double
quotes. The type name may use the backquote (`) scoping operator described
under <link linkend="syntax-16">Symbol Name Resolution</link>. If the type is a structured type, the <command>::print</command> dcmd will recursively print each member of the struct or
union. If the <replaceable>type</replaceable> argument is not present and
a static or global STT_OBJECT symbol matches the address, <command>::print</command> will infer the appropriate type automatically. If the type argument
is specified, it may be followed by an optional list of <replaceable>member</replaceable> expressions, in which case only those members and submembers
of the specified <replaceable>type</replaceable> are displayed. If <replaceable>type</replaceable> contains other structured types, each <replaceable>member</replaceable> string may refer to a sub-structure element by forming a list
of member names separated by period (‘.') delimiters. The <command>::print</command> dcmd may only be used with objects that contain symbolic
debugging information designed for use with MDB. After displaying the data
structure, <literal>::print</literal> increments dot by the size of <replaceable>type</replaceable> in bytes.</para><note><gentext type="text">Note &#8211; </gentext><para>This dcmd may only be used with objects that contain compressed
symbolic debugging information designed for use with <literal>mdb</literal>.
This information is currently only available for certain Solaris kernel modules.
The SUNWzlib (32-bit) or SUNWzlibx (64-bit) decompression software must be
installed in order to process the symbolic debugging information. </para></note><para>If the <option><gentext type="text">-</gentext>a</option> option is present, the address of each member
is displayed. If the <option><gentext type="text">-</gentext>p</option> option is present, <command>::print</command> interprets address as a physical memory address instead of a virtual
memory address. If the <option><gentext type="text">-</gentext>t</option> option is present, the type of each
member is displayed. If the <option><gentext type="text">-</gentext>d</option> or <option><gentext type="text">-</gentext>x</option> options
are present, all integers are displayed in decimal (<option><gentext type="text">-</gentext>d</option>) or
hexadecimal (<option><gentext type="text">-</gentext>x</option>); by default a heuristic is used to determine
if the value should be displayed in decimal or hexadecimal. The number of
characters in a character array that will be read and displayed as a string
can be limited with the <option><gentext type="text">-</gentext>c</option> option. If the <option><gentext type="text">-</gentext>C</option>
option is present, no limit is enforced. The number of elements in a standard
array that will be read and displayed can be limited with the <option><gentext type="text">-</gentext>l</option>
option. If the <option><gentext type="text">-</gentext>L</option> option is present, no limit is enforced
and all array elements are shown. The default values for <option><gentext type="text">-</gentext>c</option>
and <option><gentext type="text">-</gentext>l</option> can be modified using <literal>::set</literal> or the <option><gentext type="text">-</gentext>o</option> command-line option as described in <link linkend="options-1">Appendix A, Options</link>. </para></listitem></varlistentry><varlistentry><term><command>::quit</command></term><term><command>$q</command></term><indexterm id="indexterm-91"><primary>dcmds</primary><secondary><command>::quit</command></secondary></indexterm><indexterm id="indexterm-92"><primary>dcmds</primary><secondary><command>$q</command></secondary></indexterm><listitem><para>Quit the debugger.</para></listitem></varlistentry><varlistentry><term>[ thread ] <command>::regs</command></term><term>[ thread
] <command>$r</command></term><indexterm id="indexterm-93"><primary>dcmds</primary><secondary><command>::regs</command></secondary></indexterm><indexterm id="indexterm-94"><primary>dcmds</primary><secondary><command>$r</command></secondary></indexterm><listitem><para>Print the general-purpose register set of the representative
thread. If a thread is specified, the general purpose register set of that
thread is displayed.  The thread expression should be one of the thread identifiers
described under <link linkend="exec-ctrl-11">Thread Support</link>.</para></listitem></varlistentry><varlistentry><term><command>::release</command> [ <literal>-a</literal> ] </term><term><command>:R </command> [ <literal>-a</literal> ]</term><indexterm id="indexterm-95"><primary>dcmds</primary><secondary><command>::release</command></secondary></indexterm><indexterm id="indexterm-96"><primary>dcmds</primary><secondary><command>:R</command></secondary></indexterm><listitem><para>Release the previously
attached process or core file. If the <literal>-a</literal> option is present,
the process is released and left stopped and abandoned. It can subsequently
be continued by <literal>prun(1)</literal> or it can be resumed by applying
MDB or another debugger.  By  default, a released process is forcibly terminated
if it was created by MDB using <command>::run</command>, or it is released
and set running if it was attached to by MDB using the <literal>-p</literal>
option or using the <command>::attach</command> or <command>:A dcmds</command>.</para></listitem></varlistentry><varlistentry><term><command>::set</command> [ <option><gentext type="text">-</gentext>wF</option> ] [ +/-<option role="nodash">o</option> <replaceable>option</replaceable> ] [ <option><gentext type="text">-</gentext>s</option> <replaceable>distance</replaceable> ] [ <option><gentext type="text">-</gentext>I</option> <replaceable> path</replaceable>
] [ <option><gentext type="text">-</gentext>L</option> <replaceable>path</replaceable> ] [ <option><gentext type="text">-</gentext>P</option> <replaceable>prompt</replaceable> ]</term><indexterm id="indexterm-97"><primary>dcmds</primary><secondary><command>::set</command></secondary></indexterm><listitem><para>Get or set miscellaneous debugger properties. If no options are specified,
the current set of debugger properties is displayed. The <command>::set</command>
dcmd recognizes the following options:<variablelist><varlistentry><term><option><gentext type="text">-</gentext>F</option></term><listitem><para>Forcibly take
over the next user process that <command>::attach</command> is applied to,
as if <command>mdb</command> had been executed with the <option><gentext type="text">-</gentext>F</option>
option on the command line.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>I</option></term><listitem><para>Set the default
path for locating macro files. The path argument can contain any of the special
tokens described for the <option><gentext type="text">-</gentext>I</option> command-line option in <link linkend="options-1">Appendix A, Options</link>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>L</option></term><listitem><para>Set the default
path for locating debugger modules. The path argument can contain any of the
special tokens described for the <option><gentext type="text">-</gentext>I</option> command-line option in <link linkend="options-1">Appendix A, Options</link>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>o</option></term><listitem><para>Enable the specified
debugger option.  If the <literal>+o</literal> form is used, the option is
disabled.  The option strings are described along with the <option><gentext type="text">-</gentext>o</option>
command-line option in <link linkend="options-1">Appendix A, Options</link>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>P</option></term><listitem><para>Set the command
prompt to the specified prompt string.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>s</option></term><listitem><para>Set the symbol
matching distance to the specified distance. Refer to the description of the <option><gentext type="text">-</gentext>s</option> command-line option in <link linkend="options-1">Appendix A, Options</link> for more information.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>w</option></term><listitem><para>Re-open the target
for writing, as if <command>mdb</command> had been executed with the <option><gentext type="text">-</gentext>w</option> option on the command line.</para></listitem></varlistentry></variablelist></para></listitem></varlistentry><varlistentry><term><command>::sizeof <replaceable>type</replaceable></command></term><listitem><para>Print the size of the specified type in bytes. The <replaceable>type</replaceable> parameter may name a C struct, union, enum, fundamental
integer type, or a pointer to any of these types. The type name may use the
backquote (<literal>`</literal>) scoping operator described in <link linkend="syntax-16">Symbol Name Resolution</link>. </para><note><gentext type="text">Note &#8211; </gentext><para>This dcmd may only be used with objects that contain compressed
symbolic debugging information designed for use with <literal>mdb</literal>.
This information is currently only available for certain Solaris kernel modules.
The SUNWzlib (32-bit) or SUNWzlibx (64-bit) decompression software must be
installed in order to process the symbolic debugging information. </para></note></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::stack</command> [ <replaceable>count</replaceable> ]</term><term>[ <replaceable> address</replaceable> ] <literal>$c</literal> [ <replaceable>count</replaceable>
]</term><indexterm id="indexterm-98"><primary>dcmds</primary><secondary><command>::stack</command></secondary></indexterm><indexterm id="indexterm-99"><primary>dcmds</primary><secondary><literal>$c</literal></secondary></indexterm><listitem><para>Print
a C stack back trace. If the dcmd is preceded by an explicit <replaceable>address</replaceable>, a back trace beginning at this virtual memory address
is displayed. Otherwise, the stack of the representative thread is displayed.
If an optional count value is given as an argument, no more than <replaceable>count</replaceable> arguments are displayed for each stack frame in the output.</para><note arch="sparc" os="solaris64"><gentext type="text">64-bit SPARC only &#8211; </gentext><para>The biased frame pointer value (that
is, the virtual address minus <literal>0x7ff</literal>) should be used as
the address when requesting a stack trace.</para></note><indexterm id="indexterm-100"><primary>stack bias</primary></indexterm></listitem></varlistentry><varlistentry><term><command>::status</command></term><indexterm id="indexterm-101"><primary>dcmds</primary><secondary><command>::status</command></secondary></indexterm><listitem><para>Print a summary of information related to the
current target.</para></listitem></varlistentry><varlistentry><term><replaceable>thread</replaceable> <command>::tls</command> <replaceable>symbol</replaceable></term><listitem><para>Print the address of the storage
for the specified thread-local storage (TLS) symbol in the context of the
specified thread. The thread expression should be one of the thread identifiers
described under <link linkend="exec-ctrl-11">Thread Support</link>. The symbol name may use any
of the scoping operators described under <link linkend="syntax-16">Symbol Name Resolution</link>. </para></listitem></varlistentry><varlistentry><term><command>::typeset</command> [+/-<option role="nodash">t</option>] <replaceable>variable-name</replaceable> ...</term><indexterm id="indexterm-102"><primary>dcmds</primary><secondary><command>::typeset</command></secondary></indexterm><listitem><para>Set attributes for named variables. If one or
more variable names are specified, they are defined and set to the value of
dot. If the <option><gentext type="text">-</gentext>t</option> option is present, the user-defined tag associated
with each variable is set. If the <option role="plus"><gentext type="text">+</gentext>t</option> option is
present, the tag is cleared. If no variable names are specified, the list
of variables and their values is printed.</para></listitem></varlistentry><varlistentry><term><command>::unload</command> <replaceable>module-name</replaceable></term><indexterm id="indexterm-103"><primary>dcmds</primary><secondary><command>::unload</command></secondary></indexterm><listitem><para>Unload the specified dmod.
The list of active dmods can be printed using the <command>::dmods</command>
dcmd. Built-in modules cannot be unloaded. Modules that are busy (that is,
provide dcmds that are currently executing) cannot be unloaded.</para></listitem></varlistentry><varlistentry><term><command>::unset</command> <replaceable>variable-name</replaceable> ...</term><indexterm id="indexterm-104"><primary>dcmds</primary><secondary><command>::unset</command></secondary></indexterm><listitem><para>Unset (remove) the
specified variable(s) from the list of defined variables. Some variables are
exported by MDB are marked as persistent, and cannot be unset by the user.</para></listitem></varlistentry><varlistentry><term><command>::vars</command> [<option><gentext type="text">-</gentext>npt</option>]</term><indexterm id="indexterm-105"><primary>dcmds</primary><secondary><command>::vars</command></secondary></indexterm><listitem><para>Print a listing of named
variables. If the <option><gentext type="text">-</gentext>n</option> option is present, the output is restricted
to variables that currently  have non-zero values. If the <option><gentext type="text">-</gentext>p</option>
option is present, the variables are printed in a form suitable for re-processing
by the debugger using the <command>$&lt;</command> dcmd. This option can be
used to record the variables to a macro file, then restore these values later.
If the <option><gentext type="text">-</gentext>t</option> option is present, only the tagged variables are
printed. Variables can be tagged using the <option><gentext type="text">-</gentext>t</option> option of the <command>::typeset</command> dcmd.</para></listitem></varlistentry><varlistentry><term><command>::version</command></term><listitem><para>Print
the debugger version number.</para><indexterm id="indexterm-106"><primary>dcmds</primary><secondary><command>::version</command></secondary></indexterm></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::vtop [<option><gentext type="text">-</gentext>a</option> <replaceable>as</replaceable>]</command> </term><indexterm id="indexterm-107"><primary>dcmds</primary><secondary><command>::vtop</command></secondary></indexterm><listitem><para>Print the physical address mapping for the specified
virtual address, if possible. The <command>::vtop</command> dcmd is only available
when examining a kernel target, or when examining a user process inside a
kernel crash dump (after a <command>::context</command> dcmd has been issued).</para><para>When examining a kernel target from the kernel  context, the <option><gentext type="text">-</gentext>a</option> option can be used to specify the address (<replaceable>as</replaceable>)
of an  alternate  address  space  structure  that should  be  used  for the
virtual to physical translation. By default, the kernel's address space  is
 used for  translation.  This option is available for active address spaces
even when the dump  content  only  contains kernel pages. </para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::walk</command> <replaceable>walker-name</replaceable> [ <replaceable>variable-name</replaceable> ]</term><indexterm id="indexterm-108"><primary>dcmds</primary><secondary><command>::walk</command></secondary></indexterm><listitem><para>Walk through the elements
of a data structure using the specified walker. The available walkers can
be listed using the <command>::walkers</command> dcmd. Some walkers operate
on a global data structure and do not require a starting address. For example,
walk the list of <structname>proc</structname> structures in the kernel. Other
walkers operate on a specific data structure whose address must be specified
explicitly. For example, given a pointer to an address space, walk the list
of segments. </para><para>When used interactively, the <command>::walk</command> dcmd will print
the address of each element of the data structure in the default base. The
dcmd can also be used to provide a list of addresses for a pipeline. The walker
name can use the backquote “ <literal>`</literal> “ scoping operator
described in <link linkend="syntax-13">dcmd and Walker Name Resolution</link>. If the optional <replaceable>variable-name</replaceable> is specified, the specified variable will be assigned the value
returned at each step of the walk when MDB invokes the next stage of the pipeline.</para></listitem></varlistentry><varlistentry><term><command>::walkers</command></term><indexterm id="indexterm-109"><primary>dcmds</primary><secondary><command>::walkers</command></secondary></indexterm><listitem><para>List the available walkers and print a brief description
for each one.</para></listitem></varlistentry><varlistentry><term><command>::whence</command> [<option><gentext type="text">-</gentext>v</option>] <replaceable>name</replaceable> ...</term><term><command>::which</command> [<option><gentext type="text">-</gentext>v</option>] <replaceable>name</replaceable> ...</term><indexterm id="indexterm-110"><primary>dcmds</primary><secondary><command>::whence</command></secondary></indexterm><indexterm id="indexterm-111"><primary>dcmds</primary><secondary><command>::which</command></secondary></indexterm><listitem><para>Print the dmod that exports the specified dcmds
and walkers. These dcmds can be used to determine which dmod is currently
providing the global definition of the given dcmd or walker. Refer to <link linkend="syntax-13">dcmd and Walker Name Resolution</link> for more information on global name resolution. The <option><gentext type="text">-</gentext>v</option> option causes the dcmd to print the alternate definitions of each
dcmd and walker in order of precedence.</para></listitem></varlistentry><varlistentry><term><command>::xdata</command></term><indexterm id="indexterm-112"><primary>dcmds</primary><secondary><command>::xdata</command></secondary></indexterm><listitem><para>List the external data buffers exported by the
current target. External data buffers represent information associated with
the target that cannot be accessed through standard target facilities (that
is, an address space, symbol table, or register set). These buffers can be
consumed by dcmds; for more information, refer to <link linkend="api-52"><function>mdb_get_xdata()</function></link>.</para></listitem></varlistentry></variablelist></sect1></chapter><chapter id="exec-ctrl-7"><gentext type="text">Chapter 6</gentext><gentext type="toc">6.&#160;&#160;Execution Control</gentext><title>Execution Control</title><para>MDB provides facilities for controlling and tracing the execution of
a live running program. Currently, only the user process target provides support
for execution control. This chapter describes the built-in dcmds that can
be used to control target execution.</para><sect1 id="exec-ctrl-9"><title>Execution Control</title><para>MDB provides a simple model of execution control: a target process can
be started from within the debugger using <command>::run</command>, or MDB
can attach to an existing process using <command>:A</command>, <command>::attach</command>, or the <literal>-p</literal> command-line option (see <link linkend="commands-1">Chapter 5, Built-in Commands</link>).
A list of traced <emphasis>software events</emphasis> can be specified by
the user. Each time a traced event occurs in the target process, all threads
in the target stop, the thread that triggered the event is chosen as the representative
thread, and control returns to the debugger. Once the target program is set
running, control can be asynchronously returned to the debugger by typing
the user-defined interrupt character (typically ^C).</para><para>A <emphasis>software event</emphasis> is a state transition in the target
program that is observed by the debugger. For example, the debugger may observe
the transition of a program counter register to a value of interest (a breakpoint)
or the delivery of a particular signal.</para><para>A <emphasis>software event specifier</emphasis> is a description of
a class of software events that is used by the debugger to instrument the
target program in order to observe these events.  The <literal>::events</literal>
dcmd is used to list the software event specifiers.  A set of standard properties
is associated with each event specifier, as described under <command>::events</command> in <link linkend="execctrl-1">Built-in dcmds</link>.</para><para>The debugger can observe a variety of different software events, including
breakpoints, watchpoints, signals, machine faults, and system calls.  New
specifiers can be created using <command>::bp</command>, <command>::fltbp</command>, <command>:: sigbp</command>, <command>::sysbp</command>, or <command>::wp</command>. Each specifier has an associated callback (an MDB command
string to execute as if it had been typed at the command prompt) and a set
of properties, as described under <command>::events</command> in <link linkend="execctrl-1">Built-in dcmds</link>.
Any number of specifiers for the same event may be created, each with different
callbacks and properties. The current list of traced events and the properties
of the corresponding event specifiers can be displayed using the <command>::events</command> dcmd.  The event specifier properties are defined as part
of the description of the <command>::events</command> and <command>::evset</command> dcmds, in <link linkend="execctrl-1">Built-in dcmds</link>.</para><para>The execution control built-in dcmds, described in <link linkend="execctrl-1">Built-in dcmds</link>,
are always available, but will issue an error message indicating they are
not supported if applied to a target that does not support execution control.</para></sect1><sect1 id="exec-ctrl-10"><title>Event Callbacks</title><para>The <command>::evset</command> dcmd and event tracing dcmds allow you
to associate an event callback (using the <literal>-c</literal> option) with
each event specifier. The event callbacks are strings that represent MDB commands
to execute when the corresponding event occurs in the target.  These commands
are executed as if they had been typed at the command prompt. Prior to executing
each callback, the <emphasis>dot</emphasis> variable is set to the value of
the representative thread's program counter and the <emphasis>hits</emphasis>
variable is set to the number of times this specifier has been matched, including
the current match.</para><para>If the event callbacks themselves contain one or more  commands to continue
the target (for example, <command>::cont</command> or <command>::step</command>),
these commands do <emphasis>not</emphasis> immediately continue the target
and wait for it to stop again.  Instead, inside of an event callback, the
continue dcmds note that a continue operation is now pending, and then return
immediately. Therefore, if multiple dcmds are included in an event callback,
the step or continue dcmd should be the last command specified. Following
the execution of <emphasis>all</emphasis> event callbacks, the target will
immediately resume execution if <emphasis>all</emphasis> matching event callbacks
requested a continue. If conflicting continue operations are requested, the
operation with the highest precedence determines what type of continue will
occur. The order of precedence from highest to lowest is: step, step-over
(next), step-out, continue.</para></sect1><sect1 id="exec-ctrl-11"><title>Thread Support</title><para>MDB provides facilities to examine the stacks and registers of each
thread associated with the target. The persistent "thread" variable contains
the current representative thread identifier. The format of the thread identifier
depends on the target. The <command>::regs</command> and <command>::fpregs</command> dcmds  can be used to examine the register set of the representative
thread, or of another thread if its register set is currently available. In
addition, the register set of the representative thread is exported as a set
of named variables.  The user can modify the value of one or more registers
by applying the <literal>&gt;</literal> dcmd to the corresponding named variable.</para><para>The MDB kernel target exports the virtual address of the corresponding
internal thread structure as the identifier for a given thread.</para><para>The MDB process target provides proper support for examination of multi-threaded
user processes that use the native <literal>lwp_*</literal> interfaces, <filename>/usr/lib/libthread.so</filename>, or <filename>/usr/lib/libpthread.so</filename>.
When debugging a live user process, MDB will detect if a single threaded process
dlopens or closes <filename>libthread</filename> and will automatically adjust
its view of the threading model on-the-fly.  The process target thread identifiers
will correspond to either the <literal>lwpid_t</literal>, <literal>thread_t</literal>, or <literal>pthread_t</literal> of the representative, depending
on the threading model used by the application.</para><para>If MDB is debugging a user process target and the target makes use of
compiler-supported thread-local storage, MDB will automatically evaluate symbol
names referring to thread-local storage to the address of the storage corresponding
to the current representative thread. The <command>::tls</command> built-in
dcmd can be used to display the value of the symbol for threads other than
the representative thread. </para></sect1><sect1 id="execctrl-1"><title>Built-in dcmds</title><variablelist termlength="wholeline"><varlistentry><term>[ <replaceable>addr</replaceable> ] <command>::bp</command>
[+/-dDestT] [<option><gentext type="text">-</gentext>c</option> <replaceable>cmd</replaceable>] [<option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable>] <replaceable>sym</replaceable>
...</term><term><replaceable>addr</replaceable> <command>:b</command> [<replaceable>cmd</replaceable> ... ]</term><listitem><para>Set a breakpoint at the specified
locations.  The <command>::bp</command> dcmd sets a breakpoint at each address
or symbol specified, including an optional address specified by an explicit
expression preceding the dcmd, and each string or immediate value following
the dcmd. The arguments may either be symbol names or immediate values denoting
a particular virtual address of interest. If a symbol name is specified, it
may refer to a symbol that cannot yet be evaluated in the target process:
that is, it may consist of an object name and function name in a load object
that has not yet been opened.  In this case, the breakpoint is deferred and
it will not be active in the target until an object matching the given name
is loaded. The breakpoint will be automatically enabled when the load object
is opened. Breakpoints on symbols defined in a shared library should always
be set using a symbol name and not using an address expression, as the address
may refer to the corresponding Procedure Linkage Table (PLT) entry instead
of the actual symbol definition. Breakpoints set on PLT entries may be overwritten
by the run-time link-editor when the PLT entry is subsequently resolved to
the actual           symbol definition. The <option><gentext type="text">-</gentext>d</option>, <option><gentext type="text">-</gentext>D</option>, <option><gentext type="text">-</gentext>e</option>, <option><gentext type="text">-</gentext>s</option>, <option><gentext type="text">-</gentext>t</option>, <option><gentext type="text">-</gentext>T</option>, <option><gentext type="text">-</gentext>c</option>, and <option><gentext type="text">-</gentext>n</option> options have the same
meaning as they do for the <command>::evset</command> dcmd, as described later
in this section. If the <command>:b</command> form of the  dcmd is used, a
breakpoint is only set at the virtual address specified by the expression
preceding the dcmd.  The arguments following the <command>:b</command> dcmd
are concatenated together to form the callback string.  If this string contains
meta-characters, it must be quoted.</para></listitem></varlistentry><varlistentry><term><command>::cont</command> [<replaceable>SIG</replaceable>]</term><term><command>:c</command> [<replaceable>SIG</replaceable>]</term><listitem><para>Suspend the debugger, continue the target program, and wait
for it to terminate or stop following a software event of interest. If the
target is already running because the debugger was attached to a running program
with the <literal>-o nostop</literal> option enabled, this dcmd simply waits
for the target to terminate or stop after an event of interest. If an optional
signal name or number (see the signal (3HEAD) man page) is specified as an
argument, the signal is immediately delivered to the target as part of resuming
its execution. If the SIGINT signal is traced, control may be asynchronously
returned to the debugger by typing the user-defined interrupt character (usually
^C).  This SIGINT signal will be automatically cleared and will not be observed
by the target the next time it is continued.  If no target program is currently
running, <command>::cont</command> will start a new program running  as if
by <command>::run</command>.</para></listitem></varlistentry><varlistentry><term><replaceable>addr</replaceable> <command>::delete</command>
[<replaceable>id</replaceable> | <literal>all</literal>]</term><term><replaceable>addr</replaceable> <command>:d</command> [<replaceable>id</replaceable> | <literal>all</literal>]</term><listitem><para>Delete the event specifiers with the
given id number. The <replaceable>id </replaceable> number argument is interpreted
in decimal by default.  If an optional address is specified preceding the
dcmd, all event specifiers that are associated with the given virtual address
are deleted (e.g. all breakpoints or watchpoints affecting that address).
 If the special argument "<literal>all</literal>" is given, all event specifiers
are deleted, except those that are marked sticky (T flag).  The <command>::events</command> dcmd displays the current list of event specifiers.</para></listitem></varlistentry><varlistentry><term><literal>::events</literal> [<option><gentext type="text">-</gentext>av</option>]</term><term><command>$b</command> [<option><gentext type="text">-</gentext>av</option>]</term><listitem><para>Display
the list of software event specifiers.  Each event specifier is assigned a
unique ID number that can be used to delete or modify it at a later time.
The debugger may also have its own internal events enabled for tracing; these
will only be displayed if the <option><gentext type="text">-</gentext>a</option> option is present.  If the <option><gentext type="text">-</gentext>v</option> option is present, a more verbose display including the reason
for any specifier inactivity will be shown. The following <command>::events</command> dcmd shows example output:</para><programlisting format="linespecific">&gt; ::events
   ID S TA HT LM Description                              Action
----- - -- -- -- ---------------------------------------- -------------
[ 1 ] - T   1  0 stop on SIGINT                           -      
[ 2 ] - T   0  0 stop on SIGQUIT                          -
[ 3 ] - T   0  0 stop on SIGILL                           -
 ...
[ 11] - T   0  0 stop on SIGXCPU                          -
[ 12] - T   0  0 stop on SIGXFSZ                          -
[ 13] -     2  0 stop at libc`printf                      ::echo printf
&gt;</programlisting><para>The following discussion explains the meaning of each column. A summary
of this information is available using <command>::help events</command>.</para><variablelist><varlistentry><term>ID</term><listitem><para>The event specifier identifier.
The identifier will be shown in square brackets [ ] if the specifier is enabled,
in parentheses ( ) if the specifier is disabled, or in angle brackets &lt;
&gt; if the target program is currently stopped on an event that matches the
given specifier.</para></listitem></varlistentry><varlistentry><term>S</term><listitem><para>The event specifier state.  The
state will be one of the following symbols:</para><informaltable frame="topbot"><tgroup cols="2" colsep="1" rowsep="1"><colspec colwidth="5.30*"/><colspec colwidth="94.70*"/><tbody><row><entry><para>-</para></entry><entry><para>The event specifier is idle.
 When no target program is running, all specifiers are idle. When the target
program is running, a specifier may be idle if it cannot be evaluated (such
as a deferred breakpoint in a shared object that is not yet loaded).</para></entry></row><row><entry><para>+</para></entry><entry><para>The event specifier is active.
When the target is continued, events of this type will be detected by the
debugger.</para></entry></row><row><entry><para>*</para></entry><entry><para>The event specifier is armed.
This state means that the target is currently running with instrumentation
for this type of event. This state is only visible if the debugger is attached
to a running program with the<option><gentext type="text">-</gentext>o nostop</option> option.</para></entry></row><row><entry><para>!</para></entry><entry><para>The event specifier was not
armed due to an operating system                   error.  The <command>::events</command> <literal>-v</literal> option can be used to display more information
about the reason the instrumentation failed.</para></entry></row></tbody></tgroup></informaltable></listitem></varlistentry><varlistentry><term>TA</term><listitem><para>The Temporary, Sticky, and Automatic
event specifier properties. One or more of the following symbols may be shown:</para><informaltable frame="topbot"><tgroup cols="2" colsep="1" rowsep="1"><colspec colwidth="5.56*"/><colspec colwidth="94.44*"/><tbody><row><entry><para>t</para></entry><entry><para>The event specifier is temporary,
and will be deleted the next time the target stops, regardless of whether
it is matched.</para></entry></row><row><entry><para>T</para></entry><entry><para>The event specifier is sticky,
and will be not be deleted by <command>::delete</command> <literal>all</literal>
or <command>:z</command>. The specifier can be deleted by explicitly specifying
its id number to<command>::delete</command>.</para></entry></row><row><entry><para>d</para></entry><entry><para>The event specifier will be
automatically disabled when the hit count is equal to the hit limit.</para></entry></row><row><entry><para>D</para></entry><entry><para>The event specifier will be
automatically deleted when the hit count is equal to the hit limit.</para></entry></row><row><entry><para>s</para></entry><entry><para>The target will automatically
stop when the hit count is equal to the hit limit.</para></entry></row></tbody></tgroup></informaltable></listitem></varlistentry><varlistentry><term>HT</term><listitem><para>The current hit count.  This
column displays the number of times the corresponding software event has occurred
in the target since the creation of this event specifier.</para></listitem></varlistentry><varlistentry><term>LM</term><listitem><para>The current hit limit. This column
displays the limit on the hit count at which the auto-disable, auto-delete,
or auto-stop behavior will take effect. These behaviors can be configured
               using the <command>::evset</command> dcmd.</para></listitem></varlistentry><varlistentry><term>Description</term><listitem><para>A description of the
type of software event that is matched by the given specifier.</para></listitem></varlistentry><varlistentry><term>Action</term><listitem><para>The callback string to execute
when the corresponding software event occurs. This callback is executed as
if it had been typed at the command prompt.</para></listitem></varlistentry></variablelist></listitem></varlistentry><varlistentry><term><replaceable>id</replaceable> <command>::evset</command>
[+/-dDestT] [<option><gentext type="text">-</gentext>c</option> <replaceable>cmd</replaceable>] [<option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable>] <replaceable>id</replaceable>
...</term><listitem><para>Modify the properties of one or more software event
specifiers. The properties are set for each specifier identified by the optional
expression preceding the dcmd and an optional list of arguments following
the dcmd. The argument list is interpreted as a list of decimal integers,
unless an explicit radix is specified. The <command>::evset</command> dcmd
recognizes the following options:</para><variablelist><varlistentry><term><option><gentext type="text">-</gentext>d</option></term><listitem><para>Disable the event
specifier when the hit count reaches the hit limit. If the <literal>+d</literal>
form of the option is given, this behavior is disabled. Once an event specifier
is disabled, the debugger will remove any corresponding instrumentation and
will ignore the corresponding software events until the specifier is subsequently
re-enabled.  If the <option><gentext type="text">-</gentext>n</option> option is not present, the specifier
is disabled immediately.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>D</option></term><listitem><para>Delete the event
specifier when the hit count reaches the hit limit. If the <literal>+D</literal>
form of the option is given, this behavior is disabled. The <option><gentext type="text">-</gentext>D</option>
option takes precedence over the <option><gentext type="text">-</gentext>d</option> option. The hit limit
can be configured using the <option><gentext type="text">-</gentext>n</option> option.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>e</option></term><listitem><para>Enable the event
specifier. If the <literal>+e</literal> form of the option is given, the specifier
is disabled.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>s</option></term><listitem><para>Stop the target
program when the hit count reaches the hit limit. If the <literal>+s</literal>
form of the option is given, this behavior is disabled.  The <option><gentext type="text">-</gentext>s</option>
behavior tells the debugger to act as if <command>::cont</command> were issued
following each execution of the specifier's callback, except for the Nth execution,
where N is the current value of the specifier's hit limit. The <option><gentext type="text">-</gentext>s</option>
option takes precedence over both the <option><gentext type="text">-</gentext>D</option> option and the <option><gentext type="text">-</gentext>d</option> option.</para></listitem></varlistentry><varlistentry><term><literal>-t</literal></term><listitem><para>Mark the event
specifier as temporary. Temporary specifiers are automatically deleted the
next time the target stops, regardless of whether it stopped as the result
of a software event corresponding to the given specifier. If the <literal>+t</literal> form of the option is given, the temporary marker is removed.
 The <literal>-t</literal> option takes precedence over the <literal>-T</literal>
option.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>T</option></term><listitem><para>Mark the event
specifier as sticky.  Sticky specifiers will not be deleted by <command>::delete
all</command> or <command>:z</command>. They can be deleted by specifying
the corresponding specifier ID as an explicit argument to <command>::delete</command>. If the <literal>+T</literal> form of the option is given, the
sticky property is removed. The default set of event specifiers are all initially
marked sticky.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>c</option></term><listitem><para>Execute the specified <replaceable>cmd</replaceable> string each time the corresponding software event occurs
in the target program. The current callback string can be displayed using <command>::events</command>.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>n</option></term><listitem><para>Set the current
value of the hit limit to <replaceable>count</replaceable>. If no hit limit
is currently set and the <option><gentext type="text">-</gentext>n</option> option does not accompany <option><gentext type="text">-</gentext>s</option> or <option><gentext type="text">-</gentext>D</option>, the hit limit will be set to one.</para></listitem></varlistentry></variablelist><para>A summary of this information is available using <command>::help evset</command>.</para></listitem></varlistentry><varlistentry><term><replaceable>flt</replaceable> <command>::fltbp</command>
[+/-dDestT] [<option><gentext type="text">-</gentext>c</option> <replaceable>cmd</replaceable>] [<option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable>] <replaceable>flt</replaceable>
...</term><listitem><para>Trace the specified machine faults. The faults are
identified using an optional fault number preceding the dcmd, or a list of
fault names or numbers (see <filename>&lt;sys/fault.h&gt;</filename>) following
the dcmd. The <option><gentext type="text">-</gentext>d</option>, <option><gentext type="text">-</gentext>D</option>, <option><gentext type="text">-</gentext>e</option>, <option><gentext type="text">-</gentext>s</option>, <option><gentext type="text">-</gentext>t</option>, <option><gentext type="text">-</gentext>T</option>, <option><gentext type="text">-</gentext>c</option>, and <option><gentext type="text">-</gentext>n</option> options have the same meaning as they do for the <command>::evset</command> dcmd.</para></listitem></varlistentry><varlistentry><term><replaceable>signal</replaceable> <command>:i</command></term><listitem><para>If the target is a live user process, ignore the specified
signal and allow it to be delivered transparently to the target. All event
specifiers that are tracing delivery of the specified signal will be deleted
from the list of traced events. By default, the set of ignored signals is
initialized to the complement of the set of signals that cause a process to
dump core by default (see the signal(3HEAD) man page), except for SIGINT,
which is traced by default.</para></listitem></varlistentry><varlistentry><term><command>$i</command></term><listitem><para>Display the
list of signals that are ignored by the debugger and will be handled directly
by the target. More information on traced signals can be obtained using the <command>::events</command> dcmd.</para></listitem></varlistentry><varlistentry><term><command>::kill</command></term><term><command>:k</command></term><listitem><para>Forcibly terminate the target if it is a live user process.
The target will also be forcibly terminated when the debugger exits if it
was created by the debugger using <command>::run</command>.</para></listitem></varlistentry><varlistentry><term><command>$l</command></term><listitem><para>Print the
LWPID of the representative thread, if the target is a user process.</para></listitem></varlistentry><varlistentry><term><command>$L</command></term><listitem><para>Print the
LWPIDs of each LWP in the target, if the target is a user process.</para></listitem></varlistentry><varlistentry><term><command>::next</command> [<replaceable>SIG</replaceable>]</term><term><command>:e</command> [<replaceable>SIG</replaceable>]</term><listitem><para>Step the target program one instruction, but step over subroutine
calls. If an optional signal name or number (see signal(3HEAD) man page) is
specified as an argument, the signal is immediately delivered to the target
as part of resuming its execution. If no target program is currently running, <command>::next</command> will start a new program running as if by <command>::run</command> and stop at the first instruction.</para></listitem></varlistentry><varlistentry><term><command>::run</command> [<replaceable>args</replaceable>
... ]</term><term><command>:r</command> [<replaceable>args</replaceable> ...
]</term><listitem><para>Start a new target program running with the specified
arguments and attach to it. The arguments are not interpreted by the shell.
If the debugger is already examining a live running program, it will first
detach from this program as if by <command>::release</command>.</para></listitem></varlistentry><varlistentry><term>[<replaceable>signal</replaceable>] <command>::sigbp</command>
[+/-dDestT] [<option><gentext type="text">-</gentext>c</option> <replaceable>cmd</replaceable>] [<option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable>] <replaceable>SIG</replaceable>
...</term><term>[<replaceable>signal</replaceable>] <command>:t</command>
[+/<option><gentext type="text">-</gentext>dDestT</option>] [<option><gentext type="text">-</gentext>c</option> <replaceable>cmd</replaceable>]
[<option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable>] <replaceable>SIG</replaceable>
...</term><listitem><para>Trace delivery of the specified signals.  The signals
are identified using an optional signal number preceding the dcmd, or a list
of signal names or numbers (see signal(3HEAD)) following the dcmd.  The <option><gentext type="text">-</gentext>d</option>, <option><gentext type="text">-</gentext>D</option>, <option><gentext type="text">-</gentext>e</option>, <option><gentext type="text">-</gentext>s</option>, <option><gentext type="text">-</gentext>t</option>, <option><gentext type="text">-</gentext>T</option>, <option><gentext type="text">-</gentext>c</option>, and <option><gentext type="text">-</gentext>n</option>
options have the same meaning as they do for the <command>::evset</command>
dcmd.  Initially, the set of signals that cause the process to dump core by
default (see signal(3HEAD)) and SIGINT are traced.</para></listitem></varlistentry><varlistentry><term><command>::step</command> [over | out] [<replaceable>SIG</replaceable>]</term><term><command>:s</command> <replaceable>SIG</replaceable></term><term><command>:u</command> <replaceable>SIG</replaceable></term><listitem><para>Step the target program one instruction. If an optional signal name
or number (see the signal(3HEAD) man page) is specified as an argument, the
signal is immediately delivered to the target as part of resuming its execution.
If the optional "over" argument is specified, <command>::step</command> will
step over subroutine calls.  The <command>::step over</command> argument is
the same as the <command>::next</command> dcmd. If the optional "out" argument
is specified, the target program will continue until the representative thread
returns from the current function. If no target program is currently running, <command>::step over</command> will start a new program running as if by <command>::run</command> and stop at the first instruction. The <command>:s</command>
dcmd is the same as <command>::step</command>. The <command>:u</command> dcmd
is the same as <command>::step out</command>.</para></listitem></varlistentry><varlistentry><term>[<replaceable>syscall</replaceable>] <command>::sysbp</command> [+/<option><gentext type="text">-</gentext>dDestT</option>] [<option><gentext type="text">-</gentext>io</option>] [<option><gentext type="text">-</gentext>c</option> <replaceable>cmd</replaceable>] [<option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable>] <replaceable>syscall</replaceable> ...</term><listitem><para>Trace entry to or exit from
the specified system calls.  The system calls are identified using an optional
system call number preceding the dcmd, or a list of system call names or numbers
(see <filename>&lt;sys/syscall.h&gt;</filename>) following the dcmd.  If the <option><gentext type="text">-</gentext>i</option> option is specified (the default), the event specifiers trigger
on entry into the kernel for each system call.  If the <option><gentext type="text">-</gentext>o</option>
option is specified, the event specifiers trigger on exit out from the kernel.
The <option><gentext type="text">-</gentext>d</option>, <option><gentext type="text">-</gentext>D</option>, <option><gentext type="text">-</gentext>e</option>, <option><gentext type="text">-</gentext>s</option>, <option><gentext type="text">-</gentext>t</option>, <option><gentext type="text">-</gentext>T</option>, <option><gentext type="text">-</gentext>c</option>, and <option><gentext type="text">-</gentext>n</option> options have the same meaning as they do for the <command>::evset</command> dcmd.</para></listitem></varlistentry><varlistentry><term><replaceable>addr</replaceable> [,<replaceable>len</replaceable>]<command>::wp</command> [+/<option><gentext type="text">-</gentext>dDestT</option>] [<option><gentext type="text">-</gentext>rwx</option>] [<option><gentext type="text">-</gentext>c</option> <replaceable>cmd</replaceable>] [<option><gentext type="text">-</gentext>n</option> <replaceable>count</replaceable>]</term><term><replaceable>addr</replaceable> [,<replaceable>len</replaceable>]<command>:a</command> [<replaceable>cmd</replaceable>...
]</term><term><replaceable>addr</replaceable> [,<replaceable>len</replaceable>]<command>:w</command> [<replaceable>cmd</replaceable>... ]</term><term></term><listitem><para>Set a watchpoint at the specified address. The length in bytes of the
watched region may be set by specifying an optional repeat count preceding
the dcmd. If no length is explicitly set, the default is one byte. The <command>::wp</command> dcmd allows the watchpoint to be configured to trigger on any
combination of read (<option><gentext type="text">-</gentext>r</option> option), write (<option><gentext type="text">-</gentext>w</option>
option), or execute (<option><gentext type="text">-</gentext>x</option> option) access.  The <option><gentext type="text">-</gentext>d</option>, <option><gentext type="text">-</gentext>D</option>, <option><gentext type="text">-</gentext>e</option>, <option><gentext type="text">-</gentext>s</option>, <option><gentext type="text">-</gentext>t</option>, <option><gentext type="text">-</gentext>T</option>, <option><gentext type="text">-</gentext>c</option>, and <option><gentext type="text">-</gentext>n</option> options have the same
meaning as they do for the <command>::evset</command> dcmd. The <command>:a</command> dcmd sets a read access watchpoint at the specified address.
The <command>:p</command> dcmd sets an execute access watchpoint at the specified
address.  The <command>:w</command> dcmd sets a write access watchpoint at
the specified address.  The arguments following the <command>:a</command>. <command>:p</command>, and <command>:w</command> dcmds are concatenated together to
form the callback string.  If this string contains meta-characters, it must
be quoted.</para></listitem></varlistentry><varlistentry><term><command>:z</command></term><listitem><para>Delete all
event specifiers from the list of traced software events. Event specifiers
can also be deleted using <command>::delete</command>.</para></listitem></varlistentry></variablelist></sect1><sect1 id="exec-ctrl-12"><title>Interaction With <command>exec</command></title><para>When a controlled process performs a successful <command>exec</command>(2),
the behavior of the debugger is controlled by the <literal>::set -o follow_exec_mode</literal> option, as described in <link linkend="options-2">Summary of Command-line Options</link>. If the debugger
and victim process have the same data model, then the "stop" and "follow"
modes determine whether MDB automatically continues the target or returns
to the debugger prompt following the <command>exec</command>. If the debugger
and victim process have a different data model, then the "follow" behavior
causes MDB to automatically re-exec the MDB binary with the appropriate data
model and re-attach to the process, still stopped on return from the <command>exec</command>.  Not all debugger state is preserved across this re-exec. </para><para>If a 32-bit victim process <command>exec</command>s a 64-bit program,
then "stop" will return to the command prompt, but the debugger will no longer
be able to examine the process because it is now using the 64-bit data model.
To resume debugging, execute the<command> ::release -a</command> dcmd, quit
MDB, and then execute <command>mdb -p</command> <replaceable>pid</replaceable>
to re-attach the 64-bit debugger to the process. </para><para>If a 64-bit victim process execs a 32-bit program, then "stop" will
return to the command prompt, but the debugger will only provide limited capabilities
for examining the new process.  All built-in dcmds will work as advertised,
but loadable dcmds will not since they do not perform data model conversion
of structures.  The user should release and reattach the debugger to the process
as described above in order to restore full debugging capabilities.</para></sect1><sect1 id="exec-ctrl-13"><title>Interaction with Job Control</title><para> If the debugger is attached to a process that is stopped by job control
(that is, it stopped in response to SIGTSTP, SIGTTIN, or SIGTTOU), the process
may not be able to be set running again when it is continued by a continue
dcmd.  If the victim process is a member of the same session (that is, it
shares the same controlling terminal as MDB), MDB will attempt to bring the
associated process group to the foreground and continue the process with SIGCONT
to resume it from job control stop.  When MDB is detached from such a process,
it will restore the process group to the background before exiting. If the
victim process is not a member of the same session, MDB cannot safely bring
the process group to the foreground, so it will continue the process with
respect to the debugger but the process will remain stopped by job control.
MDB will print a warning in this case, and the user must issue a <command>fg</command> command from the appropriate shell in order to resume the process.</para></sect1><sect1 id="exec-ctrl-14"><title>Process Attach and Release</title><para>When MDB attaches to a running process, the process is stopped and remains
stopped until one of the continue dcmds is applied, or the debugger quits.
 If the <literal>-o nostop</literal> option is enabled prior to attaching
the debugger to a process with <literal>-p</literal> or prior to issuing an <command>::attach</command> or <command>:A</command> command, MDB will attach to the
process but not stop it. While the process is still running, it may be inspected
as usual (albeit with inconsistent results) and breakpoints or other tracing
flags may be enabled.  If the <command>:c</command> or <command>::cont</command>
dcmds are executed while the process is running, the debugger will wait for
the process to stop. If no traced software events occur, the user can send
an interrupt (^C) after <command>:c</command> or <command>::cont</command>
to force the process to stop and return control to the debugger. </para><para>MDB releases the current running process (if any) when the <command>:R</command>, <command>::release</command>, <command>:r</command>, <command>::run</command>, <command>$q</command>, or <command>::quit</command> dcmds
are executed, or when the debugger terminates as the result of an EOF or signal.
If the process was originally created by the debugger using <command>:r</command>
or <command>::run</command>, it will be forcibly terminated as if by SIGKILL
when it is released.  If the process was already running prior to attaching
MDB to it, it will be set running again when it is released. A process may
be released and left stopped and abandoned using the <command>::release -a</command> option.</para></sect1></chapter><chapter id="modules-1"><gentext type="text">Chapter 7</gentext><gentext type="toc">7.&#160;&#160;Kernel Debugging Modules</gentext><title>Kernel Debugging Modules</title><indexterm id="indexterm-113"><primary>Kernel Debugging Modules</primary></indexterm><highlights><para>This chapter describes the debugger modules, dcmds, and
walkers provided to debug the Solaris kernel.  Each kernel debugger module
is named after the corresponding Solaris kernel module, so that it will be
loaded automatically by MDB.  The facilities described here reflect the current
Solaris kernel implementation and are subject to change in the future; writing
shell scripts that depend on the output of these commands is not recommended.
 In general, the kernel debugging facilities described in this chapter are
meaningful only in the context of the corresponding kernel subsystem implementation.
 See <link linkend="preface-5">Related Books and Papers</link> for a list of references that provide more
information about the Solaris kernel implementation.</para><note><gentext type="text">Note &#8211; </gentext><para>This guide reflects the Solaris 9 operating environment implementation;
these modules, dcmds, and walkers may not be relevant, correct, or applicable
to past or future releases, since they reflect the current kernel implementation.
 They do not define a permanent public interface of any kind.  All of the
information provided about modules, dcmds, walkers, and their output formats
and arguments is subject to change in future releases of the Solaris operating
environment.</para></note></highlights><sect1 id="modules-22"><title>Generic Kernel Debugging Support (<literal>genunix</literal>)</title><sect2 id="modules-24"><title>Kernel Memory Allocator</title><para>This section discusses the dcmds and walkers used to debug problems
identified by the Solaris kernel memory allocator and to examine memory and
memory usage. The dcmds and walkers described here are discussed in more detail
in <link linkend="kmem-1">Chapter 8, Debugging With the Kernel Memory Allocator</link>.</para><sect3 id="modules-25"><title>dcmds</title><variablelist termlength="wholeline"><varlistentry><term><replaceable>thread</replaceable> <command>::allocdby</command></term><indexterm id="indexterm-114"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::allocdby</command></tertiary></indexterm><indexterm id="indexterm-115"><primary>dcmds</primary><secondary><command>::allocdby</command></secondary></indexterm><listitem><para>Given the address
of a kernel thread, print a list of memory allocations it has performed in
reverse chronological order. </para></listitem></varlistentry><varlistentry><term><replaceable>bufctl</replaceable> <command>::bufctl</command>
[<option><gentext type="text">-</gentext>a</option> <replaceable>address</replaceable>] [<option><gentext type="text">-</gentext>c</option> <replaceable>caller</replaceable>] [<option><gentext type="text">-</gentext>e</option> <replaceable>earliest</replaceable>]
[<option><gentext type="text">-</gentext>l</option> <replaceable>latest</replaceable>] [<option><gentext type="text">-</gentext>t</option> <replaceable>thread</replaceable>]</term><listitem><para><indexterm id="indexterm-116"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::bufctl</command></tertiary></indexterm><indexterm id="indexterm-117"><primary>dcmds</primary><secondary><command>::bufctl</command></secondary></indexterm>Print
a summary of the <replaceable>bufctl</replaceable> information for the specified
bufctl <replaceable>address</replaceable>.  If one or more options are present,
the bufctl information  is printed only if it matches the criteria defined
by the option arguments; in this way, the dcmd can be used as a filter for
input from a pipeline.  The <option><gentext type="text">-</gentext>a</option> option indicates that the bufctl's
corresponding buffer address must equal the specified address.  The <option><gentext type="text">-</gentext>c</option> option indicates that a program counter value from the specified
caller         must be present in the bufctl's saved stack trace.  The <option><gentext type="text">-</gentext>e</option> option indicates that the bufctl's timestamp must be greater than
or equal to the specified earliest timestamp.  The <option><gentext type="text">-</gentext>l</option> option
indicates that the bufctl's timestamp must be less than or equal to the specified
latest timestamp.  The <option><gentext type="text">-</gentext>t</option> option indicates that the bufctl's
thread pointer must be equal to the specified thread address.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::findleaks</command> [<option><gentext type="text">-</gentext>v</option>]</term><indexterm id="indexterm-118"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::findleaks</command></tertiary></indexterm><indexterm id="indexterm-119"><primary>dcmds</primary><secondary><command>::findleaks</command></secondary></indexterm><listitem><para>The <command>::findleaks</command> dcmd provides powerful
and efficient detection of memory leaks in kernel crash dumps where the full
set of kmem debug features has been enabled.  The first execution of <command>::findleaks</command> processes the dump for memory leaks (this can take a
few minutes), then coalesces the leaks by the allocation stack trace.  The
findleaks  report shows a bufctl address and the topmost stack frame for each
 memory leak that was identified.  </para><para>If the <option><gentext type="text">-</gentext>v</option> option is specified, the dcmd prints more
verbose messages as it executes.  If an  explicit address is specified prior
to the dcmd, the report is filtered and only leaks whose allocation stack
traces contain the specified function address are displayed. </para></listitem></varlistentry><varlistentry><term><replaceable>thread</replaceable> <command>::freedby</command></term><indexterm id="indexterm-120"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::freedby</command></tertiary></indexterm><indexterm id="indexterm-121"><primary>dcmds</primary><secondary><command>::freedby</command></secondary></indexterm><listitem><para>Given the address of a kernel
thread, print a list of memory frees it has performed, in reverse chronological
order. </para></listitem></varlistentry><varlistentry><term><replaceable>value</replaceable> <command>::kgrep</command></term><indexterm id="indexterm-122"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::kgrep</command></tertiary></indexterm><indexterm id="indexterm-123"><primary>dcmds</primary><secondary><command>::kgrep</command></secondary></indexterm><listitem><para>Search the kernel address
space for pointer-aligned addresses that  contain the specified pointer-sized
value.  The list of addresses that contain matching values is then printed.
 Unlike MDB's built-in search operators, <command>::kgrep</command> searches
every segment of the kernel's address space  and searches across discontiguous
segment boundaries.  On large kernels, <command>::kgrep</command> can take
a considerable amount of time to execute.</para></listitem></varlistentry><varlistentry><term><command>::kmalog</command> [ <literal>slab</literal>
| <literal>fail</literal> ]</term><listitem><para><indexterm id="indexterm-124"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::kmalog</command></tertiary></indexterm><indexterm id="indexterm-125"><primary>dcmds</primary><secondary><command>::kmalog</command></secondary></indexterm>Display
events in a kernel memory allocator transaction log.  Events  are displayed
in time-reverse order, with the most recent event displayed first. For each
event, <command>::kmalog</command> displays the time relative to the most
recent event in T-minus notation (for example, T-0.000151879),   the bufctl,
the buffer address, the kmem cache name, and the stack  trace at the time
of the event.  Without arguments, <command>::kmalog</command> displays the
kmem transaction log, which is present only if <literal>KMF_AUDIT</literal>
is set in <literal>kmem_flags</literal>.  <command>::kmalog</command> <literal>fail</literal> displays the allocation failure log, which is always present;
this can be useful in debugging drivers that don't  cope with allocation failure
correctly.  <command>::kmalog</command> <literal>slab</literal> displays the
slab create log, which is always present.  <command>::kmalog</command> <literal>slab</literal> can be useful when searching for memory leaks. </para></listitem></varlistentry><varlistentry><term><command>::kmastat</command></term><indexterm id="indexterm-126"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::kmastat</command></tertiary></indexterm><indexterm id="indexterm-127"><primary>dcmds</primary><secondary><command>::kmastat</command></secondary></indexterm><listitem><para>Display the list of kernel memory allocator caches and virtual
memory  arenas, along with corresponding statistics. </para></listitem></varlistentry><varlistentry><term><command>::kmausers</command> [<option><gentext type="text">-</gentext>ef</option>] [<replaceable>cache</replaceable> ...]</term><indexterm id="indexterm-128"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::kmausers</command></tertiary></indexterm><indexterm id="indexterm-129"><primary>dcmds</primary><secondary><command>::kmausers</command></secondary></indexterm><listitem><para>Print information about the medium and large users of the
kernel memory         allocator that have current memory allocations. The
output consists of one entry for each unique stack trace specifying the total
amount of  memory and number of allocations that was made with that stack
trace. This dcmd requires that the <literal>KMF_AUDIT</literal> flag is set
in <literal>kmem_flags</literal>.  </para><para>If one or more cache names (for example, <literal>kmem_alloc_256</literal>)
are specified,  the scan of memory usage is restricted to those caches.  By
default all  caches are included.  If the <option><gentext type="text">-</gentext>e</option> option is used,
the small users of the allocator are included.  The small users are allocations
that total  less than 1024 bytes of memory or for which there are less than
10 allocations with the same stack trace.  If the <option><gentext type="text">-</gentext>f</option> option
is used, the  stack traces are printed for each individual allocation.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::kmem_cache</command></term><indexterm id="indexterm-130"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::kmem_cache</command></tertiary></indexterm><indexterm id="indexterm-131"><primary>dcmds</primary><secondary><command>::kmem_cache</command></secondary></indexterm><listitem><para>Format and display
the <structname>kmem_cache</structname> structure stored at the specified
address, or the complete set of active <structname>kmem_cache</structname>
structures.</para></listitem></varlistentry><varlistentry><term><command>::kmem_log</command></term><indexterm id="indexterm-132"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::kmem_log</command></tertiary></indexterm><indexterm id="indexterm-133"><primary>dcmds</primary><secondary><command>::kmem_log</command></secondary></indexterm><listitem><para>Display the complete set of kmem transaction logs, sorted
in reverse  chronological order.  This dcmd uses a more concise tabular output
 format than <command>::kmalog</command>.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::kmem_verify</command></term><indexterm id="indexterm-134"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::kmem_verify</command></tertiary></indexterm><indexterm id="indexterm-135"><primary>dcmds</primary><secondary><command>::kmem_verify</command></secondary></indexterm><listitem><para>Verify the
integrity of the <structname>kmem_cache</structname> structure stored at the
 specified address, or the complete set of active <structname>kmem_cache</structname>
structures. If an explicit cache address is specified, the dcmd displays more
 verbose information regarding errors; otherwise, a summary report is displayed.
 The <command>::kmem_verify</command> dcmd is discussed in more detail in
 <link linkend="casestudy-27">Kernel Memory Caches</link>.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address </replaceable>] <command>::vmem</command></term><indexterm id="indexterm-136"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::vmem</command></tertiary></indexterm><indexterm id="indexterm-137"><primary>dcmds</primary><secondary><command>::vmem</command></secondary></indexterm><listitem><para>Format and display
the <structname>vmem</structname> structure stored at the specified address,
 or the complete set of active<structname> vmem</structname> structures. 
This structure is  defined in <literal>&lt;sys/vmem_impl.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::vmem_seg</command></term><indexterm id="indexterm-138"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::vmem_seg</command></tertiary></indexterm><indexterm id="indexterm-139"><primary>dcmds</primary><secondary><command>::vmem_seg</command></secondary></indexterm><listitem><para>Format and display
the <structname>vmem_seg</structname> structure stored at the specified address.
 This structure is defined in <literal>&lt;sys/vmem_impl.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::whatis</command>
[<option><gentext type="text">-</gentext>abv</option>]</term><listitem><para><indexterm id="indexterm-140"><primary>Kernel Memory Allocator</primary><secondary>dcmds</secondary><tertiary><command>::whatis</command></tertiary></indexterm><indexterm id="indexterm-141"><primary>dcmds</primary><secondary><command>::whatis</command></secondary></indexterm>Report
information about the specified address.  In particular, <command>::whatis</command> will attempt to determine if the address is a pointer to a kmem-managed
buffer or another type of special memory region, such as a thread stack, and
report its findings.  If the <option><gentext type="text">-</gentext>a</option> option is present, the dcmd
reports all matches instead of just the first match to its queries.  If the <option><gentext type="text">-</gentext>b</option> option is present, the dcmd also attempts to determine if  the
address is referred to by a known kmem <structname>bufctl</structname>.  If
the <option><gentext type="text">-</gentext>v</option> option is present, the dcmd reports its progress as
it searches various  kernel data structures.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-26"><title>Walkers</title><variablelist><varlistentry><term>allocdby</term><indexterm id="indexterm-142"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>allocdby</tertiary></indexterm><indexterm id="indexterm-143"><primary>Walkers</primary><secondary>allocdby</secondary></indexterm><listitem><para>Given the address of a <structname>kthread_t</structname>
structure as a starting point, iterate over the set of <structname>bufctl</structname> structures corresponding to memory allocations performed by
this kernel thread.</para></listitem></varlistentry><varlistentry><term>bufctl</term><indexterm id="indexterm-144"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>bufctl</tertiary></indexterm><indexterm id="indexterm-145"><primary>Walkers</primary><secondary>bufctl</secondary></indexterm><listitem><para>Given the address of a <structname>kmem_cache_t</structname>
structure as a starting point, iterate over the set of allocated <structname>bufctl</structname>s associated with this cache.</para></listitem></varlistentry><varlistentry><term>freectl</term><indexterm id="indexterm-146"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>freectl</tertiary></indexterm><indexterm id="indexterm-147"><primary>Walkers</primary><secondary>freectl</secondary></indexterm><listitem><para>Given the address of a <structname>kmem_cache_t</structname>
structure as a starting point, iterate over the set of free <structname>bufctl</structname>s associated with this cache.</para></listitem></varlistentry><varlistentry><term>freedby</term><indexterm id="indexterm-148"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>freedby</tertiary></indexterm><indexterm id="indexterm-149"><primary>Walkers</primary><secondary>freedby</secondary></indexterm><listitem><para>Given the address of a <structname>kthread_t</structname>
structure as a starting point, iterate over the set of <structname>bufctl</structname> structures corresponding to memory deallocations performed by
this kernel thread.</para></listitem></varlistentry><varlistentry><term>freemem</term><indexterm id="indexterm-150"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>freemem</tertiary></indexterm><indexterm id="indexterm-151"><primary>Walkers</primary><secondary>freemem</secondary></indexterm><listitem><para>Given the address of a <structname>kmem_cache_t</structname>
structure as a starting point, iterate over the set of free buffers associated
with this cache.</para></listitem></varlistentry><varlistentry><term>kmem</term><indexterm id="indexterm-152"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>kmem</tertiary></indexterm><indexterm id="indexterm-153"><primary>Walkers</primary><secondary>kmem</secondary></indexterm><listitem><para>Given the address of a <structname>kmem_cache_t</structname>
structure as a starting point,  iterate over the set of allocated buffers
associated with this cache.</para></listitem></varlistentry><varlistentry><term>kmem_cache</term><indexterm id="indexterm-154"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>kmem_cache</tertiary></indexterm><indexterm id="indexterm-155"><primary>Walkers</primary><secondary>kmem_cache</secondary></indexterm><listitem><para>Iterate over the active set of <structname>kmem_cache_t</structname>
structures.  This structure is defined in <literal>&lt;sys/kmem_impl.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>kmem_cpu_cache</term><indexterm id="indexterm-156"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>kmem_cpu_cache</tertiary></indexterm><indexterm id="indexterm-157"><primary>Walkers</primary><secondary>kmem_cpu_cache</secondary></indexterm><listitem><para>Given the address of a <structname>kmem_cache_t</structname> structure as a starting point, iterate over the
per-CPU <structname>kmem_cpu_cache_t</structname> structures associated with
this cache.  This structure is defined in <literal>&lt;sys/kmem_impl.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>kmem_slab</term><indexterm id="indexterm-158"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>kmem_slab</tertiary></indexterm><indexterm id="indexterm-159"><primary>Walkers</primary><secondary>kmem_slab</secondary></indexterm><listitem><para>Given the address of a <structname>kmem_cache_t</structname>
structure as a starting point, iterate over the set of associated <structname>kmem_slab_t</structname> structures.  This structure is defined in <literal>&lt;sys/kmem_impl.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>kmem_log</term><indexterm id="indexterm-160"><primary>Kernel Memory Allocator</primary><secondary>Walkers</secondary><tertiary>kmem_log</tertiary></indexterm><indexterm id="indexterm-161"><primary>Walkers</primary><secondary>kmem_log</secondary></indexterm><listitem><para>Iterate over the set of <structname>bufctl</structname>s stored
in the kmem allocator transaction log.</para></listitem></varlistentry><varlistentry><term>leak </term><listitem><para>Given the address of a <structname>bufctl</structname> structure, iterate over the set of <structname>bufctl</structname> structures corresponding to leaked memory buffers with similar
allocation stack traces. The <command>::findleaks</command> dcmd must be applied
to locate memory leaks before the leak walker can be used</para></listitem></varlistentry><varlistentry><term>leakbuf</term><listitem><para>Given the address of a <structname>bufctl</structname> structure, iterate over the set of buffer           addresses
corresponding to leaked memory buffers with similar allocation stack traces.
The <command>::findleaks</command> dcmd must be applied to locate memory leaks
 before the leakbuf walker can be used. </para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-27"><title>File Systems</title><para>The MDB file systems debugging support includes a built-in facility
to convert vnode pointers to the corresponding file system path name.  This
conversion is performed using the Directory Name Lookup Cache (DNLC); because
the cache does not hold all active vnodes, some vnodes might not be able to
be converted to path names and “<literal>??</literal>” is displayed
instead of a name.</para><indexterm id="indexterm-162"><primary>Directory Name Lookup Cache (DNLC)</primary></indexterm><sect3 id="modules-51"><title>dcmds</title><variablelist><varlistentry><term><command>::fsinfo</command></term><indexterm id="indexterm-163"><primary>File Systems</primary><secondary>dcmds</secondary><tertiary><command>::fsinfo</command></tertiary></indexterm><indexterm id="indexterm-164"><primary>dcmds</primary><secondary><command>::fsinfo</command></secondary></indexterm><listitem><para>Display a table of mounted file systems, including the <literal>vfs_t</literal> address, <literal>ops</literal> vector, and mount point of
each file system.</para></listitem></varlistentry><varlistentry><term><command>::lminfo</command></term><indexterm id="indexterm-165"><primary>File Systems</primary><secondary>dcmds</secondary><tertiary><command>::lminfo</command></tertiary></indexterm><indexterm id="indexterm-166"><primary>dcmds</primary><secondary><command>::lminfo</command></secondary></indexterm><listitem><para>Display a table of vnodes with active network locks registered
with         the lock manager.  The pathname corresponding to each vnode is
shown.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::vnode2path</command> [<option><gentext type="text">-</gentext>v</option>]</term><indexterm id="indexterm-167"><primary>File Systems</primary><secondary>dcmds</secondary><tertiary><command>::vnode2path</command></tertiary></indexterm><indexterm id="indexterm-168"><primary>dcmds</primary><secondary><command>::vnode2path</command></secondary></indexterm><listitem><para>Display the pathname corresponding to the given vnode address.
 If the <option><gentext type="text">-</gentext>v</option> option is specified, the dcmd prints a more verbose
display, including the vnode pointer of each intermediate path component.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-30"><title>Walkers</title><variablelist><varlistentry><term>buf</term><indexterm id="indexterm-169"><primary>File Systems</primary><secondary>Walkers</secondary><tertiary>buf</tertiary></indexterm><indexterm id="indexterm-170"><primary>Walkers</primary><secondary>buf</secondary></indexterm><listitem><para>Iterate
over the set of active block I/O transfer structures (<structname>buf_t</structname>
structures).  The <structname>buf</structname> structure is defined in <literal>&lt;sys/buf.h&gt;</literal> and is described in more detail
in <olink targetdocent="REFMAN9S" localinfo="BUF-9S" type="v-only"><citerefentry><refentrytitle>buf</refentrytitle><manvolnum><gentext type="text">(</gentext>9S<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-28"><title>Virtual Memory</title><para>This section describes the debugging support for the kernel virtual
memory subsystem.</para><sect3 id="modules-31"><title>dcmds</title><variablelist><varlistentry><term><replaceable>address</replaceable> <command>::addr2smap</command> [<replaceable>offset</replaceable>]</term><indexterm id="indexterm-171"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::addr2smap</command></tertiary></indexterm><indexterm id="indexterm-172"><primary>dcmds</primary><secondary><command>::addr2smap</command></secondary></indexterm><listitem><para>Print the <structname>smap</structname> structure address
that corresponds to the given address in the kernel's segmap address space
segment.</para></listitem></varlistentry><varlistentry><term><replaceable>as</replaceable> <command>::as2proc</command></term><indexterm id="indexterm-173"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::as2proc</command></tertiary></indexterm><indexterm id="indexterm-174"><primary>dcmds</primary><secondary><command>::as2proc</command></secondary></indexterm><listitem><para>Display the <structname>proc_t</structname> address
for the process corresponding to the <literal>as_t</literal> address <replaceable>as</replaceable>. </para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::memlist</command> [<option><gentext type="text">-</gentext>aiv</option>]</term><indexterm id="indexterm-175"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::memlist</command></tertiary></indexterm><indexterm id="indexterm-176"><primary>dcmds</primary><secondary><command>::memlist</command></secondary></indexterm><listitem><para>Display the specified <structname>memlist</structname> structure
or one of the well-known <structname>memlist</structname> structures.  If
no <structname>memlist</structname> address and options are present or if
the <option><gentext type="text">-</gentext>i</option> option is present, the <structname>memlist</structname>
representing physically installed memory is displayed.  If the <option><gentext type="text">-</gentext>a</option>
option is present, the <structname>memlist</structname> representing available
physical memory is displayed.  If the <option><gentext type="text">-</gentext>v</option> option is present,
the memlist representing available virtual memory is displayed.</para></listitem></varlistentry><varlistentry><term><command>::memstat</command></term><indexterm id="indexterm-177"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::memstat</command></tertiary></indexterm><indexterm id="indexterm-178"><primary>dcmds</primary><secondary><command>::memstat</command></secondary></indexterm><listitem><para>Display a system-wide memory usage summary.  The amount and
percentage of system memory consumed by different classes of pages (kernel,
anonymous memory, executables and libraries, page cache, and free lists) are
displayed, along with the total amount of system memory.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::page</command></term><indexterm id="indexterm-179"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::page</command></tertiary></indexterm><indexterm id="indexterm-180"><primary>dcmds</primary><secondary><command>::page</command></secondary></indexterm><listitem><para>Display the properties
of the specified <literal>page_t</literal>.  If no <literal>page_t</literal>
address is specified, the dcmd displays the properties of all system pages.</para></listitem></varlistentry><varlistentry><term><replaceable>seg</replaceable> <command>::seg</command></term><indexterm id="indexterm-181"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::seg</command></tertiary></indexterm><indexterm id="indexterm-182"><primary>dcmds</primary><secondary><command>::seg</command></secondary></indexterm><listitem><para>Format and display the specified address space
segment (<structname>seg_t</structname> address).</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::swapinfo</command></term><indexterm id="indexterm-183"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::swapinfo</command></tertiary></indexterm><indexterm id="indexterm-184"><primary>dcmds</primary><secondary><command>::swapinfo</command></secondary></indexterm><listitem><para>Display information
on all active <structname>swapinfo</structname> structures or about the specified
struct <structname>swapinfo</structname>.  The vnode, filename, and statistics
for each structure are displayed.</para></listitem></varlistentry><varlistentry><term><replaceable>vnode</replaceable> <command>::vnode2smap </command>[<replaceable>offset</replaceable>]</term><indexterm id="indexterm-185"><primary>Virtual Memory</primary><secondary>dcmds</secondary><tertiary><command>::vnode2smap</command></tertiary></indexterm><indexterm id="indexterm-186"><primary>dcmds</primary><secondary><command>::vnode2smap</command></secondary></indexterm><listitem><para>Print the <structname>smap</structname> structure
address that corresponds to the given <structname>vnode_t</structname> address
and offset.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-32"><title>Walkers</title><variablelist><varlistentry><term>anon</term><indexterm id="indexterm-187"><primary>Virtual Memory</primary><secondary>Walkers</secondary><tertiary>anon</tertiary></indexterm><indexterm id="indexterm-188"><primary>Walkers</primary><secondary>anon</secondary></indexterm><listitem><para>Given the address of an <structname>anon_map</structname> structure
as a starting point, iterate over the set of related anon structures.  The
anon map implementation is defined in <literal>&lt;vm/anon.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>memlist</term><indexterm id="indexterm-189"><primary>Virtual Memory</primary><secondary>Walkers</secondary><tertiary>memlist</tertiary></indexterm><indexterm id="indexterm-190"><primary>Walkers</primary><secondary>memlist</secondary></indexterm><listitem><para>Iterate over the spans of the specified <structname>memlist</structname>
structure.  This walker can be used in conjuction with the <command>::memlist</command> dcmd to display each span.</para></listitem></varlistentry><varlistentry><term>page</term><indexterm id="indexterm-191"><primary>Virtual Memory</primary><secondary>Walkers</secondary><tertiary>page</tertiary></indexterm><indexterm id="indexterm-192"><primary>Walkers</primary><secondary>page</secondary></indexterm><listitem><para>Iterate over all system <structname>page</structname> structures.  If
an explicit address is specified for the walk, this is taken to be the address
of a vnode and the walker iterates over only those pages associated with the
vnode.</para></listitem></varlistentry><varlistentry><term>seg</term><indexterm id="indexterm-193"><primary>Virtual Memory</primary><secondary>Walkers</secondary><tertiary>seg</tertiary></indexterm><indexterm id="indexterm-194"><primary>Walkers</primary><secondary>seg</secondary></indexterm><listitem><para>Given the address of an <structname>as_t</structname> structure as a
starting point, iterate over the set of address space segments (<structname>seg</structname> structures) associated with the specified address space.
 The <structname>seg</structname> structure is defined in <literal>&lt;vm/seg.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>swapinfo</term><indexterm id="indexterm-195"><primary>Virtual Memory</primary><secondary>Walkers</secondary><tertiary>swapinfo</tertiary></indexterm><indexterm id="indexterm-196"><primary>Walkers</primary><secondary>swapinfo</secondary></indexterm><listitem><para>Iterate over the list of active <structname>swapinfo</structname> structures.
 This walker may be used in conjunction with the <command>::swapinfo</command>
dcmd.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-33"><title>CPUs and the Dispatcher</title><para>This section describes the facilities for examining the state of the
cpu structures and the kernel dispatcher.</para><sect3 id="modules-34"><title>dcmds</title><variablelist><varlistentry><term><command>::callout</command></term><indexterm id="indexterm-197"><primary>CPUs and the Dispatcher</primary><secondary>dcmds</secondary><tertiary><command>::callout</command></tertiary></indexterm><indexterm id="indexterm-198"><primary>dcmds</primary><secondary><command>::callout</command></secondary></indexterm><listitem><para>Display the callout table. The function, argument, and expiration
time for each callout is displayed.</para></listitem></varlistentry><varlistentry><term><command>::class</command></term><indexterm id="indexterm-199"><primary>CPUs and the Dispatcher</primary><secondary>dcmds</secondary><tertiary><command>::class</command></tertiary></indexterm><indexterm id="indexterm-200"><primary>dcmds</primary><secondary><command>::class</command></secondary></indexterm><listitem><para>Display the scheduling class table.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>cpuid</replaceable> ] <command>::cpuinfo</command> [<option><gentext type="text">-</gentext>v</option>]</term><indexterm id="indexterm-201"><primary>CPUs and the Dispatcher</primary><secondary>dcmds</secondary><tertiary><command>::cpuinfo</command></tertiary></indexterm><indexterm id="indexterm-202"><primary>dcmds</primary><secondary><command>::cpuinfo</command></secondary></indexterm><listitem><para>Display a table of the threads currently executing on each
CPU.  If an optional CPU ID number or CPU structure address is specified prior
to the dcmd name, only the information for the specified CPU is displayed.
 If the <option><gentext type="text">-</gentext>v</option> option is present, <command>::cpuinfo</command>
also displays the runnable threads waiting to execute on each CPU as well
as the active interrupt threads. </para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-35"><title>Walkers</title><variablelist><varlistentry><term>cpu</term><indexterm id="indexterm-203"><primary>CPUs and the Dispatcher</primary><secondary>Walkers</secondary><tertiary>cpu</tertiary></indexterm><indexterm id="indexterm-204"><primary>Walkers</primary><secondary>cpu</secondary></indexterm><listitem><para>Iterate over the set of kernel CPU structures. The <structname>cpu_t</structname> structure is defined in <literal>&lt;sys/cpuvar.h&gt;</literal>.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-36"><title>Device Drivers and DDI Framework</title><para>This section describes dcmds and walkers that are useful for kernel
developers as well as third-party device driver developers.</para><sect3 id="modules-37"><title>dcmds</title><variablelist termlength="wholeline"><varlistentry><term><replaceable>address</replaceable> <command>::binding_hash_entry</command></term><indexterm id="indexterm-205"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::binding_hash_entry</command></tertiary></indexterm><indexterm id="indexterm-206"><primary>dcmds</primary><secondary><command>::binding_hash_entry</command></secondary></indexterm><listitem><para>Given the address of a kernel name-to-major number binding
hash table entry (struct <structname>bind</structname>), display the node
binding name, major number, and pointer to the next element.</para></listitem></varlistentry><varlistentry><term><command>::devbindings</command> <replaceable>device-name</replaceable></term><indexterm id="indexterm-207"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::devbindings</command></tertiary></indexterm><indexterm id="indexterm-208"><primary>dcmds</primary><secondary><command>::devbindings</command></secondary></indexterm><listitem><para>Display the list of all instances of the named
driver. The output consists of an entry for each instance, beginning with
the pointer to the struct <structname>dev_info</structname> (viewable with <literal>$&lt;devinfo</literal> or <command>::devinfo</command>), the driver name,
the instance number, and the driver and system properties associated with
that instance.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::devinfo</command> [ <option><gentext type="text">-</gentext>q</option> ]</term><indexterm id="indexterm-209"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::devinfo</command></tertiary></indexterm><indexterm id="indexterm-210"><primary>dcmds</primary><secondary><command>::devinfo</command></secondary></indexterm><listitem><para>Print the system and driver properties associated with a devinfo
node. If the <option><gentext type="text">-</gentext>q</option> option is specified, only a quick summary
of the device node is shown. </para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::devinfo2driver</command></term><indexterm id="indexterm-211"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::devinfo2driver</command></tertiary></indexterm><indexterm id="indexterm-212"><primary>dcmds</primary><secondary><command>::devinfo2driver</command></secondary></indexterm><listitem><para>Print the name of the driver (if any) associated with the <literal>devinfo</literal> node.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::devnames</command> [ <option><gentext type="text">-</gentext>v</option> ]</term><indexterm id="indexterm-213"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::devnames</command></tertiary></indexterm><indexterm id="indexterm-214"><primary>dcmds</primary><secondary><command>::devnames</command></secondary></indexterm><listitem><para>Display the kernel's <literal>devnames</literal> table along
with the <literal>dn_head</literal> pointer,  which points at the driver instance
list.  If the <option><gentext type="text">-</gentext>v</option> flag is specified, additional information
stored at each entry in the <literal>devnames</literal> table is displayed.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>devinfo</replaceable> ] <command>::prtconf</command> [ <option><gentext type="text">-</gentext>cpv</option> ]</term><indexterm id="indexterm-215"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::prtconf</command></tertiary></indexterm><indexterm id="indexterm-216"><primary>dcmds</primary><secondary><command>::prtconf</command></secondary></indexterm><listitem><para>Display the kernel device tree starting at the device node
specified by <replaceable>devinfo</replaceable>.  If <replaceable>devinfo</replaceable> is not provided, the root of the device tree is assumed by
default.  If the <option><gentext type="text">-</gentext>c</option> option is specified, only children of
the given device node are displayed.  If the <option><gentext type="text">-</gentext>p</option> option is
specified, only ancestors of the given device node are displayed.  If <option><gentext type="text">-</gentext>v</option> is specified, the properties associated with each node are displayed. </para></listitem></varlistentry><varlistentry><term>[ <replaceable>major-num</replaceable> ] <command>::major2name</command> [ <replaceable>major-num</replaceable> ]</term><indexterm id="indexterm-217"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::major2name</command></tertiary></indexterm><indexterm id="indexterm-218"><primary>dcmds</primary><secondary><command>::major2name</command></secondary></indexterm><listitem><para>Display the
driver name corresponding to the specified major number. The major number
can be specified as an expression preceding the dcmd or as a command-line
argument.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::modctl2devinfo</command></term><indexterm id="indexterm-219"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::modctl2devinfo</command></tertiary></indexterm><indexterm id="indexterm-220"><primary>dcmds</primary><secondary><command>::modctl2devinfo</command></secondary></indexterm><listitem><para>Print all of the device nodes that correspond to the specified <structname>modctl</structname> address.</para></listitem></varlistentry><varlistentry><term><command>::name2major</command> <replaceable>driver-name</replaceable></term><indexterm id="indexterm-221"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::name2major</command></tertiary></indexterm><indexterm id="indexterm-222"><primary>dcmds</primary><secondary><command>::name2major</command></secondary></indexterm><listitem><para>Given a device driver name, display its major
number.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::softstate</command> [ <replaceable>instance-number</replaceable> ]</term><indexterm id="indexterm-223"><primary>Device Drivers and DDI Framework</primary><secondary>dcmds</secondary><tertiary><command>::softstate</command></tertiary></indexterm><indexterm id="indexterm-224"><primary>dcmds</primary><secondary><command>::softstate</command></secondary></indexterm><listitem><para>Given a softstate
state pointer (see <olink targetdocent="REFMAN9F" localinfo="DDI-SOFT-STATE-INIT-9F" type="v-only"><citerefentry><refentrytitle>ddi_soft_state_init</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>) and a device instance number,
display the soft state for that instance.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-38"><title>Walkers</title><variablelist><varlistentry><term>binding_hash</term><indexterm id="indexterm-225"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>binding_hash</tertiary></indexterm><indexterm id="indexterm-226"><primary>Walkers</primary><secondary>binding_hash</secondary></indexterm><listitem><para>Given the address of an array of kernel
binding hash table entries (struct <structname>bind</structname>  **), walk
all entries in the hash table and return the address of each struct <structname>bind</structname>.</para></listitem></varlistentry><varlistentry><term>devinfo</term><indexterm id="indexterm-227"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>devinfo</tertiary></indexterm><indexterm id="indexterm-228"><primary>Walkers</primary><secondary>devinfo</secondary></indexterm><listitem><para>First, iterate over the parents of the given devinfo
and return them in order of seniority from most to least senior.  Second,
return the given devinfo itself.  Third, iterate over the children of the
given devinfo in order of seniority from most to least senior.  The <structname>dev_info</structname> struct is defined in <literal>&lt;sys/ddi_impldefs.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>devinfo_children</term><indexterm id="indexterm-229"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>devinfo_children</tertiary></indexterm><indexterm id="indexterm-230"><primary>Walkers</primary><secondary>devinfo_children</secondary></indexterm><listitem><para>First, return the given devinfo, then
iterate over the children of the given devinfo in order of seniority from
most to least senior. The <structname>dev_info</structname> struct is defined
in <literal>&lt;sys/ddi_impldefs.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>devinfo_parents</term><indexterm id="indexterm-231"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>devinfo_parents</tertiary></indexterm><indexterm id="indexterm-232"><primary>Walkers</primary><secondary>devinfo_parents</secondary></indexterm><listitem><para>Iterate over the parents of the given
devinfo in order of seniority from most to least senior, and then return the
given devinfo.  The <structname>dev_info</structname> struct is defined in <literal>&lt;sys/ddi_impldefs.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>devi_next</term><indexterm id="indexterm-233"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>devi_next</tertiary></indexterm><indexterm id="indexterm-234"><primary>Walkers</primary><secondary>devi_next</secondary></indexterm><listitem><para>Iterate over the siblings of the given devinfo.
 The <structname>dev_info</structname> struct is defined in <literal>&lt;sys/ddi_impldefs.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>devnames</term><indexterm id="indexterm-235"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>devnames</tertiary></indexterm><indexterm id="indexterm-236"><primary>Walkers</primary><secondary>devnames</secondary></indexterm><listitem><para>Iterate over the entries in the devnames array.
 This structure is defined in <literal>&lt;sys/autoconf.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>softstate</term><indexterm id="indexterm-237"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>softstate</tertiary></indexterm><indexterm id="indexterm-238"><primary>Walkers</primary><secondary>softstate</secondary></indexterm><listitem><para>Given a softstate pointer (see <command>ddi_soft_state_init</command>(9F)) display all non-NULL pointers to driver state structures.</para></listitem></varlistentry><varlistentry><term>softstate_all</term><indexterm id="indexterm-239"><primary>Device Drivers and DDI Framework</primary><secondary>Walkers</secondary><tertiary>softstate_all</tertiary></indexterm><indexterm id="indexterm-240"><primary>Walkers</primary><secondary>softstate_all</secondary></indexterm><listitem><para>Given a softstate pointer (see <command>ddi_soft_state_init</command>(9F)) display all pointers to driver state structures.
 Note that the pointers for unused instances will be NULL.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-39"><title>STREAMS</title><para>This section describes dcmds and walkers that are useful for kernel
developers as well as developers of third-party STREAMS modules and drivers.</para><sect3 id="modules-40"><title>dcmds</title><variablelist termlength="wholeline"><varlistentry><term><replaceable>address</replaceable> <command>::mblk2dblk</command></term><listitem><para>Given the address of an <structname>mblk_t</structname>, print the address of the corresponding <structname>dblk_t</structname>.</para></listitem></varlistentry><varlistentry><term>[<replaceable>address</replaceable>] <command>::mblk_verify</command></term><listitem><para>Verify the integrity of one or more message
blocks. If an explicit message block address is specified, the integrity of
this message block is checked. If no address is specified, the integrity of
all active message blocks are checked.           This dcmd produces output
for any invalid message block state that is detected. </para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::queue</command>
[<option><gentext type="text">-</gentext>v</option>] [<option><gentext type="text">-</gentext>f</option> <replaceable>flag</replaceable>]
[<option><gentext type="text">-</gentext>F</option> <replaceable>flag</replaceable>] [<option><gentext type="text">-</gentext>s</option> <replaceable>syncq</replaceable>]</term><indexterm id="indexterm-241"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::queue</command></tertiary></indexterm><indexterm id="indexterm-242"><primary>dcmds</primary><secondary><command>::queue</command></secondary></indexterm><listitem><para>Filter and display
the specified <structname>queue_t</structname> data structure.  With no options,
various properties of the <structname>queue_t</structname> are shown.  If
the <option><gentext type="text">-</gentext>v</option> option is present, the queue flags are decoded in greater
detail.  If the <option><gentext type="text">-</gentext>f</option>, <option><gentext type="text">-</gentext>F</option>, or <option><gentext type="text">-</gentext>m</option>
options are present, the queue is displayed only if it matches the criteria
defined by the arguments to these options; in this way, the dcmd can be used
as a filter for input from a pipeline.  The <option><gentext type="text">-</gentext>f</option> option indicates
that the specified flag (one of the Q flag names from <literal>&lt;sys/stream.h&gt;</literal>) must be present in the queue
flags.  The <option><gentext type="text">-</gentext>F</option> option indicates that the specified flag must
be absent from the queue flags. The <option><gentext type="text">-</gentext>m</option> option indicates that
the module name associated with the queue must match the specified modname.
The <option><gentext type="text">-</gentext>s</option> option indicates that the <structname>syncq_t</structname>
associated with the queue must match the specified <structname>syncq_t</structname>
address. </para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::q2syncq</command></term><indexterm id="indexterm-243"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::q2syncq</command></tertiary></indexterm><indexterm id="indexterm-244"><primary>dcmds</primary><secondary><command>::q2syncq</command></secondary></indexterm><listitem><para>Given the address of a <structname>queue_t</structname>, print the address of the corresponding <structname>syncq_t</structname> data structure.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::q2otherq</command></term><indexterm id="indexterm-245"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::q2otherq</command></tertiary></indexterm><indexterm id="indexterm-246"><primary>dcmds</primary><secondary><command>::q2otherq</command></secondary></indexterm><listitem><para>Given the address
of a <structname>queue_t</structname>, print the address of the peer read
or write queue structure.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::q2rdq</command></term><indexterm id="indexterm-247"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::q2rdq</command></tertiary></indexterm><indexterm id="indexterm-248"><primary>dcmds</primary><secondary><command>::q2rdq</command></secondary></indexterm><listitem><para>Given the address of a <structname>queue_t</structname>,
print the address of the corresponding read queue.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::q2wrq</command></term><indexterm id="indexterm-249"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::q2wrq</command></tertiary></indexterm><indexterm id="indexterm-250"><primary>dcmds</primary><secondary><command>::q2wrq</command></secondary></indexterm><listitem><para>Given the address of a <structname>queue_t</structname>,
print the address of the corresponding write queue.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::stream</command></term><indexterm id="indexterm-251"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::stream</command></tertiary></indexterm><indexterm id="indexterm-252"><primary>dcmds</primary><secondary><command>::stream</command></secondary></indexterm><listitem><para>Display a visual picture
of a kernel STREAM data structure, given the address of the <structname>stdata_t</structname> structure representing the STREAM head.  The read and write
queue pointers, byte count, and flags for each module are shown, and in some
cases additional information for the specific queue is shown in the margin.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::syncq</command>
[<option><gentext type="text">-</gentext>v</option>] [<option><gentext type="text">-</gentext>f</option> <replaceable>flag</replaceable>]
[<option><gentext type="text">-</gentext>F</option> <replaceable>flag</replaceable>] [<option><gentext type="text">-</gentext>t</option> <replaceable>type</replaceable>] [<option><gentext type="text">-</gentext>T</option> <replaceable>type</replaceable>]</term><listitem><para><indexterm id="indexterm-253"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::syncq</command></tertiary></indexterm><indexterm id="indexterm-254"><primary>dcmds</primary><secondary><command>::syncq</command></secondary></indexterm>Filter and display the specified <structname>syncq_t</structname>
data structure.  With no options, various properties of the <structname>syncq_t</structname> are shown.  If the <option><gentext type="text">-</gentext>v</option> option is present, the
syncq flags are decoded in greater detail.  If the <option><gentext type="text">-</gentext>f</option>, <option><gentext type="text">-</gentext>F</option>, <option><gentext type="text">-</gentext>t</option>, or <option><gentext type="text">-</gentext>T</option> options are present,
the syncq is displayed only if it matches the criteria defined by the arguments
to these options; in this way, the dcmd can be used as a filter for input
from a pipeline. The <option><gentext type="text">-</gentext>f</option> option indicates that the specified
flag (one of the <literal>SQ_</literal> flag names from <literal>&lt;sys/strsubr.h&gt;</literal>) must be present in the syncq
flags. The <option><gentext type="text">-</gentext>F</option> option indicates that the specified flag must
be absent from the syncq flags.  The <option><gentext type="text">-</gentext>t</option> option indicates that
the specified type (one of the <literal>SQ_CI</literal> or <literal>SQ_CO</literal> type names from <literal>&lt;sys/strsubr.h&gt;</literal>) must be present in the syncq type bits.  The <option><gentext type="text">-</gentext>T</option> option indicates that the specified type must be absent from the
syncq type bits.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::syncq2q</command></term><indexterm id="indexterm-255"><primary>STREAMS</primary><secondary>dcmds</secondary><tertiary><command>::syncq2q</command></tertiary></indexterm><indexterm id="indexterm-256"><primary>dcmds</primary><secondary><command>::syncq2q</command></secondary></indexterm><listitem><para>Given the address of a <structname>syncq_t</structname>, print the address of the corresponding <structname>queue_t</structname> data structure.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-41"><title>Walkers</title><variablelist><varlistentry><term>b_cont</term><listitem><para>Given the address of an <structname>mblk_t</structname>, iterate over the set of associated message          
structures by following the <literal>b_cont</literal> pointer. The <literal>b_cont</literal> pointer is used to link a given message block to the next
associated message block that is the ontinuation of the same message. The
message block is described in more           detail in <literal>msgb</literal>(9S)</para></listitem></varlistentry><varlistentry><term>b_next</term><listitem><para>Given the address of an <structname>mblk_t</structname>, iterate over the set of associated message          
structures by following the <literal>b_next</literal> pointer. The <literal>b_next</literal> pointer is used to link a given message block to the next
associated message block on a given queue. The message block is described
in more detail in <literal>msgb</literal>(9S).</para></listitem></varlistentry><varlistentry><term>qlink</term><indexterm id="indexterm-257"><primary>STREAMS</primary><secondary>Walkers</secondary><tertiary>qlink</tertiary></indexterm><indexterm id="indexterm-258"><primary>Walkers</primary><secondary>qlink</secondary></indexterm><listitem><para>Given the address of a <structname>queue_t</structname> structure, walk the
list of related queues using the <literal>q_link</literal> pointer.  This
structure is defined in <literal>&lt;sys/stream.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>qnext</term><indexterm id="indexterm-259"><primary>STREAMS</primary><secondary>Walkers</secondary><tertiary>qnext</tertiary></indexterm><indexterm id="indexterm-260"><primary>Walkers</primary><secondary>qnext</secondary></indexterm><listitem><para>Given the address of a <structname>queue_t</structname> structure, walk the
list of related queues using the <literal>q_next</literal> pointer.  This
structure is defined in <literal>&lt;sys/stream.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>readq</term><indexterm id="indexterm-261"><primary>STREAMS</primary><secondary>Walkers</secondary><tertiary>readq</tertiary></indexterm><indexterm id="indexterm-262"><primary>Walkers</primary><secondary>readq</secondary></indexterm><listitem><para>Given the address of an <structname>stdata_t</structname> structure, walk
the list of read-side queue structures.</para></listitem></varlistentry><varlistentry><term>writeq</term><indexterm id="indexterm-263"><primary>STREAMS</primary><secondary>Walkers</secondary><tertiary>writeq</tertiary></indexterm><indexterm id="indexterm-264"><primary>Walkers</primary><secondary>writeq</secondary></indexterm><listitem><para>Given the address of an <structname>stdata_t</structname> structure, walk
the list of write-side queue structures. </para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-77"><title>Networking</title><para>The following dcmds and walkers are provided to help debug the core
kernel networking stack protocols.</para><sect3 id="modules-78"><title>dcmds</title><variablelist termlength="wholeline"><varlistentry><term><replaceable>address</replaceable> <command>::mi</command>
[<option><gentext type="text">-</gentext>p</option>] [<option><gentext type="text">-</gentext>d</option> | <option><gentext type="text">-</gentext>m</option>]</term><indexterm id="indexterm-265"><primary>Networking</primary><secondary>dcmds</secondary><tertiary><command>::mi</command></tertiary></indexterm><indexterm id="indexterm-266"><primary>dcmds</primary><secondary><command>::mi</command></secondary></indexterm><listitem><para>Given the address of a kernel MI_O, filter and display the MI_O or its payload.
If the <option><gentext type="text">-</gentext>p</option> option is specified, then the address of the corresponding
payload of the MI_O is displayed, otherwise the MI_O itself is displayed.
Specifying filter <option><gentext type="text">-</gentext>d</option> or <option><gentext type="text">-</gentext>m</option> enables the dcmd
to filter device or module MI_O objects respectively.</para></listitem></varlistentry><varlistentry><term><command>::netstat</command> [<option><gentext type="text">-</gentext>av</option>] [<option><gentext type="text">-</gentext>f</option> <literal>inet</literal> | <literal>inet6</literal> | <literal>unix</literal>] [<option><gentext type="text">-</gentext>P</option> <literal>tcp</literal> | <literal>udp</literal>]</term><indexterm id="indexterm-267"><primary>Networking</primary><secondary>dcmds</secondary><tertiary><command>::netstat</command></tertiary></indexterm><indexterm id="indexterm-268"><primary>dcmds</primary><secondary><command>::netstat</command></secondary></indexterm><listitem><para>Show network statistics
and active connections.  If the <option><gentext type="text">-</gentext>a</option> option is present, the
state of all sockets is displayed.  If the <option><gentext type="text">-</gentext>v</option> option is present,
more verbose output is displayed.  If the <option><gentext type="text">-</gentext>f</option> option is present,
only connections associated with the specified address family are displayed.
 If the <option><gentext type="text">-</gentext>P</option> option is present, only connections associated
with the specified protocols are displayed.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::sonode</command> [<option><gentext type="text">-</gentext>f</option> <literal>inet</literal> | <literal>inet6</literal>
| <literal>unix</literal> | <replaceable>id</replaceable>] [<option><gentext type="text">-</gentext>t</option> <literal>stream</literal> | <literal>dgram</literal> | <literal>raw</literal> | <replaceable>id</replaceable>] [<option><gentext type="text">-</gentext>p</option> <replaceable>id</replaceable>]</term><indexterm id="indexterm-269"><primary>Networking</primary><secondary>dcmds</secondary><tertiary><command>::sonode</command></tertiary></indexterm><indexterm id="indexterm-270"><primary>dcmds</primary><secondary><command>::sonode</command></secondary></indexterm><listitem><para>Filters and displays sonode objects. If no address
is given, then the list of AF_UNIX sockets is displayed, otherwise only the
specified sonode is displayed.  If the <option><gentext type="text">-</gentext>f</option> option is present,
then only sockets of the given family will be output. If the <option><gentext type="text">-</gentext>t</option>
option is present, then only sonodes of the given type will be output. If
the <option><gentext type="text">-</gentext>p</option> option is present, then only sockets of the given protocol
will be displayed.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::tcpb</command> [<option><gentext type="text">-</gentext>av</option>] [<option><gentext type="text">-</gentext>P</option> <literal>v4</literal>
| <literal>v6</literal>]</term><indexterm id="indexterm-271"><primary>Networking</primary><secondary>dcmds</secondary><tertiary><command>::tcpb</command></tertiary></indexterm><indexterm id="indexterm-272"><primary>dcmds</primary><secondary><command>::tcpb</command></secondary></indexterm><listitem><para>Filters and displays
tcpb objects. If no address is specified, all connections are walked, otherwise
only the specified tcpb is filtered/displayed. Specifying <option><gentext type="text">-</gentext>a</option>
filters for only active connections and <option><gentext type="text">-</gentext>P</option> can be used to
filter for TCP IPv4 or IPv6 connections. The <command>tcpb</command> dcmd
is intelligent about filtering TCP connections, and if a IPv6 TCP connection
is in a state that would still facilitate a IPv4 connection, the <option><gentext type="text">-</gentext>P</option> filter considers the connection as both IPv4 and IPv6 in much the
same way that <command>::netstat</command> does. If the dcmd is not being
used as a filter and the <option><gentext type="text">-</gentext>v</option> option is specified, then the
output of the dcmd will be verbose.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-79"><title>Walkers</title><variablelist><varlistentry><term>ar</term><indexterm id="indexterm-273"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>ar</tertiary></indexterm><indexterm id="indexterm-274"><primary>Walkers</primary><secondary>ar</secondary></indexterm><listitem><para>Given
the address of an ar, this walker walks all ar objects from the given ar to
the final ar. If no address is specified, all ar objects are walked.</para></listitem></varlistentry><varlistentry><term>icmp</term><indexterm id="indexterm-275"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>icmp</tertiary></indexterm><indexterm id="indexterm-276"><primary>Walkers</primary><secondary>icmp</secondary></indexterm><listitem><para>Given
the address of an icmp, this walker walks all icmp objects from the given
icmp to the final icmp. If no address is specified, all icmp objects are walked.</para></listitem></varlistentry><varlistentry><term>ill</term><indexterm id="indexterm-277"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>ill</tertiary></indexterm><indexterm id="indexterm-278"><primary>Walkers</primary><secondary>ill</secondary></indexterm><listitem><para>Given
the address of an interface link layer structure (ill), this walker walks
all ill objects from the given ill to the final. If no address is specified,
all ill objects are walked.</para></listitem></varlistentry><varlistentry><term>ipc</term><indexterm id="indexterm-279"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>ipc</tertiary></indexterm><indexterm id="indexterm-280"><primary>Walkers</primary><secondary>ipc</secondary></indexterm><listitem><para>Given
the address of an ipc, this walker walks all ipc objects from the given ipc
to the final ipc. If no address is specified, all ipc objects are walked.</para></listitem></varlistentry><varlistentry><term>mi</term><indexterm id="indexterm-281"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>mi</tertiary></indexterm><indexterm id="indexterm-282"><primary>Walkers</primary><secondary>mi</secondary></indexterm><listitem><para>Given
the address of a MI_O, walk all the MI_O's in this MI.</para></listitem></varlistentry><varlistentry><term>sonode</term><indexterm id="indexterm-283"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>sonode</tertiary></indexterm><indexterm id="indexterm-284"><primary>Walkers</primary><secondary>sonode</secondary></indexterm><listitem><para>Given the address of a AF_UNIX sonode, walk the associated list of AF_UNIX
sonodes beginning with the given sonode. If no address is specified, this
walker walks the list of all AF_UNIX sockets.</para></listitem></varlistentry><varlistentry><term>tcpb</term><indexterm id="indexterm-285"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>tcpb</tertiary></indexterm><indexterm id="indexterm-286"><primary>Walkers</primary><secondary>tcpb</secondary></indexterm><listitem><para>Given
the address of a tcpb, this walker walks all TCP connections from the given
tcpb to the final TCP connection. If no address is specified, all tcpb objects
are walked.</para></listitem></varlistentry><varlistentry><term>udp</term><indexterm id="indexterm-287"><primary>Networking</primary><secondary>Walkers</secondary><tertiary>udp</tertiary></indexterm><indexterm id="indexterm-288"><primary>Walkers</primary><secondary>udp</secondary></indexterm><listitem><para>Given
the address of a udp, this walker walks all udp objects from the given udp
to the final udp. If no address is specified, all udp objects are walked.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-42"><title>Files, Processes, and Threads</title><para>This section describes dcmds and walkers used to format and examine
various fundamental file, process, and thread structures in the Solaris kernel. </para><sect3 id="modules-43"><title>dcmds</title><variablelist termlength="wholeline"><varlistentry><term><replaceable>process</replaceable> <command>::fd</command> <replaceable>fd-num</replaceable></term><indexterm id="indexterm-289"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::fd</command></tertiary></indexterm><indexterm id="indexterm-290"><primary>dcmds</primary><secondary><command>::fd</command></secondary></indexterm><listitem><para>Print the <structname>file_t</structname> address corresponding to the file
descriptor <replaceable>fd-num</replaceable> associated with the specified
process.  The process is specified using the virtual address of its <structname>proc_t</structname> structure.</para></listitem></varlistentry><varlistentry><term><replaceable>thread</replaceable> <command>::findstack</command> [ <replaceable>command</replaceable> ]</term><indexterm id="indexterm-291"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::findstack</command></tertiary></indexterm><indexterm id="indexterm-292"><primary>dcmds</primary><secondary><command>::findstack</command></secondary></indexterm><listitem><para>Print the stack trace associated
with the given kernel thread, identified by the virtual address of its <structname>kthread_t</structname> structure.  The dcmd employs several different algorithms
to locate the appropriate stack backtrace.  If an optional command string
is specified, the dot variable is reset to the frame pointer address of the
topmost stack frame, and the specified command is evaluated as if it had been
typed at the command line.  The default command string is “<literal>&lt;.$C0</literal>”; that is, print a stack trace including frame pointers
but no arguments.</para></listitem></varlistentry><varlistentry><term><replaceable>pid</replaceable> <command>::pid2proc</command></term><indexterm id="indexterm-293"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::pid2proc</command></tertiary></indexterm><indexterm id="indexterm-294"><primary>dcmds</primary><secondary><command>::pid2proc</command></secondary></indexterm><listitem><para> Print the <structname>proc_t</structname> address corresponding to the specified PID.  Recall that
MDB's default base is hexadecimal, so decimal PIDs obtained using <olink targetdocent="REFMAN1" localinfo="PGREP-1" type="v-only"><citerefentry><refentrytitle>pgrep</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink> or <olink targetdocent="REFMAN1" localinfo="PS-1" type="v-only"><citerefentry><refentrytitle>ps</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink> should be prefixed with <literal>0t</literal>. </para></listitem></varlistentry><varlistentry><term><replaceable>process</replaceable> <command>::pmap</command>
[<option><gentext type="text">-</gentext>q</option>]</term><indexterm id="indexterm-295"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::pmap</command></tertiary></indexterm><indexterm id="indexterm-296"><primary>dcmds</primary><secondary><command>::pmap</command></secondary></indexterm><listitem><para>Print the memory map of the process indicated by the given process address.
 The dcmd displays output using a format similar to <olink targetdocent="REFMAN1" localinfo="PMAP-1" type="v-only"><citerefentry><refentrytitle>pmap</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink>. If the <option><gentext type="text">-</gentext>q</option>
option is present, the dcmd displays an abbreviated form of its output that
requires less processing time.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::ps</command>
[<option><gentext type="text">-</gentext>fltTP</option>]</term><listitem><para><indexterm id="indexterm-297"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::ps</command></tertiary></indexterm><indexterm id="indexterm-298"><primary>dcmds</primary><secondary><command>::ps</command></secondary></indexterm>Print a summary
of the information related to the specified process, or all active system
processes, similar to <olink targetdocent="REFMAN1" localinfo="PS-1" type="v-only"><citerefentry><refentrytitle>ps</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.
 If the <option><gentext type="text">-</gentext>f</option> option is specified, the full command name and
initial arguments are printed. If the <option><gentext type="text">-</gentext>l</option> option is specified,
the LWPs associated with each process are printed.  If the <option><gentext type="text">-</gentext>t</option>
option is specified, the kernel threads associated with each process LWP are
printed. If the <option><gentext type="text">-</gentext>T</option> option is specified, the task ID associated
with each process is displayed. If the <option><gentext type="text">-</gentext>P</option> option is specified,
the project ID associated with each           process is displayed. </para></listitem></varlistentry><varlistentry><term><command>::ptree</command></term><indexterm id="indexterm-299"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::ptree</command></tertiary></indexterm><indexterm id="indexterm-300"><primary>dcmds</primary><secondary><command>::ptree</command></secondary></indexterm><listitem><para>Print a process tree, with child processes indented
from their respective parent processes.  The dcmd displays output using a
format similar to <olink targetdocent="REFMAN1" localinfo="PTREE-1" type="v-only"><citerefentry><refentrytitle>ptree</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.</para></listitem></varlistentry><varlistentry><term><command><replaceable>address</replaceable> ::task</command><indexterm id="indexterm-301"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::task</command></tertiary></indexterm><indexterm id="indexterm-302"><primary>dcmds</primary><secondary><command>::task</command></secondary></indexterm></term><listitem><para>Print a list of the active kernel task
structures and their associated ID numbers and attributes. The process task
ID is described in more detail in <literal>settaskid</literal>(2). </para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::thread</command> [<option><gentext type="text">-</gentext>bdfimps</option>]<indexterm id="indexterm-303"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::thread</command></tertiary></indexterm><indexterm id="indexterm-304"><primary>dcmds</primary><secondary><command>::thread</command></secondary></indexterm></term><listitem><para>Display properties of the specified kernel <structname>kthread_t</structname> structure.  If no <structname>kthread_t</structname> address
is specified, the properties of all kernel threads are displayed.  The dcmd
options are used to control which output columns are shown.  If no options
are present, the <option><gentext type="text">-</gentext>i</option> option is enabled by default.  If the <option><gentext type="text">-</gentext>b</option> option is present, information relating to the thread's turnstile
and blocking synchronization object is shown. If the <option><gentext type="text">-</gentext>d</option> option
is present, the thread's dispatcher priority, binding, and last dispatch time
is shown.  If the <option><gentext type="text">-</gentext>f</option> option is present, threads whose state
is TS_FREE are elided from the output.  If the <option><gentext type="text">-</gentext>i</option> option is
present (the default), thread state, flags, priority, and interrupt information
is shown.  If the <option><gentext type="text">-</gentext>m</option> option is present, all of the other output
options are merged together on to a single output line.  If the <option><gentext type="text">-</gentext>p</option> option is present, the thread's process, LWP, and credential pointers
are displayed.  If the <option><gentext type="text">-</gentext>s</option> option is present, the thread's
signal queue and masks of pending and held signals are shown.</para></listitem></varlistentry><varlistentry><term><replaceable>vnode</replaceable> <command>::whereopen</command></term><indexterm id="indexterm-305"><primary>Files, Processes, and Threads</primary><secondary>dcmds</secondary><tertiary><command>::whereopen</command></tertiary></indexterm><indexterm id="indexterm-306"><primary>dcmds</primary><secondary><command>::whereopen</command></secondary></indexterm><listitem><para>Given a <structname>vnode_t</structname> address, print the <structname>proc_t</structname> addresses of all processes that have this vnode currently
open in their file table. </para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-44"><title>Walkers</title><variablelist><varlistentry><term>file</term><indexterm id="indexterm-307"><primary>Files, Processes, and Threads</primary><secondary>Walkers</secondary><tertiary>file</tertiary></indexterm><indexterm id="indexterm-308"><primary>Walkers</primary><secondary>file</secondary></indexterm><listitem><para>Given the address of a <structname>proc_t</structname> structure
as a starting point, iterate over the set of open files (<structname>file_t</structname> structures) associated with the specified process.  The <structname>file_t</structname> structure is defined in <literal>&lt;sys/file.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>proc</term><indexterm id="indexterm-309"><primary>Files, Processes, and Threads</primary><secondary>Walkers</secondary><tertiary>proc</tertiary></indexterm><indexterm id="indexterm-310"><primary>Walkers</primary><secondary>proc</secondary></indexterm><listitem><para>Iterate over the active process (<structname>proc_t</structname>)
structures.  This structure is defined in <literal>&lt;sys/proc.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>task</term><listitem><para>Given a task pointer, iterate
over the list of <structname>proc_t</structname> structures for processes
that are members of the given task</para></listitem></varlistentry><varlistentry><term>thread</term><indexterm id="indexterm-311"><primary>Files, Processes, and Threads</primary><secondary>Walkers</secondary><tertiary>thread</tertiary></indexterm><indexterm id="indexterm-312"><primary>Walkers</primary><secondary>thread</secondary></indexterm><listitem><para>Iterate over a set of kernel thread (<structname>kthread_t</structname>) structures.  If the global walk is invoked, all kernel
threads are returned by the walker. If a local walk is invoked using a <structname>proc_t</structname> address as the starting point, the set of threads associated
with the specified process is returned. The <structname>kthread_t</structname>
structure is defined in <literal>&lt;sys/thread.h&gt;</literal>.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-45"><title>Synchronization Primitives</title><para>This section describes dcmds and walkers used to examine particular
kernel synchronization primitives.  The semantics of each primitive are discussed
in the corresponding (9f) section of the manual pages. </para><sect3 id="modules-46"><title>dcmds</title><variablelist><varlistentry><term><replaceable>rwlock</replaceable> <command>::rwlock</command></term><indexterm id="indexterm-313"><primary>Synchronization Primitives</primary><secondary>dcmds</secondary><tertiary><command>::rwlock</command></tertiary></indexterm><indexterm id="indexterm-314"><primary>dcmds</primary><secondary><command>::rwlock</command></secondary></indexterm><listitem><para>Given the address of a readers-writers
lock (see <olink targetdocent="REFMAN9F" localinfo="RWLOCK-9F" type="v-only"><citerefentry><refentrytitle>rwlock</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>),
display the current state of the lock and the list of waiting threads.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::sobj2ts</command></term><indexterm id="indexterm-315"><primary>Synchronization Primitives</primary><secondary>dcmds</secondary><tertiary><command>::sobj2ts</command></tertiary></indexterm><indexterm id="indexterm-316"><primary>dcmds</primary><secondary><command>::sobj2ts</command></secondary></indexterm><listitem><para>Convert the address
of a synchronization object to the address of the corresponding turnstile
and print the turnstile address.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::turnstile</command></term><indexterm id="indexterm-317"><primary>Synchronization Primitives</primary><secondary>dcmds</secondary><tertiary><command>::turnstile</command></tertiary></indexterm><indexterm id="indexterm-318"><primary>dcmds</primary><secondary><command>::turnstile</command></secondary></indexterm><listitem><para>Display the properties of the specified <structname>turnstile_t</structname>.
 If no <structname>turnstile_t</structname> address is specified, the dcmd
displays the properties of all turnstiles.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::wchaninfo</command> [<option><gentext type="text">-</gentext>v</option>]</term><indexterm id="indexterm-319"><primary>Synchronization Primitives</primary><secondary>dcmds</secondary><tertiary><command>::wchaninfo</command></tertiary></indexterm><indexterm id="indexterm-320"><primary>dcmds</primary><secondary><command>::wchaninfo</command></secondary></indexterm><listitem><para>Given the address of a condition variable (see <olink targetdocent="REFMAN9F" localinfo="CONDVAR-9F" type="v-only"><citerefentry><refentrytitle>condvar</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>) or semaphore
(see <olink targetdocent="REFMAN9F" localinfo="SEMAPHORE-9F" type="v-only"><citerefentry><refentrytitle>semaphore</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>),
display the current number of waiters on this object.  If no explicit address
is specified, display all such objects that have waiting threads.  If the <option><gentext type="text">-</gentext>v</option> option is specified, display the list of threads that are blocked
on each object.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-47"><title>Walkers</title><variablelist><varlistentry><term>blocked</term><indexterm id="indexterm-321"><primary>Synchronization Primitives</primary><secondary>Walkers</secondary><tertiary>blocked</tertiary></indexterm><indexterm id="indexterm-322"><primary>Walkers</primary><secondary>blocked</secondary></indexterm><listitem><para>Given the address of a synchronization object (such as a <olink targetdocent="REFMAN9F" localinfo="MUTEX-9F" type="v-only"><citerefentry><refentrytitle>mutex</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>
or <olink targetdocent="REFMAN9F" localinfo="RWLOCK-9F" type="v-only"><citerefentry><refentrytitle>rwlock</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>),
iterate over the list of blocked kernel threads.</para></listitem></varlistentry><varlistentry><term>wchan</term><indexterm id="indexterm-323"><primary>Synchronization Primitives</primary><secondary>Walkers</secondary><tertiary>wchan</tertiary></indexterm><indexterm id="indexterm-324"><primary>Walkers</primary><secondary>wchan</secondary></indexterm><listitem><para>Given the address of a condition variable (see <olink targetdocent="REFMAN9F" localinfo="CONDVAR-9F" type="v-only"><citerefentry><refentrytitle>condvar</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>) or semaphore
(see <olink targetdocent="REFMAN9F" localinfo="SEMAPHORE-9F" type="v-only"><citerefentry><refentrytitle>semaphore</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>),
iterate over the list of blocked kernel threads.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-48"><title>Cyclics</title><para>The cyclic subsystem is a low-level kernel subsystem that provides high
resolution, per-CPU interval timer facilities to other kernel services and
programming interfaces.</para><sect3 id="modules-49"><title>dcmds</title><variablelist><varlistentry><term><command>::cycinfo</command> [<option><gentext type="text">-</gentext>vV</option>]</term><indexterm id="indexterm-325"><primary>Cyclics</primary><secondary>dcmds</secondary><tertiary><command>::cycinfo</command></tertiary></indexterm><indexterm id="indexterm-326"><primary>dcmds</primary><secondary><command>::cycinfo</command></secondary></indexterm><listitem><para>Display the cyclic subsystem per-CPU state for
each CPU. If the <option><gentext type="text">-</gentext>v</option> option is present, a more verbose display
is shown. If the <option><gentext type="text">-</gentext>V</option> option is present, an even more verbose
display than <option><gentext type="text">-</gentext>v</option> is shown.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::cyclic</command></term><indexterm id="indexterm-327"><primary>Cyclics</primary><secondary>dcmds</secondary><tertiary><command>::cyclic</command></tertiary></indexterm><indexterm id="indexterm-328"><primary>dcmds</primary><secondary><command>::cyclic</command></secondary></indexterm><listitem><para>Format and display the <literal>cyclic_t</literal>
at the specified address.</para></listitem></varlistentry><varlistentry><term><command>::cyccover</command></term><indexterm id="indexterm-329"><primary>Cyclics</primary><secondary>dcmds</secondary><tertiary><command>::cyccover</command></tertiary></indexterm><indexterm id="indexterm-330"><primary>dcmds</primary><secondary><command>::cyccover</command></secondary></indexterm><listitem><para>Display cyclic subsystem code coverage information.  This
information is available only in a DEBUG kernel.</para></listitem></varlistentry><varlistentry><term><command>::cyctrace</command></term><indexterm id="indexterm-331"><primary>Cyclics</primary><secondary>dcmds</secondary><tertiary><command>::cyctrace</command></tertiary></indexterm><indexterm id="indexterm-332"><primary>dcmds</primary><secondary><command>::cyctrace</command></secondary></indexterm><listitem><para>Display cyclic subsystem trace information.  This information
is available only in a DEBUG kernel.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-50"><title>Walkers</title><variablelist><varlistentry><term>cyccpu</term><indexterm id="indexterm-333"><primary>Cyclics</primary><secondary>Walkers</secondary><tertiary>cyccpu</tertiary></indexterm><indexterm id="indexterm-334"><primary>Walkers</primary><secondary>cyccpu</secondary></indexterm><listitem><para>Iterate over the per-CPU <structname>cyc_cpu_t</structname> structures.  This
structure is defined in <literal>&lt;sys/cyclic_impl.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>cyctrace</term><indexterm id="indexterm-335"><primary>Cyclics</primary><secondary>Walkers</secondary><tertiary>cyctrace</tertiary></indexterm><indexterm id="indexterm-336"><primary>Walkers</primary><secondary>cyctrace</secondary></indexterm><listitem><para>Iterate over the cyclic trace buffer structures.  This information is only
available in a DEBUG kernel.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-71"><title>Task Queues</title><para>The task queue subsystem provides general-purpose asynchronous task
scheduling for a variety of clients in the kernel.</para><sect3 id="modules-72"><title>dcmds</title><variablelist><varlistentry><term><replaceable>address</replaceable> <command>::taskq_entry</command></term><indexterm id="indexterm-337"><primary>Task Queues</primary><secondary>dcmds</secondary><tertiary><command>::taskq_entry</command></tertiary></indexterm><indexterm id="indexterm-338"><primary>dcmds</primary><secondary><command>::taskq_entry</command></secondary></indexterm><listitem><para>Print the contents
of the specified struct <structname>taskq_entry</structname>.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-73"><title>Walkers</title><variablelist><varlistentry><term>taskq_entry</term><indexterm id="indexterm-339"><primary>Task Queues</primary><secondary>Walkers</secondary><tertiary>taskq_entry</tertiary></indexterm><indexterm id="indexterm-340"><primary>Walkers</primary><secondary>taskq_entry</secondary></indexterm><listitem><para>Given the addresss of a <structname>taskq</structname> structure,
iterate over the list of <structname>taskq_entry</structname> structures.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-74"><title>Error Queues</title><para>The error queue subsystem provides general-purpose asynchronous error
event processing for platform-specific error handling code.</para><sect3 id="modules-75"><title>dcmds</title><variablelist><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::errorq</command></term><indexterm id="indexterm-341"><primary>Error Queues</primary><secondary>dcmds</secondary><tertiary><command>::errorq</command></tertiary></indexterm><indexterm id="indexterm-342"><primary>dcmds</primary><secondary><command>::errorq</command></secondary></indexterm><listitem><para>Display a summary
of information relating to the specified error queue. If no address is given,
display information relating to all system error queues.  The address, name,
queue length, and data element size for each queue are displayed, along with
various queue statistics.</para></listitem></varlistentry></variablelist></sect3><sect3 id="modules-76"><title>Walkers</title><variablelist><varlistentry><term>errorq</term><indexterm id="indexterm-343"><primary>Error Queues</primary><secondary>Walkers</secondary><tertiary>errorq</tertiary></indexterm><indexterm id="indexterm-344"><primary>Walkers</primary><secondary>errorq</secondary></indexterm><listitem><para>Walk the list of system error queues and return the address of each
individual error queue.</para></listitem></varlistentry><varlistentry><term>errorq_data</term><indexterm id="indexterm-345"><primary>Error Queues</primary><secondary>Walkers</secondary><tertiary>errorq_data</tertiary></indexterm><indexterm id="indexterm-346"><primary>Walkers</primary><secondary>errorq_data</secondary></indexterm><listitem><para>Given the address of an error queue, return the address of
each pending error event data buffer.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="modules-63"><title>Configuration</title><para>This section describes dcmds that can be used to examine system configuration
data.</para><sect3 id="modules-64"><title>dcmds</title><variablelist><varlistentry><term><command>::system</command></term><indexterm id="indexterm-347"><primary>Configuration</primary><secondary>dcmds</secondary><tertiary><command>::system</command></tertiary></indexterm><indexterm id="indexterm-348"><primary>dcmds</primary><secondary><command>::system</command></secondary></indexterm><listitem><para>Display the contents of the <literal>system</literal>(4) configuration
file at the time the kernel parsed the file during system initialization.</para></listitem></varlistentry></variablelist></sect3></sect2></sect1><sect1 id="chapter1-2"><title>Interprocess Communication Debugging Support (<literal>ipc</literal>)</title><para>The <literal>ipc</literal> module provides debugging support for the
implementation of the message queue, semaphore, and shared memory interprocess
communication primitives.</para><sect2 id="chapter1-3"><title>dcmds</title><variablelist><varlistentry><term><command>::ipcs</command> [<option><gentext type="text">-</gentext>l</option>]</term><listitem><para><indexterm id="indexterm-349"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::ipcs</command></tertiary></indexterm><indexterm id="indexterm-350"><primary>dcmds</primary><secondary><command>::ipcs</command></secondary></indexterm>Display
a listing of system-wide IPC identifiers, corresponding to known message queues,
semaphores, and shared memory segments.  If the <option><gentext type="text">-</gentext>l</option> option
is specified, a longer listing of information is shown.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::msg</command>
[<option><gentext type="text">-</gentext>l</option>] [<option><gentext type="text">-</gentext>t</option> <replaceable>type</replaceable>]</term><listitem><para><indexterm id="indexterm-351"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::msg</command></tertiary></indexterm><indexterm id="indexterm-352"><primary>dcmds</primary><secondary><command>::msg</command></secondary></indexterm>Display the properties of the specified message queue element
(struct <structname>msg</structname>).  If the <option><gentext type="text">-</gentext>l</option> option is
present, the raw contents of the message are displayed in hexadecimal and
ASCII.  If the <option><gentext type="text">-</gentext>t</option> option is present, it can be used to filter
the output and only display messages of the specified type.  This can be useful
when piping the output of the <literal>msgqueue</literal> walker to <command>::msg</command>.</para></listitem></varlistentry><varlistentry><term><replaceable>id</replaceable> <command>::msqid</command>
[<option><gentext type="text">-</gentext>k</option>]</term><listitem><para><indexterm id="indexterm-353"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::msqid</command></tertiary></indexterm><indexterm id="indexterm-354"><primary>dcmds</primary><secondary><command>::msqid</command></secondary></indexterm>Convert the specified message queue
IPC identifier to a pointer to the corresponding kernel implementation structure
and print the address of this kernel structure.  If the <option><gentext type="text">-</gentext>k</option>
option is present, the <replaceable>id</replaceable> is instead interpreted
as a message queue key to match (see <literal>msgget</literal>(2)).</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::msqid_ds</command> [<option><gentext type="text">-</gentext>l</option>]</term><indexterm id="indexterm-355"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::msqid_ds</command></tertiary></indexterm><indexterm id="indexterm-356"><primary>dcmds</primary><secondary><command>::msqid_ds</command></secondary></indexterm><listitem><para>Print the specified <structname>msqid_ds</structname> structure or a table of the active <structname>msqid_ds</structname> structures (message queue identifiers).  If the <option><gentext type="text">-</gentext>l</option>
option is specified, a longer listing of information is displayed.</para></listitem></varlistentry><varlistentry><term><replaceable>id</replaceable> <command>::semid</command>
[<option><gentext type="text">-</gentext>k</option>]</term><indexterm id="indexterm-357"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::semid</command></tertiary></indexterm><indexterm id="indexterm-358"><primary>dcmds</primary><secondary><command>::semid</command></secondary></indexterm><listitem><para>Convert the specified
semaphore IPC identifier to a pointer to       the corresponding kernel implementation
structure and print the       address of this kernel structure.  If the <option><gentext type="text">-</gentext>k</option> option is present, the <replaceable>id</replaceable> is instead
interpreted as a semaphore key to match (see <literal>semget</literal>(2)).</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::semid_ds</command> [<option><gentext type="text">-</gentext>l</option>]</term><indexterm id="indexterm-359"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::semid_ds</command></tertiary></indexterm><indexterm id="indexterm-360"><primary>dcmds</primary><secondary><command>::semid_ds</command></secondary></indexterm><listitem><para>Print the specified <structname>semid_ds</structname> structure or a table of the active <structname>semid_ds</structname> structures (semaphore identifiers).  If the <option><gentext type="text">-</gentext>l</option>
option is specified, a longer listing of information is displayed.</para></listitem></varlistentry><varlistentry><term><replaceable>id</replaceable> <command>::shmid</command>
[<option><gentext type="text">-</gentext>k</option>]</term><indexterm id="indexterm-361"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::shmid</command></tertiary></indexterm><indexterm id="indexterm-362"><primary>dcmds</primary><secondary><command>::shmid</command></secondary></indexterm><listitem><para>Convert the specified
shared memory IPC identifier to a pointer to the corresponding kernel implementation
structure and print the address of this kernel structure.  If the <option><gentext type="text">-</gentext>k</option> option is present, the <replaceable>id</replaceable> is instead
interpreted as a shared memory key to match (see <literal>shmget</literal>(2)).</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::shmid_ds</command> [<option><gentext type="text">-</gentext>l</option>]</term><indexterm id="indexterm-363"><primary>dcmds</primary><secondary><command>::shmid_ds</command></secondary></indexterm><indexterm id="indexterm-364"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::shmid_ds</command></tertiary></indexterm><listitem><para>Print the specified <structname>shmid_ds</structname> structure or a table of the active <structname>shmid_ds</structname> structures (shared memory segment identifiers).  If the <option><gentext type="text">-</gentext>l</option> option is specified, a longer listing of information is displayed.</para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-62"><title>Walkers</title><variablelist><varlistentry><term>msg</term><indexterm id="indexterm-365"><primary>Walkers</primary><secondary>msg</secondary></indexterm><indexterm id="indexterm-366"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>Walkers</secondary><tertiary>msg</tertiary></indexterm><listitem><para>Walk the active <structname>msqid_ds</structname> structures corresponding to message queue identifiers.
 This structure is defined in <literal>&lt;sys/msg.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>msgqueue</term><indexterm id="indexterm-367"><primary>Walkers</primary><secondary>msgqueue</secondary></indexterm><indexterm id="indexterm-368"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>Walkers</secondary><tertiary>msgqueue</tertiary></indexterm><listitem><para>Iterate over the <structname>message</structname> structures that are currently enqueued on the specified
message queue.</para></listitem></varlistentry><varlistentry><term>sem</term><indexterm id="indexterm-369"><primary>Walkers</primary><secondary>sem</secondary></indexterm><indexterm id="indexterm-370"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>Walkers</secondary><tertiary>sem</tertiary></indexterm><listitem><para>Walk the active <structname>semid_ds</structname> structures corresponding to semaphore identifiers. 
This structure is defined in <literal>&lt;sys/sem.h&gt;</literal>.</para></listitem></varlistentry><varlistentry><term>shm</term><indexterm id="indexterm-371"><primary>Walkers</primary><secondary>shm</secondary></indexterm><indexterm id="indexterm-372"><primary>Interprocess Communication Debugging Support (<literal>ipc</literal>)</primary><secondary>Walkers</secondary><tertiary>shm</tertiary></indexterm><listitem><para>Walk the active <structname>shmid_ds</structname> structures corresponding to shared memory segment identifiers.
 This structure is defined in <literal>&lt;sys/shm.h&gt;</literal>.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-5"><title>Loopback File System Debugging Support (<literal>lofs</literal>)</title><para>The <literal>lofs</literal> module provides debugging support for the <olink targetdocent="REFMAN7" localinfo="LOFS-7FS" type="v-only"><citerefentry><refentrytitle>lofs</refentrytitle><manvolnum><gentext type="text">(</gentext>7FS<gentext type="text">)</gentext></manvolnum></citerefentry></olink> file
system.</para><sect2 id="modules-6"><title>dcmds</title><variablelist><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::lnode</command></term><indexterm id="indexterm-373"><primary>dcmds</primary><secondary><command>::lnode</command></secondary></indexterm><indexterm id="indexterm-374"><primary>Loopback File System Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::lnode</command></tertiary></indexterm><listitem><para>Print the specified <structname>lnode_t</structname>, or a table of the active <structname>lnode_t</structname>
structures in the kernel.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::lnode2dev</command></term><indexterm id="indexterm-375"><primary>dcmds</primary><secondary><command>::lnode2dev</command></secondary></indexterm><indexterm id="indexterm-376"><primary>Loopback File System Debugging Support (<literal>lofs</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::lnode2dev</command></tertiary></indexterm><listitem><para>Print the <structname>dev_t</structname> (<structname>vfs_dev</structname>) for the underlying loopback mounted filesystem corresponding
to the given <structname>lnode_t</structname> address. </para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::lnode2rdev</command></term><indexterm id="indexterm-377"><primary>dcmds</primary><secondary><command>::lnode2rdev</command></secondary></indexterm><indexterm id="indexterm-378"><primary>Loopback File System Debugging Support (<literal>lofs</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::lnode2rdev</command></tertiary></indexterm><listitem><para>Print the <structname>dev_t</structname> (<structname>li_rdev</structname>) for the underlying loopback mounted file system corresponding
to the given <structname>lnode_t</structname> address. </para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-7"><title>Walkers</title><variablelist><varlistentry><term>lnode</term><indexterm id="indexterm-379"><primary>Walkers</primary><secondary>lnode</secondary></indexterm><indexterm id="indexterm-380"><primary>Loopback File System Debugging Support (<literal>lofs</literal>)</primary><secondary>Walkers</secondary><tertiary>lnode</tertiary></indexterm><listitem><para>Walk the active <structname>lnode_t</structname> structures in the kernel.  This structure is defined
in <literal>&lt;sys/fs/lofs_node.h&gt;</literal>.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-23"><title>Internet Protocol Module Debugging Support (<literal>ip</literal>)</title><para>The <literal>ip</literal> module provides debugging support for the <olink targetdocent="REFMAN7" localinfo="LC-IP-7P" type="v-only"><citerefentry><refentrytitle>ip</refentrytitle><manvolnum><gentext type="text">(</gentext>7P<gentext type="text">)</gentext></manvolnum></citerefentry></olink> driver</para><sect2 id="modules-2"><title>dcmds</title><variablelist><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::ire</command> [<option><gentext type="text">-</gentext>q</option>]</term><indexterm id="indexterm-381"><primary>dcmds</primary><secondary><command>::ire</command></secondary></indexterm><indexterm id="indexterm-382"><primary>Internet Protocol Module Debugging Support (<literal>ip</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::ire</command></tertiary></indexterm><listitem><para>Print the specified <structname>ire_t</structname>, or a table of the active <structname>ire_t</structname>
structures in the kernel.  If the <option><gentext type="text">-</gentext>q</option> flag is specified, the
send and receive queue pointers are printed instead of the source and destination
addresses.</para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-3"><title>Walkers</title><variablelist><varlistentry><term>ire</term><indexterm id="indexterm-383"><primary>Walkers</primary><secondary>ire</secondary></indexterm><indexterm id="indexterm-384"><primary>Internet Protocol Module Debugging Support (<literal>ip</literal>)</primary><secondary>Walkers</secondary><tertiary>ire</tertiary></indexterm><listitem><para>Walk the active <structname>ire</structname> (Internet Route Entry) structures in the kernel. This structure
is defined in <literal>&lt;inet/ip.h&gt;</literal>.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-4"><title>Kernel Runtime Link Editor Debugging Support (<literal>krtld</literal>)</title><para>This section describes the debugging support for the kernel runtime
link editor, which is responsible for loading kernel modules and drivers.</para><sect2 id="modules-8"><title>dcmds</title><variablelist><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::modctl</command></term><indexterm id="indexterm-385"><primary>dcmds</primary><secondary><command>::modctl</command></secondary></indexterm><indexterm id="indexterm-386"><primary>Kernel Runtime Link Editor Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::modctl</command></tertiary></indexterm><listitem><para>Print the specified <structname>modctl</structname>, or a table of the
active <structname>modctl</structname> structures in the kernel.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::modhdrs</command></term><indexterm id="indexterm-387"><primary>dcmds</primary><secondary><command>::modhdrs</command></secondary></indexterm><indexterm id="indexterm-388"><primary>Kernel Runtime Link Editor Debugging Support (<literal>krtld</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::modhdrs</command></tertiary></indexterm><listitem><para>Given the address of a <structname>modctl</structname>
structure, print the module's ELF executable header and section headers.</para></listitem></varlistentry><varlistentry><term><command>::modinfo</command></term><indexterm id="indexterm-389"><primary>dcmds</primary><secondary><command>::modinfo</command></secondary></indexterm><indexterm id="indexterm-390"><primary>Kernel Runtime Link Editor Debugging Support (<literal>krtld</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::modinfo</command></tertiary></indexterm><listitem><para>Print information about the active kernel modules, similar to the output
of the <literal>/usr/sbin/modinfo</literal>
command.</para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-9"><title>Walkers</title><variablelist><varlistentry><term>modctl</term><indexterm id="indexterm-391"><primary>Walkers</primary><secondary>modctl</secondary></indexterm><indexterm id="indexterm-392"><primary>Kernel Runtime Link Editor Debugging Support (<literal>krtld</literal>)</primary><secondary>Walkers</secondary><tertiary>modctl</tertiary></indexterm><listitem><para>Walk the list of active
modctl structures in the kernel.  This structure is defined in <literal>&lt;sys/modctl.h&gt;</literal>.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-65"><title>USB Framework Debugging Support (<literal>uhci</literal>)</title><para>The <literal>uchi</literal> module provides debugging support for the
host controller interface portion of the Universal Serial Bus (USB) framework.</para><sect2 id="modules-66"><title>dcmds</title><variablelist><varlistentry><term><replaceable>address</replaceable> <command>::uhci_qh</command> [<option><gentext type="text">-</gentext>bd</option>]</term><listitem><para><indexterm id="indexterm-393"><primary>dcmds</primary><secondary><command>::uhci_qh</command></secondary></indexterm><indexterm id="indexterm-394"><primary>USB Framework Debugging Support (<literal>uhci</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::uhci_qh</command></tertiary></indexterm>Given the address of a USB UHCI
controller Queue Head (QH) structure, print the contents of the structure.
 If the <option><gentext type="text">-</gentext>b</option> option is present iterate over the <literal>link_ptr</literal> chain, printing all QHs found.  If the <option><gentext type="text">-</gentext>d</option> option
is present, iterate over the <literal>element_ptr</literal> chain, printing
all TDs found.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::uhci_td</command> [<option><gentext type="text">-</gentext>d</option>]</term><listitem><para><indexterm id="indexterm-395"><primary>dcmds</primary><secondary><command>::uhci_td</command></secondary></indexterm><indexterm id="indexterm-396"><primary>USB Framework Debugging Support (<literal>uhci</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::uhci_td</command></tertiary></indexterm>Given the address of a USB UHCI
controller Transaction Descriptor (TD)  structure, print the contents of the
structure.  Note this only works for Control and Interrupt TDs.  If the <option><gentext type="text">-</gentext>d</option> option is present, iterate over the <literal>element_ptr</literal>
chain, printing all TDs found. </para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-67"><title>Walkers</title><variablelist><varlistentry><term>uhci_qh</term><indexterm id="indexterm-397"><primary>Walkers</primary><secondary>uhci_qh</secondary></indexterm><indexterm id="indexterm-398"><primary>USB Framework Debugging Support (<literal>uhci</literal>)</primary><secondary>Walkers</secondary><tertiary>uhci_qh</tertiary></indexterm><listitem><para>Given the address
of a USB UHCI controller Queue Head (QH) structure, iterate over the list
of such structures.</para></listitem></varlistentry><varlistentry><term>uhci_td</term><indexterm id="indexterm-399"><primary>Walkers</primary><secondary>uhci_td</secondary></indexterm><indexterm id="indexterm-400"><primary>USB Framework Debugging Support (<literal>uhci</literal>)</primary><secondary>Walkers</secondary><tertiary>uhci_td</tertiary></indexterm><listitem><para>Given the address
of a USB UHCI controller Queue Head Descriptor (TD) structure, iterate over
the list of such structures.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-68"><title>USB Framework Debugging Support (<literal>usba</literal>)</title><para>The <literal>usba</literal> module provides debugging support for the
platform-independent Universal Serial Bus (USB) framework.</para><sect2 id="modules-69"><title>dcmds</title><variablelist><varlistentry><term><command>::usba_debug_buf</command></term><listitem><para><indexterm id="indexterm-401"><primary>dcmds</primary><secondary><command>::usba_debug_buf</command></secondary></indexterm><indexterm id="indexterm-402"><primary>USB Framework Debugging Support (<literal>usba</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::usba_debug_buf</command></tertiary></indexterm>Print
the USB debugging information buffer.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::usb_hcdi_cb</command></term><listitem><para><indexterm id="indexterm-403"><primary>dcmds</primary><secondary><command>::usb_hcdi_cb</command></secondary></indexterm><indexterm id="indexterm-404"><primary>USB Framework Debugging Support (<literal>usba</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::usb_hcdi_cb</command></tertiary></indexterm>Given the address of a host controller callback
structure (struct <structname>usb_hcdi_cb</structname>), print summary information
for this callback.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::usb_device</command> [<option><gentext type="text">-</gentext>pv</option>]</term><listitem><para><indexterm id="indexterm-405"><primary>dcmds</primary><secondary><command>::usb_device</command></secondary></indexterm><indexterm id="indexterm-406"><primary>USB Framework Debugging Support (<literal>usba</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::usb_device</command></tertiary></indexterm>Given the address of a <structname>usb_device</structname> structure, print summary information. If no address
is supplied, this dcmd walks the global list of <structname>usb_device</structname>
structures.  If the <option><gentext type="text">-</gentext>p</option> option is present, also list information
for all open pipes on this device.  If the <option><gentext type="text">-</gentext>v</option> option is present,
list verbose information for each device.</para></listitem></varlistentry><varlistentry><term><replaceable>address</replaceable> <command>::usb_pipe_handle</command></term><listitem><para><indexterm id="indexterm-407"><primary>dcmds</primary><secondary><command>::usb_pipe_handle</command></secondary></indexterm><indexterm id="indexterm-408"><primary>USB Framework Debugging Support (<literal>usba</literal>)</primary><secondary>dcmds</secondary><tertiary><command>::usb_pipe_handle</command></tertiary></indexterm>Given the address of a USB pipe handle structure
(struct <structname>usb_pipe_handle_impl</structname>), print summary information
for this handle.</para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-70"><title>Walkers</title><variablelist><varlistentry><term>usb_hcdi_cb</term><listitem><indexterm id="indexterm-409"><primary>Walkers</primary><secondary>usb_hcdi_cb</secondary></indexterm><indexterm id="indexterm-410"><primary>USB Framework Debugging Support (<literal>usba</literal>)</primary><secondary>Walkers</secondary><tertiary>usb_hcdi_cb</tertiary></indexterm><para>Given
the address of a USB host controller devinfo node, iterate over the list of <structname>usb_hcdi_cb_t</structname> structs for the controller.</para></listitem></varlistentry><varlistentry><term>usba_list_entry</term><listitem><indexterm id="indexterm-411"><primary>Walkers</primary><secondary>usba_list_entry</secondary></indexterm><indexterm id="indexterm-412"><primary>USB Framework Debugging Support (<literal>usba</literal>)</primary><secondary>Walkers</secondary><tertiary>usba_list_entry</tertiary></indexterm><para>Given the address of a <structname>usba_list_entry</structname> structure,
iterate over the chain of such structures.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-10" arch="ia"><title><gentext type="text">x86: </gentext>Platform Debugging Support (<literal>unix</literal>)</title><para>These dcmds and walkers are specific to IA.</para><sect2 id="modules-11"><title>dcmds</title><variablelist termlength="wholeline"><varlistentry><term>[ <replaceable>cpuid</replaceable> | <replaceable>address</replaceable> ] <command>::ttrace</command> [<option><gentext type="text">-</gentext>x</option>]</term><listitem><para><indexterm id="indexterm-413"><primary>dcmds</primary><secondary><command>::ttrace</command></secondary></indexterm><indexterm id="indexterm-414"><primary>Platform Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::ttrace</command></tertiary></indexterm>Display trap trace records in reverse
chronological order.  The trap trace facility is available only in DEBUG kernels.
 If an explicit dot value is specified, this is interpreted as either a CPU
ID number or a trap trace record address, depending on the precise value.
 If a CPU ID is specified, the output is restricted to the buffer from that
CPU. If a record address is specified, only that record is formatted. If the <option><gentext type="text">-</gentext>x</option> option is specified, the complete raw record is displayed.</para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-12"><title>Walkers</title><variablelist><varlistentry><term>ttrace</term><indexterm id="indexterm-415"><primary>Walkers</primary><secondary>ttrace</secondary></indexterm><indexterm id="indexterm-416"><primary>Platform Debugging Support</primary><secondary>Walkers</secondary><tertiary>ttrace</tertiary></indexterm><listitem><para>Walk the list of trap trace record addresses in reverse chronological
order.  The trap trace facility is available only in DEBUG kernels.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-16" arch="sparc"><title><gentext type="text">SPARC: </gentext>sun4m Platform Debugging Support (<literal>unix</literal>)</title><para>These dcmds and walkers are specific to the SPARC sun4m platform.</para><sect2 id="modules-17"><title>dcmds</title><variablelist termlength="wholeline"><varlistentry><term>[ <replaceable>cpuid</replaceable> | <replaceable>address</replaceable> ] <command>::ttrace</command> [<option><gentext type="text">-</gentext>x</option>]</term><listitem><para><indexterm id="indexterm-417"><primary>dcmds</primary><secondary><command>::ttrace</command></secondary></indexterm><indexterm id="indexterm-418"><primary>Platform Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::ttrace</command></tertiary></indexterm>Display trap trace records in reverse
chronological order.  The trap trace facility is available only in DEBUG kernels.
 If an explicit dot value is specified, this is interpreted as either a CPU
ID number or a trap trace record address, depending on the precise value.
 If a CPU ID is specified, the output is restricted to the buffer from that
CPU. If a record address is specified, only that record is formatted. If the <option><gentext type="text">-</gentext>x</option> option is specified, the complete raw record is displayed.</para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-18"><title>Walkers</title><variablelist><varlistentry><term>ttrace</term><indexterm id="indexterm-419"><primary>Walkers</primary><secondary>ttrace</secondary></indexterm><indexterm id="indexterm-420"><primary>Platform Debugging Support</primary><secondary>Walkers</secondary><tertiary>ttrace</tertiary></indexterm><listitem><para>Walk the list of trap trace record addresses in reverse chronological
order.  The trap trace facility is only available in DEBUG kernels.</para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="modules-19" arch="sparc"><title><gentext type="text">SPARC: </gentext>sun4u Platform Debugging Support (<literal>unix</literal>)</title><para>These dcmds and walkers are specific to the SPARC sun4u platform.</para><sect2 id="modules-20"><title>dcmds</title><variablelist><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::softint</command></term><listitem><para><indexterm id="indexterm-421"><primary>dcmds</primary><secondary><command>::softint</command></secondary></indexterm><indexterm id="indexterm-422"><primary>Platform Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::softint</command></tertiary></indexterm>Display
the soft interrupt vector structure at the specified address, or display all
the active soft interrupt vectors.  The pending count, PIL, argument, and
handler function for each structure is displayed.</para></listitem></varlistentry><varlistentry><term><command>::ttctl</command></term><indexterm id="indexterm-423"><primary>dcmds</primary><secondary><command>::ttctl</command></secondary></indexterm><indexterm id="indexterm-424"><primary>Platform Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::ttctl</command></tertiary></indexterm><listitem><para>Display trap trace control records.  The trap
trace facility is available only in DEBUG kernels.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>cpuid</replaceable> ] <command>::ttrace</command> [<option><gentext type="text">-</gentext>x</option>]</term><indexterm id="indexterm-425"><primary>dcmds</primary><secondary><command>::ttrace</command></secondary></indexterm><indexterm id="indexterm-426"><primary>Platform Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::ttrace</command></tertiary></indexterm><listitem><para>Display trap trace records in reverse chronological order.
 The trap trace facility is available only in DEBUG kernels.  If an explicit
dot value is specified, this is interpreted as a CPU ID number, and the output
is restricted to the buffer from that CPU.  If the <option><gentext type="text">-</gentext>x</option> option
is specified, the complete raw record is displayed.</para></listitem></varlistentry><varlistentry><term>[ <replaceable>address</replaceable> ] <command>::xc_mbox</command></term><indexterm id="indexterm-427"><primary>dcmds</primary><secondary><command>::xc_mbox</command></secondary></indexterm><indexterm id="indexterm-428"><primary>Platform Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::xc_mbox</command></tertiary></indexterm><listitem><para>Display the cross-call
mailbox at the specified address, or format  all the cross-call mailboxes
that have pending requests.</para></listitem></varlistentry><varlistentry><term><command>::xctrace</command></term><indexterm id="indexterm-429"><primary>dcmds</primary><secondary><command>::xctrace</command></secondary></indexterm><indexterm id="indexterm-430"><primary>Platform Debugging Support</primary><secondary>dcmds</secondary><tertiary><command>::xctrace</command></tertiary></indexterm><listitem><para>Format and display cross-call trace records in
reverse chronological order that are related to CPU cross-call activity. 
The cross-call trace facility is available only in DEBUG kernels.</para></listitem></varlistentry></variablelist></sect2><sect2 id="modules-21"><title>Walkers</title><variablelist><varlistentry><term>softint</term><indexterm id="indexterm-431"><primary>Walkers</primary><secondary>softint</secondary></indexterm><indexterm id="indexterm-432"><primary>Platform Debugging Support</primary><secondary>Walkers</secondary><tertiary>softint</tertiary></indexterm><listitem><para>Iterate over the soft interrupt vector table entries.</para></listitem></varlistentry><varlistentry><term>ttrace</term><indexterm id="indexterm-433"><primary>Walkers</primary><secondary>ttrace</secondary></indexterm><indexterm id="indexterm-434"><primary>Platform Debugging Support</primary><secondary>Walkers</secondary><tertiary>ttrace</tertiary></indexterm><listitem><para>Iterate over the trap trace record addresses in reverse chronological
order.  The trap trace facility is only available in DEBUG kernels.</para></listitem></varlistentry><varlistentry><term>xc_mbox</term><indexterm id="indexterm-435"><primary>Walkers</primary><secondary>xc_mbox</secondary></indexterm><indexterm id="indexterm-436"><primary>Platform Debugging Support</primary><secondary>Walkers</secondary><tertiary>xc_mbox</tertiary></indexterm><listitem><para>Iterate over the mailboxes used for CPU handshake and cross-call
(x-call) requests.</para></listitem></varlistentry></variablelist></sect2></sect1></chapter><chapter id="kmem-1"><gentext type="text">Chapter 8</gentext><gentext type="toc">8.&#160;&#160;Debugging With the Kernel Memory Allocator</gentext><title>Debugging With the Kernel Memory Allocator</title><highlights><para>The Solaris kernel memory (kmem) allocator provides a powerful
set of debugging features that can facilitate analysis of a kernel crash dump.
This chapter discusses these debugging features, and the MDB dcmds and walkers
designed specifically for the allocator. Bonwick (see <link linkend="preface-5">Related Books and Papers</link>)
provides an overview of the principles of the allocator itself. Refer to the
header file <literal>&lt;sys/kmem_impl.h&gt;</literal>
for the definitions of allocator data structures. The kmem debugging features
can be enabled on a production system to enhance problem analysis, or on development
systems to aid in debugging kernel software and device drivers. </para><note><gentext type="text">Note &#8211; </gentext><para>This guide reflects Solaris 9 implementation; this information
might not be relevant, correct, or applicable to past or future releases,
since it reflects the current kernel implementation. It does not define a
public interface of any kind. All of the information provided about the kernel
memory allocator is subject to change in future Solaris releases.</para></note></highlights><sect1 id="casestudy-13"><title>Getting Started: Creating a Sample Crash Dump</title><para>This section shows you how to obtain a sample crash dump, and how to
invoke MDB in order to examine it.</para><sect2 id="casestudy-15"><title>Setting <literal>kmem_flags</literal></title><para><indexterm id="indexterm-437"><primary><literal>kmem_flags</literal></primary></indexterm>The
kernel memory allocator contains many advanced debugging features, but these
are not enabled by default because they can cause performance degradation.
In order to follow the examples in this guide, you should turn on these features.
You should enable these features only on a test system, as they can cause
performance degradation or expose latent problems.</para><para>The allocator's debugging functionality is controlled by the <literal>kmem_flags</literal> tunable. To get started, make sure <literal>kmem_flags</literal> is set properly: </para><programlisting format="linespecific"># mdb -k
&gt; kmem_flags/X
kmem_flags:
kmem_flags:     f</programlisting><para>If kmem_flags is not set to '<literal>f</literal>', you should add the
line:</para><programlisting format="linespecific">set kmem_flags=0xf</programlisting><para>to <literal>/etc/system</literal> and reboot the system. When the system
reboots, confirm that <literal>kmem_flags</literal> is set to '<literal>f</literal>'. Remember to remove your <literal>/etc/system</literal> modifications
before returning this system to production use.</para></sect2><sect2 id="casestudy-16"><title>Forcing a Crash Dump</title><para>The next step is to make sure crash dumps are properly configured. First,
confirm that <command>dumpadm</command> is configured to save kernel crash
dumps and that <command>savecore</command> is enabled.  See <olink targetdocent="REFMAN1M" localinfo="DUMPADM-1M" type="v-only"><citerefentry><refentrytitle>dumpadm</refentrytitle><manvolnum><gentext type="text">(</gentext>1M<gentext type="text">)</gentext></manvolnum></citerefentry></olink> for more
information on crash dump parameters.<indexterm id="indexterm-438"><primary><command>dumpadm</command></primary></indexterm></para><programlisting format="linespecific"># dumpadm
		      Dump content: kernel pages
		       Dump device: /dev/dsk/c0t0d0s1 (swap)
		Savecore directory: /var/crash/testsystem
		  Savecore enabled: yes</programlisting><para>Next, reboot the system using the '<literal>-d</literal>' flag to <olink targetdocent="REFMAN1M" localinfo="REBOOT-1M" type="v-only"><citerefentry><refentrytitle>reboot</refentrytitle><manvolnum><gentext type="text">(</gentext>1M<gentext type="text">)</gentext></manvolnum></citerefentry></olink>,
which forces the kernel to panic and save a crash dump.<indexterm id="indexterm-439"><primary>reboot</primary></indexterm></para><programlisting format="linespecific"># reboot -d
Sep 28 17:51:18 testsystem reboot: rebooted by root

panic[cpu0]/thread=70aacde0: forced crash dump initiated at user request

401fbb10 genunix:uadmin+55c (1, 1, 0, 6d700000, 5, 0)
  %l0-7: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
         00000000
...</programlisting><para>When the system reboots, make sure the crash dump succeeded:</para><programlisting format="linespecific">$ cd /var/crash/testsystem
$ ls
bounds    unix.0    unix.1    vmcore.0  vmcore.1</programlisting><para>If the dump is missing from your dump directory, it could be that the
partition is out of space.  You can free up space and run <olink targetdocent="REFMAN1M" localinfo="SAVECORE-1M" type="v-only"><citerefentry><refentrytitle>savecore</refentrytitle><manvolnum><gentext type="text">(</gentext>1M<gentext type="text">)</gentext></manvolnum></citerefentry></olink> manually
as root to subsequently save the dump. If your dump directory contains multiple
crash dumps, the one you just created will be the <filename>unix.[n]</filename>
and <filename>vmcore.[n]</filename> pair with the most recent modification
time.<indexterm id="indexterm-440"><primary><command>savecore</command></primary></indexterm></para></sect2><sect2 id="casestudy-17"><title>Starting MDB</title><para>Now, run <command>mdb</command> on the crash dump you created, and check
its status:</para><programlisting format="linespecific">$ mdb unix.1 vmcore.1
Loading modules: [ unix krtld genunix ip nfs ipc ]
&gt; ::status
debugging crash dump vmcore.1 (32-bit) from testsystem
operating system: 5.9 Generic (sun4u)
panic message: forced crash dump initiated at user request</programlisting><para>In the examples presented in this guide, a crash dump from a 32-bit
kernel is used.  All of the techniques presented here are applicable to a
64-bit kernel, and care has been taken to distinguish pointers (sized differently
on 32- and 64-bit systems) from fixed-sized quantities, which are invariant
with respect to the kernel data model.</para><para>A Sun Ultra-1 workstation was used to generate the example presented.
Your results can vary depending on the architecture and model of system you
use.</para></sect2></sect1><sect1 id="casestudy-18"><title>Allocator Basics</title><para>The kernel memory allocator's job is to parcel out regions of virtual
memory to other kernel subsystems (these are commonly called <emphasis>clients</emphasis>). This section explains the basics of the allocator's operation
and introduces some terms used later in this guide.</para><sect2 id="casestudy-19"><title>Buffer States</title><para>The functional domain of the kernel memory allocator is the set of <emphasis>buffers</emphasis> of virtual memory that make up the kernel heap.  These
buffers are grouped together into sets of uniform size and purpose, known
as <emphasis>caches</emphasis>.  Each cache contains a set of buffers.  Some
of these buffers are currently <emphasis>free</emphasis>, which means that
they have not yet been allocated to any client of the allocator.  The remaining
buffers are <emphasis>allocated</emphasis>, which means that a pointer to
that buffer has been provided to a client of the allocator.  If no client
of the allocator holds a pointer to an allocated buffer, this buffer is said
to be <emphasis>leaked</emphasis>, because it cannot be freed.  Leaked buffers
indicate incorrect code that is wasting kernel resources. </para></sect2><sect2 id="casestudy-20"><title>Transactions</title><para>A kmem <emphasis>transaction</emphasis> is a transition on a buffer
between the allocated and free states.  The allocator can verify that the
state of a buffer is valid as part of each transaction. Additionally, the
allocator has facilities for logging transactions for post-mortem examination.</para></sect2><sect2 id="casestudy-21"><title>Sleeping and Non-Sleeping Allocations</title><para>Unlike the Standard C Library's <olink targetdocent="REFMAN3A" localinfo="MALLOC-3C" type="v-only"><citerefentry><refentrytitle>malloc</refentrytitle><manvolnum><gentext type="text">(</gentext>3C<gentext type="text">)</gentext></manvolnum></citerefentry></olink> function, the kernel memory allocator
can block (or <emphasis>sleep</emphasis>), waiting until enough virtual memory
is available to satisfy the client's request.  This is controlled by the 'flag'
parameter to <olink targetdocent="REFMAN9F" localinfo="KMEM-ALLOC-9F" type="v-only"><citerefentry><refentrytitle>kmem_alloc</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.
 A call to <olink targetdocent="REFMAN9F" localinfo="KMEM-ALLOC-9F" type="v-only"><citerefentry><refentrytitle>kmem_alloc</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>
which has the <literal>KM_SLEEP</literal> flag set can never fail; it will
block forever waiting for resources to become available.<indexterm id="indexterm-441"><primary><command>kmem_alloc</command></primary></indexterm></para></sect2><sect2 id="casestudy-22"><title>Kernel Memory Caches</title><para>The kernel memory allocator divides the memory it manages into a set
of <emphasis>caches</emphasis>.  All allocations are supplied from these caches,
which are represented by the <structname>kmem_cache_t</structname> data structure.
 Each cache has a fixed <emphasis>buffer size</emphasis>, which represents
the maximum allocation size satisfied by that cache.  Each cache has a string
name indicating the type of data it manages.<indexterm id="indexterm-442"><primary><structname>kmem_cache_t</structname></primary></indexterm></para><para>Some kernel memory caches are special purpose and are initialized to
allocate only a particular kind of data structure.  An example of this is
the “thread_cache,” which allocates only structures of type <type>kthread_t</type>.  Memory from these caches is allocated to clients by the <function>kmem_cache_alloc<gentext type="text">()</gentext></function> function and freed by the <function>kmem_cache_free<gentext type="text">()</gentext></function> function.<indexterm id="indexterm-443"><primary><function>kmem_cache_alloc<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-444"><primary><function>kmem_cache_free<gentext type="text">()</gentext></function></primary></indexterm></para><note><gentext type="text">Note &#8211; </gentext><para><function>kmem_cache_alloc<gentext type="text">()</gentext></function> and <function>kmem_cache_free<gentext type="text">()</gentext></function> are not public DDI interfaces. Do NOT write code that relies on
them, because they are subject to change or removal in future releases of
Solaris.</para></note><para>Caches whose name begins with “<literal>kmem_alloc_</literal>”
implement the kernel's general memory allocation scheme.  These caches provide
memory to clients of <olink targetdocent="REFMAN9F" localinfo="KMEM-ALLOC-9F" type="v-only"><citerefentry><refentrytitle>kmem_alloc</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink> and <olink targetdocent="REFMAN9F" localinfo="KMEM-ZALLOC-9F" type="v-only"><citerefentry><refentrytitle>kmem_zalloc</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.  Each of these caches satisfies requests
whose size is between the buffer size of that cache and the buffer size of
the next smallest cache.  For example, the kernel has <literal>kmem_alloc_8</literal> and <literal>kmem_alloc_16</literal> caches.  In this case, the <literal>kmem_alloc_16</literal> cache handles all client requests for 9-16 bytes of
memory.  Remember that the size of each buffer in the <literal>kmem_alloc_16</literal> cache is 16 bytes, regardless of the size of the client request.
 In a 14 byte request, two bytes of the resulting buffer are unused, since
the request is satisfied from the <literal>kmem_alloc_16</literal> cache.<indexterm id="indexterm-445"><primary><function>kmem_zalloc<gentext type="text">()</gentext></function></primary></indexterm></para><para>The last set of caches are those used internally by the kernel memory
allocator for its own bookkeeping.  These include those caches whose names
start with “<literal>kmem_magazine_</literal>” or “<literal>kmem_va_</literal>”, the <literal>kmem_slab_cache</literal>, the <literal>kmem_bufctl_cache</literal> and others.</para></sect2></sect1><sect1 id="casestudy-27"><title>Kernel Memory Caches</title><para>This section explains how to find and examine kernel memory caches.
 You can learn about the various kmem caches on the system by issuing the <command>::kmastat</command> command.<indexterm id="indexterm-446"><primary>dcmds</primary><secondary><command>::kmastat</command></secondary></indexterm></para><programlisting format="linespecific">&gt; ::kmastat
cache                        buf    buf    buf    memory     alloc alloc
name                        size in use  total    in use   succeed  fail
------------------------- ------ ------ ------ --------- --------- -----
kmem_magazine_1                8     24   1020      8192        24     0
kmem_magazine_3               16    141    510      8192       141     0
kmem_magazine_7               32     96    255      8192        96     0
...
kmem_alloc_8                   8   3614   3751     90112   9834113     0
kmem_alloc_16                 16   2781   3072     98304   8278603     0
kmem_alloc_24                 24    517    612     24576    680537     0
kmem_alloc_32                 32    398    510     24576    903214     0
kmem_alloc_40                 40    482    584     32768    672089     0
...
thread_cache                 368    107    126     49152    669881     0
lwp_cache                    576    107    117     73728       182     0
turnstile_cache               36    149    292     16384    670506     0
cred_cache                    96      6     73      8192   2677787     0
...</programlisting><para>If you run <command>::kmastat</command> you get a feel for what a “normal”
system looks like.  This will help you to spot excessively large caches on
systems that are leaking memory.  The results of <command>::kmastat</command>
will vary depending on the system you are running on, how many processes are
running, and so forth.</para><para>Another way to list the various kmem caches is with the <command>::kmem_cache</command> command:<indexterm id="indexterm-447"><primary>dcmds</primary><secondary><command>::kmem_cache</command></secondary></indexterm></para><programlisting format="linespecific">&gt; ::kmem_cache
ADDR     NAME                      FLAG  CFLAG  BUFSIZE  BUFTOTL
70036028 kmem_magazine_1           0020 0e0000        8     1020
700362a8 kmem_magazine_3           0020 0e0000       16      510
70036528 kmem_magazine_7           0020 0e0000       32      255
...
70039428 kmem_alloc_8              020f 000000        8     3751
700396a8 kmem_alloc_16             020f 000000       16     3072
70039928 kmem_alloc_24             020f 000000       24      612
70039ba8 kmem_alloc_32             020f 000000       32      510
7003a028 kmem_alloc_40             020f 000000       40      584
...</programlisting><para>This command is useful because it maps cache names to addresses, and
provides the debugging flags for each cache in the FLAG column.  It is important
to understand that the allocator's selection of debugging features is derived
on a per-cache basis from this set of flags.  These are set in conjunction
with the global <literal>kmem_flags</literal> variable at cache creation time.
 Setting <literal>kmem_flags</literal> while the system is running has no
effect on the debugging behavior, except for subsequently created caches (which
is rare after boot-up).</para><para>Next, walk the list of kmem caches directly using MDB's <literal>kmem_cache</literal> walker:<indexterm id="indexterm-448"><primary>Walkers</primary><secondary>kmem_cache</secondary></indexterm></para><programlisting format="linespecific">&gt; ::walk kmem_cache
70036028
700362a8
70036528
700367a8
...</programlisting><para>This produces a list of pointers that correspond to each kmem cache
in the kernel.  To find out about a specific cache, apply the <literal>kmem_cache</literal> macro:<indexterm id="indexterm-449"><primary>Macros</primary><secondary>kmem_cache</secondary></indexterm> </para><programlisting format="linespecific">&gt; 0x70039928$&lt;kmem_cache
0x70039928:     lock
0x70039928:     owner/waiters
                0
0x70039930:     flags           freelist        offset
                20f             707c86a0        24
0x7003993c:     global_alloc    global_free     alloc_fail
                523             0               0
0x70039948:     hash_shift      hash_mask       hash_table
                5               1ff             70444858
0x70039954:     nullslab
0x70039954:     cache           base            next
                70039928        0               702d5de0
0x70039960:     prev            head            tail
                707c86a0        0               0
0x7003996c:     refcnt          chunks
                -1              0
0x70039974:     constructor     destructor      reclaim
                0               0               0
0x70039980:     private         arena           cflags
                0               104444f8        0
0x70039994:     bufsize         align           chunksize
                24              8               40
0x700399a0:     slabsize        color           maxcolor
                8192            24              32
0x700399ac:     slab_create     slab_destroy    buftotal
                3               0               612
0x700399b8:     bufmax          rescale         lookup_depth
                612             1               0
0x700399c4:     kstat           next            prev
                702c8608        70039ba8        700396a8
0x700399d0:     name    kmem_alloc_24
0x700399f0:     bufctl_cache    magazine_cache  magazine_size
                70037ba8        700367a8        15
...</programlisting><para>Important fields for debugging include 'bufsize', 'flags' and 'name'.
The name of the <literal>kmem_cache</literal> (in this case “<literal>kmem_alloc_24</literal>”) indicates its purpose in the system.  Bufsize
indicates the size of each buffer in this cache; in this case, the cache is
used for allocations of size 24 and smaller.  'flags' indicates what debugging
features are turned on for this cache.  You can find the debugging flags listed
in <literal>&lt;sys/kmem_impl.h&gt;</literal>.  In this case 'flags' is <literal>0x20f</literal>, which is <literal>KMF_AUDIT | KMF_DEADBEEF | KMF_REDZONE
| KMF_CONTENTS | KMF_HASH</literal>.  This document explains each of the debugging
features in subsequent sections.</para><para>When you are interested in looking at buffers in a particular cache,
you can walk the allocated and freed buffers in that cache directly: <indexterm id="indexterm-450"><primary>Walkers</primary><secondary>kmem</secondary></indexterm><indexterm id="indexterm-451"><primary>Walkers</primary><secondary>freemem</secondary></indexterm></para><programlisting format="linespecific">&gt; 0x70039928::walk kmem
704ba010
702ba008
704ba038
702ba030
...

&gt; 0x70039928::walk freemem
70a9ae50
70a9ae28
704bb730
704bb2f8
...</programlisting><para>MDB provides a shortcut to supplying the cache address to the kmem walker:
a specific walker is provided for each kmem cache, and its name is the same
as the name of the cache.  For example:</para><programlisting format="linespecific">&gt; ::walk kmem_alloc_24
704ba010
702ba008
704ba038
702ba030
...

&gt; ::walk thread_cache
70b38080
70aac060
705c4020
70aac1e0
...</programlisting><para>Now you know how to iterate over the kernel memory allocator's internal
data structures and examine the most important members of the <structname>kmem_cache</structname> data structure.</para></sect1><sect1 id="casestudy-26"><title>Detecting Memory Corruption</title><para><indexterm id="indexterm-452"><primary>Memory Corruption</primary></indexterm>One of the
primary debugging facilities of the allocator is that it includes algorithms
to recognize data corruption quickly. When corruption is detected, the allocator
immediately panics the system.  </para><para>This section describes how the allocator recognizes data corruption;
you must understand this to be able to debug these problems. Memory abuse
typically falls into one of the following categories: </para><itemizedlist><listitem><para>Writing past the end of a buffer</para></listitem><listitem><para>Accessing uninitialized data</para></listitem><listitem><para>Continuing to use a freed buffer</para></listitem><listitem><para>Corrupting kernel memory</para></listitem></itemizedlist><para>Keep these problems in mind as you read the next three sections.  They
will help you to understand the allocator's design, and enable you to diagnose
problems more efficiently.</para><sect2 id="casestudy-25"><title>Freed Buffer Checking: <literal>0xdeadbeef</literal></title><para><indexterm id="indexterm-453"><primary><literal>0xdeadbeef</literal></primary></indexterm>When
the <literal>KMF_DEADBEEF (0x2)</literal> bit is set in the flags field of
a <literal>kmem_cache</literal>, the allocator tries to make memory corruption
easy to detect by writing a special pattern into all freed buffers.  This
pattern is <literal>0xdeadbeef</literal>.  Since a typical region of memory
contains both allocated and freed memory, sections of each kind of block will
be interspersed; here is an example from the “<filename>kmem_alloc_24</filename>” cache:</para><programlisting format="linespecific">0x70a9add8:     deadbeef        deadbeef
0x70a9ade0:     deadbeef        deadbeef
0x70a9ade8:     deadbeef        deadbeef
0x70a9adf0:     feedface        feedface
0x70a9adf8:     70ae3260        8440c68e
0x70a9ae00:     5               4ef83
0x70a9ae08:     0               0
0x70a9ae10:     1               bbddcafe
0x70a9ae18:     feedface        139d
0x70a9ae20:     70ae3200        d1befaed
0x70a9ae28:     deadbeef        deadbeef
0x70a9ae30:     deadbeef        deadbeef
0x70a9ae38:     deadbeef        deadbeef
0x70a9ae40:     feedface        feedface
0x70a9ae48:     70ae31a0        8440c54e</programlisting><para>The buffer beginning at <literal>0x70a9add8</literal> is filled with
the <literal>0xdeadbeef</literal> pattern, which is an immediate indication
that the buffer is currently free.  At <literal>0x70a9ae28</literal> another
free buffer begins; at <literal>0x70a9ae00</literal> an allocated buffer is
located between them.</para><note><gentext type="text">Note &#8211; </gentext><para>You might have observed that there are some holes on this picture,
 and that 3 24–byte regions should occupy only 72 bytes of memory, instead
of the 120 bytes shown here.  This discrepancy is explained in the next section <link linkend="casestudy-28">Redzone: <literal>0xfeedface</literal></link>.</para></note></sect2><sect2 id="casestudy-28"><title>Redzone: <literal>0xfeedface</literal></title><para><indexterm id="indexterm-454"><primary>Redzone</primary></indexterm><indexterm id="indexterm-455"><primary><literal>0xfeedface</literal></primary></indexterm>The pattern <literal>0xfeedface</literal> appears frequently in the buffer above.  This pattern is known
as the “redzone” indicator.  It enables the allocator (and a programmer
debugging a problem) to determine if the boundaries of a buffer have been
violated by “buggy” code.  Following the redzone is some additional
information.  The contents of that data depends upon other factors (see <link linkend="casestudy-31">Memory Allocation Logging</link>).  The redzone and its suffix are collectively called
the <emphasis>buftag</emphasis> region.<indexterm id="indexterm-456"><primary>buftag</primary></indexterm>  <link linkend="casestudy-fig-39">Figure 8–1</link> summarizes this information.</para><figure id="casestudy-fig-39"><gentext type="text">Figure 8&#8211;1 </gentext><title>The Redzone</title><graphic entityref="redzone.fig1" width="496" depth="68"><![CDATA[The redzone lies between user data and the debugging data. The redzone is 64 bits long.]]></graphic></figure><para>The buftag is appended to each buffer in a cache when any of the <literal>KMF_AUDIT</literal>, <literal>KMF_DEADBEEF</literal>, or <literal>KMF_REDZONE</literal> flags are set in that buffer's cache.  The contents of the buftag
depend on whether <literal>KMF_AUDIT</literal> is set.</para><para>Decomposing the memory region presented above into distinct buffers
is now simple:</para><programlisting format="linespecific">0x70a9add8:     deadbeef        deadbeef  \
0x70a9ade0:     deadbeef        deadbeef   +- User Data (free)
0x70a9ade8:     deadbeef        deadbeef  /
0x70a9adf0:     feedface        feedface  -- REDZONE
0x70a9adf8:     70ae3260        8440c68e  -- Debugging Data

0x70a9ae00:     5               4ef83     \
0x70a9ae08:     0               0          +- User Data (allocated)
0x70a9ae10:     1               bbddcafe  /
0x70a9ae18:     feedface        139d    -- REDZONE
0x70a9ae20:     70ae3200        d1befaed  -- Debugging Data

0x70a9ae28:     deadbeef        deadbeef  \
0x70a9ae30:     deadbeef        deadbeef   +- User Data (free)
0x70a9ae38:     deadbeef        deadbeef  /
0x70a9ae40:     feedface        feedface  -- REDZONE
0x70a9ae48:     70ae31a0        8440c54e  -- Debugging Data</programlisting><para>In the free buffers at <literal>0x70a9add8</literal> and <literal>0x70a9ae28</literal>, the redzone is filled with <literal>0xfeedfacefeedface</literal>.
 This a convenient way of determining that a buffer is free.</para><para>In the allocated buffer beginning at <literal>0x70a9ae00</literal>,
the situation is different. Recall from <link linkend="casestudy-18">Allocator Basics</link> that
there are two allocation types: </para><para>1) The client requested memory using <function>kmem_cache_alloc<gentext type="text">()</gentext></function>,
in which case the size of the requested buffer is equal to the bufsize of
the cache.<indexterm id="indexterm-457"><primary><function>kmem_cache_alloc<gentext type="text">()</gentext></function></primary></indexterm></para><para>2) The client requested memory using <olink targetdocent="REFMAN9F" localinfo="KMEM-ALLOC-9F" type="v-only"><citerefentry><refentrytitle>kmem_alloc</refentrytitle><manvolnum><gentext type="text">(</gentext>9F<gentext type="text">)</gentext></manvolnum></citerefentry></olink>, in which
case the size of the requested buffer is less than or equal to the bufsize
of the cache.  For example, a request for 20 bytes will be fulfilled from
the <filename>kmem_alloc_24</filename> cache.  The allocator enforces the
buffer boundary by placing a marker, the <emphasis>redzone byte</emphasis>,
immediately following the client data:<indexterm id="indexterm-458"><primary><function>kmem_alloc<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-459"><primary>redzone byte</primary></indexterm> </para><programlisting format="linespecific">0x70a9ae00:     5               4ef83     \
0x70a9ae08:     0               0          +- User Data (allocated)
0x70a9ae10:     1               bbddcafe  /
0x70a9ae18:     feedface        139d    -- REDZONE
0x70a9ae20:     70ae3200        d1befaed  -- Debugging Data</programlisting><para><literal>0xfeedface</literal> at <literal>0x70a9ae18</literal> is followed
by a 32-bit word containing what seems to be a random value.  This number
is actually an encoded representation of the size of the buffer.  To decode
this number and find the size of the allocated buffer, use the formula:</para><programlisting format="linespecific">size = redzone_value / 251</programlisting><para>So, in this example, </para><programlisting format="linespecific">size = 0x139d / 251 = 20 bytes.</programlisting><para>This indicates that the buffer requested was of size 20 bytes.  The
allocator performs this decoding operation and finds that the redzone byte
should be at offset 20.  The redzone byte is the hex pattern <literal>0xbb</literal>, which is present at <literal>0x729084e4 (0x729084d0 + 0t20)</literal>
as expected.</para><figure id="casestudy-fig-41"><gentext type="text">Figure 8&#8211;2 </gentext><title>Sample <literal>kmem_alloc(9F)</literal> Buffer</title><graphic entityref="redzone.fig2" width="444" depth="147"><![CDATA[A sample buffer containing valid user data through 0x729084e0, a REDZONE marker at 0x729084e8, and debugging data at 0x729084f0.]]></graphic></figure><para><link linkend="casestudy-fig-43">Figure 8–3</link> shows the general form of this memory
layout.</para><figure id="casestudy-fig-43"><gentext type="text">Figure 8&#8211;3 </gentext><title>Redzone Byte</title><graphic entityref="redzone.fig3" width="484" depth="68"><![CDATA[Context describes graphic.]]></graphic></figure><para>If the allocation size is the same as the bufsize of the cache, the
redzone byte overwrites the first byte of the redzone itself, as shown in <link linkend="casestudy-fig-45">Figure 8–4</link>. </para><figure id="casestudy-fig-45"><gentext type="text">Figure 8&#8211;4 </gentext><title>Redzone Byte at the Beginning of the Redzone</title><graphic entityref="redzone.fig4" width="488" depth="69"><![CDATA[Context describes graphic.]]></graphic></figure><para>This overwriting results in the first 32-bit word of the redzone being <literal>0xbbedface</literal>, or <literal>0xfeedfabb</literal> depending on the endianness
of the hardware on which the system is running.</para><note><gentext type="text">Note &#8211; </gentext><para>Why is the allocation size encoded this way?  To encode the size,
the allocator uses the formula (251 * size + 1). When the size decode occurs,
the integer division discards the  remainder of '+1'.  However, the addition
of 1 is valuable because the allocator can check whether the size is valid
by testing whether (size % 251 == 1).  In this way, the allocator defends
against corruption of the redzone byte index. </para></note></sect2><sect2 id="casestudy-29"><title>Uninitialized Data: <literal>0xbaddcafe</literal></title><para><indexterm id="indexterm-460"><primary>Uninitialized Data</primary></indexterm><indexterm id="indexterm-461"><primary><literal>0xbaddcafe</literal></primary></indexterm>You might be wondering
what the suspicious <literal>0xbbddcafe</literal> at address <literal>0x729084d4</literal> was <emphasis>before</emphasis> the redzone byte got placed over
the first byte in the word.  It was <literal>0xbaddcaf</literal>e.  When the <literal>KMF_DEADBEEF</literal> flag is set in the cache, allocated but <emphasis>uninitialized</emphasis> memory is filled with the <literal>0xbaddcafe</literal>
pattern.  When the allocator performs an allocation, it loops across the words
of the buffer and verifies that each word contains <literal>0xdeadbeef</literal>,
then fills that word with <literal>0xbaddcafe</literal>.</para><para>A system can panic with a message such as: </para><programlisting format="linespecific">panic[cpu1]/thread=e1979420: BAD TRAP: type=e (Page Fault)
rp=ef641e88 addr=baddcafe occurred in module "unix" due to an
illegal access to a user address</programlisting><para>In this case, the address that caused the fault was <literal>0xbaddcafe</literal>:  the panicking thread has accessed some data that was never initialized. </para></sect2><sect2 id="casestudy-30"><title>Associating Panic Messages With Failures</title><para>The kernel memory allocator emits panic messages corresponding to the
failure modes described earlier.  For example, a system can panic with a message
such as:</para><programlisting format="linespecific">kernel memory allocator: buffer modified after being freed
modification occurred at offset 0x30</programlisting><para>The allocator was able to detect this case because it tried to validate
that the buffer in question was filled with <literal>0xdeadbeef</literal>.
 At offset <literal>0x30,</literal> this condition was not met.  Since this
condition indicates memory corruption, the allocator panicked the system.</para><para>Another example failure message is:</para><programlisting format="linespecific">kernel memory allocator: redzone violation: write past end of buffer</programlisting><para>The allocator was able to detect this case because it tried to validate
that the redzone byte (<literal>0xbb</literal>) was in the location it determined
from the redzone size encoding.  It failed to find the signature byte in the
correct location.  Since this indicates memory corruption, the allocator panicked
the system.  Other allocator panic messages are discussed later. </para></sect2></sect1><sect1 id="casestudy-31"><title>Memory Allocation Logging</title><para>This section explains the logging features of the kernel memory allocator
and how you can employ them to debug system crashes.</para><sect2 id="casestudy-32"><title>Buftag Data Integrity</title><para>As explained earlier, the second half of each buftag contains extra
information about the corresponding buffer.  Some of this data is debugging
information, and some is data private to the allocator.  While this auxiliary
data can take several different forms, it is collectively known as “Buffer
Control” or <emphasis>bufctl</emphasis> data.<indexterm id="indexterm-462"><primary>bufctl</primary></indexterm></para><para>However, the allocator needs to know whether a buffer's bufctl pointer
is valid, since this pointer might also have been corrupted by malfunctioning
code.  The allocator confirms the integrity of its auxiliary pointer by storing
the pointer <emphasis>and</emphasis> an encoded version of that pointer, and
then cross-checking the two versions.  </para><para>As shown in <link linkend="casestudy-fig-47">Figure 8–5</link>, these pointers are the <emphasis>bcp</emphasis> (buffer control pointer) and <emphasis>bxstat</emphasis> (buffer
control XOR status).  The allocator arranges bcp and bxstat so that the expression <literal>bcp XOR bxstat</literal> equals a well-known value.<indexterm id="indexterm-463"><primary><literal>bcp</literal></primary></indexterm><indexterm id="indexterm-464"><primary><literal>bxstat</literal></primary></indexterm></para><figure id="casestudy-fig-47"><gentext type="text">Figure 8&#8211;5 </gentext><title>Extra Debugging Data in the Buftag</title><graphic entityref="redzone.fig5" width="496" depth="49"><![CDATA[Debugging data contains a bcp pointer and a bxstat pointer.]]></graphic></figure><para>In the event that one or both of these pointers becomes corrupted, the
allocator can easily detect such corruption and panic the system. When a buffer
is <emphasis>allocated</emphasis>, <literal>bcp XOR bxstat = 0xa110c8ed</literal>
(“allocated”). When a buffer is free, <literal>bcp XOR bxstat
= 0xf4eef4ee</literal> (“freefree”). </para><note><gentext type="text">Note &#8211; </gentext><para>You might find it helpful to re-examine the example provided in <link linkend="casestudy-25">Freed Buffer Checking: <literal>0xdeadbeef</literal></link>, in order to confirm that the buftag pointers shown
there are consistent.</para></note><para>In the event that the allocator finds a corrupt buftag, it panics the
system and produces a message similar to the following: </para><programlisting format="linespecific">kernel memory allocator: boundary tag corrupted
    bcp ^ bxstat = 0xffeef4ee, should be f4eef4ee</programlisting><para>Remember, if bcp is corrupt, it is still possible to retrieve its value
by taking the value of <literal>bxstat XOR 0xf4eef4ee</literal> or <literal>bxstat XOR 0xa110c8ed</literal>, depending on whether the buffer is allocated
or free.</para></sect2><sect2 id="casestudy-33"><title>The <type>bufctl</type> Pointer</title><para><indexterm id="indexterm-465"><primary>bufctl</primary></indexterm><indexterm id="indexterm-466"><primary><structname>kmem_bufctl_t</structname></primary></indexterm><indexterm id="indexterm-467"><primary><literal>kmem_bufctl_audit_t</literal></primary></indexterm>The buffer control (bufctl)
pointer contained in the buftag region can have different meanings, depending
on the cache's <literal>kmem_flags</literal>.  The behavior toggled by the <literal>KMF_AUDIT</literal> flag is of particular interest: when the KMF_AUDIT flag
is <emphasis>not</emphasis> set, the kernel memory allocator allocates a <structname>kmem_bufctl_t</structname> structure for each buffer.  This structure contains
some minimal accounting information about each buffer.  When the <literal>KMF_AUDIT</literal> flag <emphasis>is</emphasis> set, the allocator instead
allocates a <literal>kmem_bufctl_audit_t</literal>, an extended version of
the <literal>kmem_bufctl_t</literal>.  </para><para>This section presumes the <literal>KMF_AUDIT</literal> flag is set.
For caches that do not have this bit set, the amount of available debugging
information is reduced.</para><para>The <literal>kmem_bufctl_audit_t</literal> (<literal>bufctl_audit</literal>
for short) contains additional information about the last transaction that
occurred on this buffer. The following example shows how to apply the <literal>bufctl_audit</literal> macro to examine an audit record.  The buffer shown
is the example buffer used in <link linkend="casestudy-26">Detecting Memory Corruption</link>:</para><programlisting format="linespecific">&gt; 0x70a9ae00,5/KKn
0x70a9ae00:     5               4ef83
                0               0
                1               bbddcafe
                feedface        139d
                70ae3200        d1befaed</programlisting><para>Using the techniques presented above, it is easy to see that <literal>0x70ae3200</literal> points to the <literal>bufctl_audit</literal> record:
it is the first pointer following the redzone.  To examine the <literal>bufctl_audit</literal> record it points to, apply the <literal>bufctl_audit</literal>
macro:<indexterm id="indexterm-468"><primary>Macros</primary><secondary><literal>bufctl_audit</literal></secondary></indexterm></para><programlisting format="linespecific">&gt; 0x70ae3200$&lt;bufctl_audit
0x70ae3200:     next            addr            slab
                70378000        70a9ae00        707c86a0
0x70ae320c:     cache           timestamp       thread
                70039928        e1bd0e26afe     70aac4e0
0x70ae321c:     lastlog         contents        stackdepth
                7011c7c0        7018a0b0        4
0x70ae3228:
                kmem_zalloc+0x30
                pid_assign+8
                getproc+0x68
                cfork+0x60</programlisting><para>The 'addr' field is the address of the buffer corresponding to this
bufctl_audit record.  This is the original address: <literal>0x70a9ae00</literal>.
The 'cache' field points at the kmem_cache that allocated this buffer. You
can use the <command>::kmem_cache</command> dcmd to examine it as follows: </para><programlisting format="linespecific">&gt; 0x70039928::kmem_cache
ADDR     NAME                      FLAG  CFLAG  BUFSIZE  BUFTOTL
70039928 kmem_alloc_24             020f 000000       24      612</programlisting><para>The 'timestamp' field represents the time this transaction occurred.
This time is expressed in the same manner as <olink targetdocent="REFMAN3A" localinfo="GETHRTIME-3C" type="v-only"><citerefentry><refentrytitle>gethrtime</refentrytitle><manvolnum><gentext type="text">(</gentext>3C<gentext type="text">)</gentext></manvolnum></citerefentry></olink>. </para><para>'thread' is a pointer to the thread that performed the last transaction
on this buffer.  The 'lastlog' and 'contents' pointers point to locations
in the allocator's <emphasis>transaction logs</emphasis>.  These logs are
discussed in detail in <link linkend="casestudy-38">Allocator Logging Facility</link>. </para><para>Typically, the most useful piece of information provided by <literal>bufctl_audit</literal> is the stack trace recorded at the point at which the
transaction took place.  In this case, the transaction was an allocation called
as part of executing <olink targetdocent="REFMAN2" localinfo="FORK-2" type="v-only"><citerefentry><refentrytitle>fork</refentrytitle><manvolnum><gentext type="text">(</gentext>2<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.</para></sect2></sect1><sect1 id="casestudy-34"><title>Advanced Memory Analysis</title><para>This section describes facilities for performing advanced memory analysis,
including locating memory leaks and sources of data corruption.</para><sect2 id="casestudy-35"><title>Finding Memory Leaks</title><para><indexterm id="indexterm-469"><primary>dcmds</primary><secondary><command>::findleaks</command></secondary></indexterm>The <command>::findleaks</command>
dcmd provides powerful and efficient detection of memory leaks in kernel crash
dumps where the full set of kmem debug features has been enabled.  The first
execution of <command>::findleaks</command> processes the dump for memory
leaks (this can take a few minutes), and then coalesces the leaks by the allocation
stack trace.  The findleaks report shows a bufctl address and the topmost
stack frame for each memory leak that was identified:</para><programlisting format="linespecific">&gt; ::findleaks
CACHE     LEAKED   BUFCTL CALLER
70039ba8       1 703746c0 pm_autoconfig+0x708
70039ba8       1 703748a0 pm_autoconfig+0x708
7003a028       1 70d3b1a0 sigaddq+0x108
7003c7a8       1 70515200 pm_ioctl+0x187c
------------------------------------------------------
   Total       4 buffers, 376 bytes</programlisting><para>Using the bufctl pointers, you can obtain the complete stack backtrace
of the allocation by applying the <literal>bufctl_audit</literal> macro:<indexterm id="indexterm-470"><primary>Macros</primary><secondary><literal>bufctl_audit</literal></secondary></indexterm> </para><programlisting format="linespecific">&gt; 70d3b1a0$&lt;bufctl_audit
0x70d3b1a0:     next            addr            slab
                70a049c0        70d03b28        70bb7480
0x70d3b1ac:     cache           timestamp       thread
                7003a028        13f7cf63b3      70b38380
0x70d3b1bc:     lastlog         contents        stackdepth
                700d6e60        0               5
0x70d3b1c8:
                kmem_alloc+0x30
                sigaddq+0x108
                sigsendproc+0x210
                sigqkill+0x90
                kill+0x28</programlisting><para>The programmer can usually use the <literal>bufctl_audit</literal> information
and the allocation stack trace to quickly track down the code path that leaks
the given buffer.</para></sect2><sect2 id="casestudy-36"><title>Finding References to Data</title><para>When trying to diagnose a memory corruption problem, you should know
what other kernel entities hold a copy of a particular pointer. This is important
because it can reveal which thread accessed a data structure after it was
freed.  It can also make it easier to understand what kernel entities are
sharing knowledge of a particular (valid) data item.  The <command>::whatis</command> and <command>::kgrep</command> dcmds can be used to answer these
questions.  You can apply <command>::whatis</command> to a value of interest: <indexterm id="indexterm-471"><primary>dcmds</primary><secondary><command>::whatis</command></secondary></indexterm><indexterm id="indexterm-472"><primary>dcmds</primary><secondary><command>::kgrep</command></secondary></indexterm></para><programlisting format="linespecific">&gt; 0x705d8640::whatis
705d8640 is 705d8640+0, allocated from streams_mblk</programlisting><para>In this case, <literal>0x705d8640</literal> is revealed to be a pointer
to a STREAMS <structname>mblk</structname> structure.  To see the entire allocation
tree, use <command>::whatis</command> <option><gentext type="text">-</gentext>a</option> instead:</para><programlisting format="linespecific">&gt; 0x705d8640::whatis -a
705d8640 is 705d8640+0, allocated from streams_mblk
705d8640 is 705d8000+640, allocated from kmem_va_8192
705d8640 is 705d8000+640 from kmem_default vmem arena
705d8640 is 705d2000+2640 from kmem_va vmem arena
705d8640 is 705d2000+2640 from heap vmem arena</programlisting><para>This reveals that the allocation also appears in the <literal>kmem_va_8192</literal> cache--a kmem cache that is fronting the <literal>kmem_va</literal>
vmem arena.  It also shows the full stack of vmem allocations.</para><para>The complete list of kmem caches and vmem arenas is displayed by the <command>::kmastat</command> dcmd.  You can use <command>::kgrep</command> to locate
other kernel addresses that contain a pointer to this <structname>mblk</structname>.
This illustrates the hierarchical nature of memory allocations in the system;
in general, you can determine the type of object referred to by the given
address from the name of the most specific kmem cache. </para><programlisting format="linespecific">&gt; 0x705d8640::kgrep
400a3720
70580d24
7069d7f0
706a37ec
706add34</programlisting><para>and investigate them by applying <command>::whatis</command> again:</para><programlisting format="linespecific">&gt; 400a3720::whatis
400a3720 is in thread 7095b240's stack

&gt; 706add34::whatis
706add34 is 706add20+14, allocated from streams_dblk_120</programlisting><para>Here one pointer is located on the stack of a known kernel thread, and
another is the <literal>mblk</literal> pointer inside of the corresponding
STREAMS <structname>dblk</structname> structure.</para></sect2><sect2 id="casestudy-37"><title>Finding Corrupt Buffers With <command>::kmem_verify</command></title><para>MDB's <command>::kmem_verify</command> dcmd implements most of the same
checks that the kmem allocator does at runtime.  <command>::kmem_verify</command>
can be invoked in order to scan every kmem cache with appropriate <literal>kmem_flags</literal>, or to examine a particular cache. <indexterm id="indexterm-473"><primary>dcmds</primary><secondary><command>::kmem_verify</command></secondary></indexterm></para><para>Here is an example of using <command>::kmem_verify</command> to isolate
a problem: </para><programlisting format="linespecific">&gt; ::kmem_verify
Cache Name                      Addr     Cache Integrity
kmem_alloc_8                    70039428 clean
kmem_alloc_16                   700396a8 clean
kmem_alloc_24                   70039928 1 corrupt buffer
kmem_alloc_32                   70039ba8 clean
kmem_alloc_40                   7003a028 clean
kmem_alloc_48                   7003a2a8 clean
...</programlisting><para>It is easy to see here that the <filename>kmem_alloc_24</filename> cache
contains what <command>::kmem_verify</command> believes to be a problem. 
With an explicit cache argument, the <command>::kmem_verify</command> dcmd
provides more detailed information about the problem:</para><programlisting format="linespecific">&gt; 70039928::kmem_verify
Summary for cache 'kmem_alloc_24'
  buffer 702babc0 (free) seems corrupted, at 702babc0</programlisting><para>The next step is to examine the buffer which <command>::kmem_verify</command> believes to be corrupt: </para><programlisting format="linespecific">&gt; 0x702babc0,5/KKn
0x702babc0:     0               deadbeef
                deadbeef        deadbeef
                deadbeef        deadbeef
                feedface        feedface
                703785a0        84d9714e</programlisting><para>The reason that <command>::kmem_verify</command> flagged this buffer
is now clear: The first word in the buffer (at <literal>0x702babc0</literal>)
should probably be filled with the <literal>0xdeadbeef</literal> pattern,
not with a <literal>0</literal>.  At this point, examining the <literal>bufctl_audit</literal> for this buffer might yield clues about what code recently wrote
to the buffer, indicating where and when it was freed.</para><para>Another useful technique in this situation is to use <command>::kgrep</command> to search the address space for references to address <literal>0x702babc0</literal>, in order to discover what threads or data structures
are still holding references to this freed data. </para></sect2><sect2 id="casestudy-38"><title>Allocator Logging Facility</title><para>When <literal>KMF_AUDIT</literal> is set for a cache, the kernel memory
allocator maintains a log that records the recent history of its activity.
 This <emphasis>transaction log</emphasis> records <literal>bufctl_audit</literal>
records. If the <literal>KMF_AUDIT</literal> and the <literal>KMF_CONTENTS</literal> flags are both set, the allocator generates a <emphasis>contents
log</emphasis> that records portions of the actual contents of allocated and
freed buffers.  The structure and use of the contents log is outside the scope
of this document. The transaction log is discussed in this section. <indexterm id="indexterm-474"><primary>transaction log</primary></indexterm><indexterm id="indexterm-475"><primary>contents log</primary></indexterm></para><para>MDB provides several facilities for displaying the transaction log.
 The simplest is <command>::walk kmem_log</command>, which prints out the
transaction in the log as a series of <literal>bufctl_audit_t</literal> pointers: <indexterm id="indexterm-476"><primary>Walkers</primary><secondary>kmem_log</secondary></indexterm></para><programlisting format="linespecific">&gt; ::walk kmem_log
70128340
701282e0
70128280
70128220
701281c0
...
&gt; 70128340$&lt;bufctl_audit
0x70128340:     next            addr            slab
                70ac1d40        70bc4ea8        70bb7c00
0x7012834c:     cache           timestamp       thread
                70039428        e1bd7abe721     70aacde0
0x7012835c:     lastlog         contents        stackdepth
                701282e0        7018f340        4
0x70128368:
                kmem_cache_free+0x24
                nfs3_sync+0x3c
                vfs_sync+0x84
                syssync+4</programlisting><para>A more elegant way to view the entire transaction log is by using the <command>::kmem_log</command> command:<indexterm id="indexterm-477"><primary>dcmds</primary><secondary><command>::kmem_log</command></secondary></indexterm></para><programlisting format="linespecific">&gt; ::kmem_log
CPU ADDR     BUFADDR         TIMESTAMP THREAD
  0 70128340 70bc4ea8      e1bd7abe721 70aacde0
  0 701282e0 70bc4ea8      e1bd7aa86fa 70aacde0
  0 70128280 70bc4ea8      e1bd7aa27dd 70aacde0
  0 70128220 70bc4ea8      e1bd7a98a6e 70aacde0
  0 701281c0 70d03738      e1bd7a8e3e0 70aacde0
  ...
  0 70127140 70cf78a0      e1bd78035ad 70aacde0
  0 701270e0 709cf6c0      e1bd6d2573a 40033e60
  0 70127080 70cedf20      e1bd6d1e984 40033e60
  0 70127020 70b09578      e1bd5fc1791 40033e60
  0 70126fc0 70cf78a0      e1bd5fb6b5a 40033e60
  0 70126f60 705ed388      e1bd5fb080d 40033e60
  0 70126f00 705ed388      e1bd551ff73 70aacde0
  ...</programlisting><para>The output of <command>::kmem_log</command> is sorted in descending
order by timestamp. The <literal>ADDR</literal> column is the <structname>bufctl_audit</structname> structure corresponding to that transaction; <literal>BUFADDR</literal> points to the actual buffer. </para><para>These figures represent <emphasis>transactions</emphasis> on buffers
(both allocations and frees). When a particular buffer is corrupted, it can
be helpful to locate that buffer in the transaction log, then determine in
which other transactions the transacting thread was involved.  This can help
to assemble a picture of the sequence of events that occurred prior to and
after the allocation (or free) of a buffer.</para><para><indexterm id="indexterm-478"><primary>dcmds</primary><secondary><command>::bufctl</command></secondary></indexterm>You can employ the <command>::bufctl</command> command to filter the output of walking the transaction log.  The <command>::bufctl -a</command> command filters the buffers in the transaction log by
buffer address.  This example filters on buffer <literal>0x70b09578</literal>:</para><programlisting format="linespecific">&gt; ::walk kmem_log | ::bufctl -a 0x70b09578
ADDR     BUFADDR   TIMESTAMP   THREAD   CALLER
70127020 70b09578  e1bd5fc1791 40033e60 biodone+0x108
70126e40 70b09578  e1bd55062da 70aacde0 pageio_setup+0x268
70126de0 70b09578  e1bd52b2317 40033e60 biodone+0x108
70126c00 70b09578  e1bd497ee8e 70aacde0 pageio_setup+0x268
70120480 70b09578  e1bd21c5e2a 70aacde0 elfexec+0x9f0
70120060 70b09578  e1bd20f5ab5 70aacde0 getelfhead+0x100
7011ef20 70b09578  e1bd1e9a1dd 70aacde0 ufs_getpage_miss+0x354
7011d720 70b09578  e1bd1170dc4 70aacde0 pageio_setup+0x268
70117d80 70b09578  e1bcff6ff27 70bc2480 elfexec+0x9f0
70117960 70b09578  e1bcfea4a9f 70bc2480 getelfhead+0x100
...</programlisting><para>This example illustrates that a particular buffer can be used in numerous
transactions.</para><note><gentext type="text">Note &#8211; </gentext><para>Remember that the kmem transaction log is an incomplete record
of the transactions made by the kernel memory allocator. Older entries in
the log are evicted as needed in order to keep the size of the log constant.</para></note><para><indexterm id="indexterm-479"><primary>dcmds</primary><secondary><command>::allocdby</command></secondary></indexterm><indexterm id="indexterm-480"><primary>dcmds</primary><secondary><command>::freedby</command></secondary></indexterm>The <command>::allocdby</command> and <command>::freedby</command> dcmds provide a convenient
way to summarize transactions associated with a particular thread.  Here is
an example of listing the recent allocations performed by thread <literal>0x70aacde0</literal>: </para><programlisting format="linespecific">&gt; 0x70aacde0::allocdby
BUFCTL      TIMESTAMP CALLER
70d4d8c0  e1edb14511a allocb+0x88
70d4e8a0  e1edb142472 dblk_constructor+0xc
70d4a240  e1edb13dd4f allocb+0x88
70d4e840  e1edb13aeec dblk_constructor+0xc
70d4d860  e1ed8344071 allocb+0x88
70d4e7e0  e1ed8342536 dblk_constructor+0xc
70d4a1e0  e1ed82b3a3c allocb+0x88
70a53f80  e1ed82b0b91 dblk_constructor+0xc
70d4d800  e1e9b663b92 allocb+0x88</programlisting><para>By examining <literal>bufctl_audit</literal> records, you can understand
the recent activities of a particular thread.</para></sect2></sect1></chapter><chapter id="api-5"><gentext type="text">Chapter 9</gentext><gentext type="toc">9.&#160;&#160;Module Programming API</gentext><title>Module Programming API</title><para>This chapter describes the structures and functions contained in the
MDB debugger module API. The header file <literal>&lt;sys/mdb_modapi.h&gt;</literal>
contains prototypes for these functions, and the SUNWmdbdm package provides
source code for an example module in the directory <literal>/usr/demo/mdb</literal>.</para><sect1 id="api-1"><title>Debugger Module Linkage</title><sect2 id="api-6"><title><function>_mdb_init<gentext type="text">()</gentext></function></title><programlisting format="linespecific">const mdb_modinfo_t *_mdb_init(void);</programlisting><para><indexterm id="indexterm-481"><primary><function>_mdb_init<gentext type="text">()</gentext></function></primary></indexterm>Each
debugger module is required to provide, for linkage and identification purposes,
a function named <function>_mdb_init<gentext type="text">()</gentext></function>. This function returns a pointer
to a persistent (that is, not declared as an automatic variable) <literal>mdb_modinfo_t</literal> structure, as defined in <literal>&lt;sys/mdb_modapi.h&gt;</literal>:<indexterm id="indexterm-482"><primary><literal>mdb_modinfo_t</literal></primary></indexterm></para><programlisting format="linespecific">typedef struct mdb_modinfo {
        ushort_t mi_dvers;               /* Debugger API version number */
        const mdb_dcmd_t *mi_dcmds;      /* NULL-terminated list of dcmds */
        const mdb_walker_t *mi_walkers;  /* NULL-terminated list of walks */
} mdb_modinfo_t;</programlisting><para><indexterm id="indexterm-483"><primary><literal>MDB_API_VERSION</literal></primary></indexterm>The <replaceable>mi_dvers</replaceable> member is used to identify the API version number,
and should always be set to <literal>MDB_API_VERSION</literal>. The current
version number is therefore compiled into each debugger module, allowing the
debugger to identify and verify the application binary interface used by the
module. The debugger does not load modules that are compiled for an API version
that is more recent than the debugger itself.</para><para>The <replaceable>mi_dcmds</replaceable> and <replaceable>mi_walkers</replaceable> members, if not NULL, point to arrays of dcmd and walker definition
structures, respectively. Each array must be terminated by a NULL element.
These dcmds and walkers are installed and registered with the debugger as
part of the module loading process. The debugger will refuse to load the module
if one or more dcmds or walkers are defined improperly or if they have conflicting
or invalid names. Dcmd and walker names are prohibited from containing characters
that have special meaning to the debugger, such as quotation marks and parentheses.</para><para>The module can also execute code in <function>_mdb_init<gentext type="text">()</gentext></function> using
the module API to determine if it is appropriate to load. For example, a module
can only be appropriate for a particular target if certain symbols are present.
If these symbols are not found, the module can return NULL from the <function>_mdb_init<gentext type="text">()</gentext></function> function. In this case, the debugger will refuse to load
the module and an appropriate error message is printed.  </para></sect2><sect2 id="api-7"><title><function>_mdb_fini<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void _mdb_fini(void);</programlisting><para><indexterm id="indexterm-484"><primary><function>_mdb_fini<gentext type="text">()</gentext></function></primary></indexterm>If
the module performs certain tasks prior to unloading, such as freeing persistent
memory previously allocated with <function>mdb_alloc<gentext type="text">()</gentext></function>, it can declare
a function named <function>_mdb_fini<gentext type="text">()</gentext></function> for this purpose. This function
is not required by the debugger. If declared, it is called once prior to unloading
the module. Modules are unloaded when the user requests that the debugger
terminate or when the user explicitly unloads a module using the <command>::unload</command> built-in dcmd. </para></sect2></sect1><sect1 id="api-2"><title>Dcmd Definitions</title><programlisting format="linespecific">int dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv);</programlisting><para>A dcmd is implemented with a function similar to the <function>dcmd<gentext type="text">()</gentext></function> declaration. This function receives four arguments and returns
an integer status. The function arguments are:</para><variablelist termlength="xtranarrow"><varlistentry><term><replaceable>addr</replaceable></term><listitem><para>Current address, also called dot. At the start of the dcmd, this address corresponds
to the value of the dot “ <literal>.</literal>”
variable in the debugger. </para></listitem></varlistentry><varlistentry><term><replaceable>flags</replaceable></term><listitem><para>Integer containing the logical OR of one or more of the following flags:</para><variablelist termlength="medium"><varlistentry><term><literal>DCMD_ADDRSPEC</literal></term><listitem><para>An explicit address was specified to the left of <command>::dcmd</command>.<indexterm id="indexterm-485"><primary><literal>DCMD_ADDRSPEC</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_LOOP</literal></term><listitem><para>The
dcmd was invoked in a loop using the <literal>,count</literal> syntax, or
the dcmd was invoked in a loop by a pipeline.<indexterm id="indexterm-486"><primary><literal>DCMD_LOOP</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_LOOPFIRST</literal></term><listitem><para>This invocation of the dcmd function corresponds to the first loop or pipeline
invocation.<indexterm id="indexterm-487"><primary><literal>DCMD_LOOPFIRST</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_PIPE</literal></term><listitem><para>The
dcmd was invoked with input from a pipeline.<indexterm id="indexterm-488"><primary><literal>DCMD_PIPE</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_PIPE_OUT</literal></term><listitem><para>The dcmd was invoked with output set to a pipeline.<indexterm id="indexterm-489"><primary><literal>DCMD_PIPE_OUT</literal></primary></indexterm></para></listitem></varlistentry></variablelist><para>As a convenience, the <function>DCMD_HDRSPEC<gentext type="text">()</gentext></function>
macro is provided to allow a dcmd to test its flags to determine if it should
print a header line (that is, it was not invoked as part of a loop, or it
was invoked as the first iteration of a loop or pipeline).</para></listitem></varlistentry><varlistentry><term><replaceable>argc</replaceable></term><listitem><para>Number of arguments in the <replaceable>argv</replaceable> array.</para></listitem></varlistentry><varlistentry><term><replaceable>argv</replaceable></term><listitem><para>Array of arguments specified to the right of <command>::dcmd</command> on
the command line. These arguments can be either strings or integer values.</para></listitem></varlistentry></variablelist><para>The dcmd function is expected to return one of the following
integer values, defined in <literal>&lt;sys/mdb_modapi.h&gt;</literal>.</para><variablelist termlength="narrow"><varlistentry><term><literal>DCMD_OK</literal></term><listitem><para>The dcmd
completed successfully.<indexterm id="indexterm-490"><primary><literal>DCMD_OK</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_ERR</literal></term><listitem><para>The
dcmd failed for some reason.<indexterm id="indexterm-491"><primary><literal>DCMD_ERR</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_USAGE</literal></term><listitem><para>The
dcmd failed because invalid arguments were specified. When this value is returned,
the dcmd usage message (described below) prints automatically.<indexterm id="indexterm-492"><primary><literal>DCMD_USAGE</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_NEXT</literal></term><listitem><para>The
next dcmd definition (if one is present) is automatically invoked with the
same arguments. <indexterm id="indexterm-493"><primary><literal>DCMD_NEXT</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>DCMD_ABORT</literal></term><listitem><para>The
dcmd failed, and the current loop or pipeline should be aborted. This is like <literal>DCMD_ERR</literal>, but indicates that no further progress is possible in
the current loop or pipe.<indexterm id="indexterm-494"><primary><literal>DCMD_ABORT</literal></primary></indexterm></para></listitem></varlistentry></variablelist><para>Each dcmd consists of a function defined according to
the example <function>dcmd<gentext type="text">()</gentext></function> prototype, and a corresponding <structname>mdb_dcmd_t</structname> structure, as defined in <literal>&lt;sys/mdb_modapi.h&gt;</literal>.  This structure consists
of the following fields:<indexterm id="indexterm-495"><primary><structname>mdb_dcmd_t</structname></primary></indexterm></para><variablelist><varlistentry><term><literal>const char *dc_name</literal></term><listitem><para>The string name of the dcmd, without the leading “<command>::</command>”. The name cannot contain any of the MDB meta-characters,
such as $<literal></literal> or <literal>`</literal>.</para></listitem></varlistentry><varlistentry><term><literal>const char *dc_usage</literal></term><listitem><para>An optional usage string for the dcmd, to be printed when the dcmd returns <literal>DCMD_USAGE</literal>.  For example, if the dcmd accepts options <option><gentext type="text">-</gentext>a</option> and <option><gentext type="text">-</gentext>b</option>, <literal>dc_usage</literal> might be specified
as “<literal>[<option><gentext type="text">-</gentext>ab</option>]</literal>”.  If the dcmd accepts
no arguments, <literal>dc_usage</literal> can be set to NULL.  If the usage
string begins with “<command>:</command>”, this is shorthand for
indicating that the dcmd requires an explicit address (that is, it requires <literal>DCMD_ADDRSPEC</literal> to be set in its flags parameter). If the usage string
begins with “<literal>?</literal>”, this indicates that the dcmd
optionally accepts an address. These hints modify the usage message accordingly.</para></listitem></varlistentry><varlistentry><term><literal>const char *dc_descr</literal></term><listitem><para>A mandatory description string, briefly explaining the purpose of the
dcmd. This string should consist of only a single line of text.</para></listitem></varlistentry><varlistentry><term><literal>mdb_dcmd_f *dc_funcp</literal></term><listitem><para>A pointer to the function that will be called to execute the dcmd.</para></listitem></varlistentry><varlistentry><term><literal>void (*dc_help)(void)</literal></term><listitem><para>An optional function pointer to a help function for the dcmd. If this
pointer is not NULL, this function will be called when the user executes <command>::help</command> <replaceable>dcmd</replaceable>. This function can use <function>mdb_printf<gentext type="text">()</gentext></function> to display further information or examples.</para></listitem></varlistentry></variablelist></sect1><sect1 id="api-3"><title>Walker Definitions</title><programlisting format="linespecific">int walk_init(mdb_walk_state_t *wsp);
int walk_step(mdb_walk_state_t *wsp);
void walk_fini(mdb_walk_state_t *wsp);</programlisting><para>A walker is composed of three functions, <literal>init</literal>, <literal>step</literal>, and <literal>fini</literal>, which are defined according to
the example prototypes above.  A walker is invoked by the debugger when one
of the walk functions (such as <function>mdb_walk<gentext type="text">()</gentext></function>) is called, or
when the user executes the <command>::walk</command> built-in dcmd.  When
the walk begins, MDB calls the walker's init function, passing it the address
of a new <structname>mdb_walk_state_t</structname> structure, as defined in <literal>&lt;sys/mdb_modapi.h&gt;</literal>:</para><programlisting format="linespecific">typedef struct mdb_walk_state {
			mdb_walk_cb_t walk_callback;    /* Callback to issue */
			void *walk_cbdata;              /* Callback private data */
			uintptr_t walk_addr;            /* Current address */
			void *walk_data;                /* Walk private data */
			void *walk_arg;                 /* Walk private argument */
			void *walk_layer;               /* Data from underlying layer */
} mdb_walk_state_t;</programlisting><para><indexterm id="indexterm-496"><primary><literal>mdb_walk_state_t</literal></primary></indexterm>A
separate <structname>mdb_walk_state_t</structname> is created for each walk,
so that multiple instances of the same walker can be active simultaneously.
The state structure contains the callback the walker should invoke at each
step (<replaceable>walk_callback</replaceable>), and the private data for
the callback (<replaceable>walk_cbdata</replaceable>), as specified to <function>mdb_walk<gentext type="text">()</gentext></function>, for example.  The <replaceable>walk_cbdata</replaceable>
pointer is opaque to the walker: it must not modify or dereference this value,
nor can it assume it is a pointer to valid memory.</para><para>The starting address for the walk is stored in <replaceable>walk_addr</replaceable>. This is either NULL if <function>mdb_walk<gentext type="text">()</gentext></function> was called,
or the address parameter specified to <function>mdb_pwalk<gentext type="text">()</gentext></function>. If the <command>::walk</command> built-in was used, <replaceable>walk_addr</replaceable> will
be non-NULL if an explicit address was specified on the left-hand side of <command>::walk</command>. A walk with a starting address of NULL is referred to as <emphasis>global</emphasis>. A walk with an explicit non-NULL starting address is referred
to as <emphasis>local</emphasis>. </para><para>The <replaceable>walk_data</replaceable> and <replaceable>walk_arg</replaceable>
fields are provided for use as private storage for the walker.  Complex walkers
might need to allocate an auxiliary state structure and set <replaceable>walk_data</replaceable> to point to this structure.  Each time a walk is initiated, <replaceable>walk_arg</replaceable> is initialized to the value of the <literal>walk_init_arg</literal> member of the corresponding walker's <literal>mdb_walker_t</literal>
structure.  </para><para>In some cases, it is useful to have several walkers share the same init,
step, and fini routines.  For example, the MDB <literal>genunix</literal>
module provides walkers for each kernel memory cache.  These share the same
init, step, and fini functions, and use the <literal>walk_init_arg</literal>
member of the <literal>mdb_walker_t</literal> to specify the address of the
appropriate cache as the <replaceable>walk_arg</replaceable>.</para><para>If the walker calls <function>mdb_layered_walk<gentext type="text">()</gentext></function> to instantiate
an underlying layer, then the underlying layer will reset <replaceable>walk_addr</replaceable> and <replaceable>walk_layer</replaceable> prior to each call
to the walker's step function.  The underlying layer sets <replaceable>walk_addr</replaceable> to the target virtual address of the underlying object, and
set <replaceable>walk_layer</replaceable> to point to the walker's local copy
of the underlying object.  For more information on layered walks, refer to
the discussion of <function>mdb_layered_walk<gentext type="text">()</gentext></function> below. </para><para>The walker init and step functions are expected to return one of the
following status values:</para><variablelist termlength="narrow"><varlistentry><term><literal>WALK_NEXT</literal></term><listitem><para><indexterm id="indexterm-497"><primary><literal>WALK_NEXT</literal></primary></indexterm>Proceed to the
next step.  When the walk init function returns <literal>WALK_NEXT</literal>,
MDB invokes the walk step function. When the walk step function returns <literal>WALK_NEXT</literal>, this indicates that MDB should call the step function
again.</para></listitem></varlistentry><varlistentry><term><literal>WALK_DONE</literal></term><listitem><para><indexterm id="indexterm-498"><primary><literal>WALK_DONE</literal></primary></indexterm>The walk has completed
successfully. <literal>WALK_DONE</literal> can be returned by either the step
function to indicate that the walk is complete, or by the init function to
indicate that no steps are needed (for example, if the given data structure
is empty).</para></listitem></varlistentry><varlistentry><term><literal>WALK_ERR</literal></term><listitem><para><indexterm id="indexterm-499"><primary><literal>WALK_ERR</literal></primary></indexterm>The walk has terminated
due to an error.  If <literal>WALK_ERR</literal> is returned by the init function, <function>mdb_walk<gentext type="text">()</gentext></function> (or any of its counterparts) returns –1 to indicate
that the walker failed to initialize.  If <literal>WALK_ERR</literal> is returned
by the step function, the walk terminates but <function>mdb_walk<gentext type="text">()</gentext></function>
returns success.</para></listitem></varlistentry></variablelist><para>The <replaceable>walk_callback</replaceable> is also
expected to return one of the values above. Therefore, the walk step function's
job is to determine the address of the next object, read in a local copy of
this object, call the <replaceable>walk_callback</replaceable> function, then
return its status.  The step function can also return <literal>WALK_DONE</literal>
or <literal>WALK_ERR</literal> without invoking the callback if the walk is
complete or if an error occurred.</para><para>The walker itself is defined using the <structname>mdb_walker_t</structname>
structure, defined in :</para><programlisting format="linespecific">typedef struct mdb_walker {
        const char *walk_name;                 /* Walk type name */
        const char *walk_descr;                /* Walk description */
        int (*walk_init)(mdb_walk_state_t *);  /* Walk constructor */
        int (*walk_step)(mdb_walk_state_t *);  /* Walk iterator */
        void (*walk_fini)(mdb_walk_state_t *); /* Walk destructor */
        void *walk_init_arg;                   /* Constructor argument */
} mdb_walker_t;</programlisting><para><indexterm id="indexterm-500"><primary><literal>mdb_walker_t</literal></primary></indexterm>The <literal>walk_name</literal> and <literal>walk_descr</literal> fields should be initialized
to point to strings containing the name and a brief description of the walker,
respectively. A walker is required to have a non-NULL name and description,
and the name cannot contain any of the MDB meta-characters.  The description
string is printed by the <command>::walkers</command> and <command>::dmods</command> built-in dcmds.</para><para> The <literal>walk_init</literal>, <literal>walk_step</literal>, and <literal>walk_fini</literal> members refer to the walk functions themselves, as described
earlier. The <literal>walk_init</literal> and <literal>walk_fini</literal>
members can be set to NULL to indicate that no special initialization or cleanup
actions need to be taken. The <literal>walk_step</literal> member cannot be
set to NULL. The <literal>walk_init_arg</literal> member is used to initialize
the <literal>walk_arg</literal> member of each new <literal>mdb_walk_state_t</literal> created for the given walker, as described earlier. <link linkend="api-fig-54">Figure 9–1</link>
shows a flowchart for the algorithm of a typical walker.</para><figure id="api-fig-54"><gentext type="text">Figure 9&#8211;1 </gentext><title>Sample Walker</title><graphic entityref="proc-t" width="498" depth="460"><![CDATA[Context describes graphic.]]></graphic></figure><para>The walker is designed to iterate over the list of <structname>proc_t</structname> structures in the kernel. The head of the list is stored in
the global <literal>practive</literal> variable, and each element's <literal>p_next</literal> pointer points to the next <structname>proc_t</structname>
in the list. The list is terminated with a NULL pointer. In the walker's <literal>init</literal> routine, the <literal>practive</literal> symbol is located
using <function>mdb_lookup_by_name<gentext type="text">()</gentext></function> step (1), and its value is copied
into the <structname>mdb_walk_state_t</structname> pointed to by <replaceable>wsp</replaceable>. </para><para>In the walker's step function, the next <structname>proc_t</structname>
structure in the list is copied into the debugger's address space using <function>mdb_vread<gentext type="text">()</gentext></function> step (2), the callback function is invoked with a pointer
to this local copy, step (3), and then the <structname>mdb_walk_state_t</structname>
is updated with the address of the <structname>proc_t</structname> structure
for the next iteration. This update corresponds to following the pointer,
step (4), to the next element in the list. </para><para>These steps demonstrate the structure of a typical walker: the init
routine locates the global information for a particular data structure, the
step function reads in a local copy of the next data item and passes it to
the callback function, and the address of the next element is read. Finally,
when the walk terminates, the fini function frees any private storage.</para></sect1><sect1 id="api-4"><title>API Functions</title><sect2 id="api-43"><title><function>mdb_pwalk<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_pwalk(const char *name, mdb_walk_cb_t func, void *data,
              uintptr_t addr);</programlisting><para><indexterm id="indexterm-501"><primary><function>mdb_pwalk<gentext type="text">()</gentext></function></primary></indexterm>Initiate
a local walk starting at <replaceable>addr</replaceable> using the walker
specified by <replaceable>name</replaceable>, and invoke the callback function <replaceable>func</replaceable> at each step.  If <replaceable>addr</replaceable> is NULL,
a global walk is performed (that is, the <function>mdb_pwalk<gentext type="text">()</gentext></function> invocation
is equivalent to the identical call to <function>mdb_walk<gentext type="text">()</gentext></function> without
the trailing <replaceable>addr</replaceable> parameter).  This function returns
0 for success, or -1 for error.  The <function>mdb_pwalk<gentext type="text">()</gentext></function> function
fails if the walker itself returns a fatal error, or if the specified walker
name is not known to the debugger. The walker name may be scoped using the
backquote (<literal>`</literal>) operator if there are naming conflicts. The <replaceable>data</replaceable> parameter is an opaque argument that has meaning only to
the caller; it is passed back to <replaceable>func</replaceable> at each step
of the walk.</para></sect2><sect2 id="api-42"><title><function>mdb_walk<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_walk(const char *name, mdb_walk_cb_t func, void *data);</programlisting><para><indexterm id="indexterm-502"><primary><function>mdb_walk<gentext type="text">()</gentext></function></primary></indexterm>Initiate
a global walk starting at <replaceable>addr</replaceable> using the walker
specified by <replaceable>name</replaceable>, and invoke the callback function <replaceable>func</replaceable> at each step.  This function returns 0 for success, or
-1 for error.  The <function>mdb_walk<gentext type="text">()</gentext></function> function fails if the walker
itself returns a fatal error, or if the specified walker name is not known
to the debugger. The walker name can be scoped using the backquote (<literal>`</literal>) operator if there are naming conflicts. The data parameter is
an opaque argument that has meaning only to the caller; it is passed back
to <replaceable>func</replaceable> at each step of the walk.</para></sect2><sect2 id="api-41"><title><function>mdb_pwalk_dcmd<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_pwalk_dcmd(const char *wname, const char *dcname, int argc,
			const mdb_arg_t *argv, uintptr_t addr);</programlisting><para><indexterm id="indexterm-503"><primary><function>mdb_pwalk_dcmd<gentext type="text">()</gentext></function></primary></indexterm>Initiate
a local walk starting at <replaceable>addr</replaceable> using the walker
specified by <replaceable>wname</replaceable>, and invoke the dcmd specified
by <replaceable>dcname</replaceable> with the specified <replaceable>argc</replaceable> and <replaceable>argv</replaceable> at each step. This function
returns 0 for success, or -1 for error.  The function fails if the walker
itself returns a fatal error, if the specified walker name or dcmd name is
not known to the debugger, or if the dcmd itself returns <literal>DCMD_ABORT</literal> or <literal>DCMD_USAGE</literal> to the walker. The walker name
and dcmd name can each be scoped using the backquote (<literal>`</literal>)
operator if there are naming conflicts.  When invoked from <function>mdb_pwalk_dcmd<gentext type="text">()</gentext></function>, the dcmd will have the <literal>DCMD_LOOP</literal> and <literal>DCMD_ADDRSPEC</literal> bits set in its flags parameter, and the first call
will have <literal>DCMD_LOOPFIRST</literal> set.</para></sect2><sect2 id="api-44"><title><function>mdb_walk_dcmd<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_walk_dcmd(const char *wname, const char *dcname, int argc,
			const mdb_arg_t *argv);</programlisting><para><indexterm id="indexterm-504"><primary><function>mdb_walk_dcmd<gentext type="text">()</gentext></function></primary></indexterm>Initiate
a global walk using the walker specified by <replaceable>wname</replaceable>,
and invoke the dcmd specified by <replaceable>dcname</replaceable> with the
specified <replaceable>argc</replaceable> and <replaceable>argv</replaceable>
at each step.  This function returns 0 for success, or -1 for error. The function
fails if the walker itself returns a fatal error, if the specified walker
name or dcmd name is not known to the debugger, or if the dcmd itself returns <literal>DCMD_ABORT</literal> or <literal>DCMD_USAGE</literal> to the walker. The walker
name and dcmd name can each be scoped using the backquote (<literal>`</literal>)
operator if there are naming conflicts.  When invoked from <function>mdb_walk_dcmd<gentext type="text">()</gentext></function>, the dcmd will have the <literal>DCMD_LOOP</literal> and <literal>DCMD_ADDRSPEC</literal> bits set in its flags parameter, and the first call
will have <literal>DCMD_LOOPFIRST</literal> set.</para></sect2><sect2 id="api-45"><title><function>mdb_call_dcmd<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_call_dcmd(const char *name, uintptr_t addr, uint_t flags, 
			int argc, const mdb_arg_t *argv);</programlisting><para><indexterm id="indexterm-505"><primary><function>mdb_call_dcmd<gentext type="text">()</gentext></function></primary></indexterm>Invoke
the specified dcmd name with the given parameters.  The dot variable is reset
to <replaceable>addr</replaceable>, and <replaceable>addr</replaceable>, <replaceable>flags</replaceable>, <replaceable>argc</replaceable>, and <replaceable>argv</replaceable> are passed to the dcmd.  The function returns 0 for success,
or -1 for error. The function fails if the dcmd returns <literal>DCMD_ERR</literal>, <literal>DCMD_ABORT</literal>, or <literal>DCMD_USAGE</literal>,
or if the specified dcmd name is not known to the debugger.  The dcmd name
can be scoped using the backquote (<literal>`</literal>) operator if there
are naming conflicts.</para></sect2><sect2 id="api-46"><title><function>mdb_layered_walk<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_layered_walk(const char *name, mdb_walk_state_t *wsp);</programlisting><para><indexterm id="indexterm-506"><primary><function>mdb_layered_walk<gentext type="text">()</gentext></function></primary></indexterm>Layer the walk denoted by <replaceable>wsp</replaceable> on top
of a walk initiated using the specified walker <replaceable>name</replaceable>.
The name can be scoped using the backquote (<literal>`</literal>) operator
if there are naming conflicts. Layered walks can be used, for example, to
facilitate constructing walkers for data structures that are embedded in other
data structures. </para><para>For example, suppose that each CPU structure in the kernel contains
a pointer to an embedded structure. To write a walker for the embedded structure
type, you could replicate the code to iterate over CPU structures and dereference
the appropriate member of each CPU structure, or you could layer the embedded
structure's walker on top of the existing CPU walker.</para><para>The <function>mdb_layered_walk<gentext type="text">()</gentext></function> function is used from within
a walker's init routine to add a new layer to the current walk.  The underlying
layer is initialized as part of the call to <function>mdb_layered_walk<gentext type="text">()</gentext></function>.
The calling walk routine passes in a pointer to its current walk state; this
state is used to construct the layered walk. Each layered walk is cleaned
up after the caller's walk fini function is called.  If more than one layer
is added to a walk, the caller's walk step function will step through each
element returned by the first layer, then the second layer, and so forth.</para><para>The <function>mdb_layered_walk<gentext type="text">()</gentext></function> function returns 0 for success,
or -1 for error. The function fails if the specified walker name is not known
to the debugger, if the <replaceable>wsp</replaceable> pointer is not a valid,
active walk state pointer, if the layered walker itself fails to initialize,
or if the caller attempts to layer the walker on top of itself.</para></sect2><sect2 id="api-37"><title><function>mdb_add_walker<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_add_walker(const mdb_walker_t *w);</programlisting><para><indexterm id="indexterm-507"><primary><function>mdb_add_walker<gentext type="text">()</gentext></function></primary></indexterm>Register
a new walker with the debugger. The walker is added to the module's namespace,
and to the debugger's global namespace according to the name resolution rules
described in <link linkend="syntax-13">dcmd and Walker Name Resolution</link>. This function returns 0 for success,
or -1 for error if the given walker name is already registered by this module,
or if the walker structure <replaceable>w</replaceable> is improperly constructed.
The information in the <structfield>mdb_walker_t</structfield> <replaceable>w</replaceable> is copied to internal debugger structures, so the caller can
reuse or free this structure after the call to <function>mdb_add_walker<gentext type="text">()</gentext></function>.
                 </para></sect2><sect2 id="api-36"><title><function>mdb_remove_walker<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_remove_walker(const char *name);</programlisting><para><indexterm id="indexterm-508"><primary><function>mdb_remove_walker<gentext type="text">()</gentext></function></primary></indexterm>Remove the walker with the specified <replaceable>name</replaceable>.
This function returns 0 for success, or -1 for error. The walker is removed
from the current module's namespace. The function fails if the walker name
is unknown, or is registered only in another module's namespace. The <function>mdb_remove_walker<gentext type="text">()</gentext></function> function can be used to remove walkers that were
added dynamically using <function>mdb_add_walker<gentext type="text">()</gentext></function>, or walkers that
were added statically as part of the module's linkage structure. The scoping
operator cannot be used in the walker name; it is not legal for the caller
of <function>mdb_remove_walker<gentext type="text">()</gentext></function> to attempt to remove a walker exported
by a different module.</para></sect2><sect2 id="api-35"><title><function>mdb_vread<gentext type="text">()</gentext></function> and <function>mdb_vwrite<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_vread(void *buf, size_t nbytes, uintptr_t addr);
ssize_t mdb_vwrite(const void *buf, size_t nbytes, uintptr_t addr);</programlisting><para><indexterm id="indexterm-509"><primary><function>mdb_vread<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-510"><primary><function>mdb_vwrite<gentext type="text">()</gentext></function></primary></indexterm>These functions
provide the ability to read and write data from a given target virtual address,
specified by the <replaceable>addr</replaceable> parameter. The <function>mdb_vread<gentext type="text">()</gentext></function> function returns <replaceable>nbytes</replaceable> for
success, or -1 for error; if a read is truncated because only a portion of
the data can be read from the specified address, -1 is returned. The <function>mdb_vwrite<gentext type="text">()</gentext></function> function returns the number of bytes actually written
upon success; -1 is returned upon error.</para></sect2><sect2 id="api-59"><title><function>mdb_fread<gentext type="text">()</gentext></function> and <function>mdb_fwrite<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_fread(void *buf, size_t nbytes, uintptr_t addr);
ssize_t mdb_fwrite(const void *buf, size_t nbytes, uintptr_t addr);</programlisting><para><indexterm id="indexterm-511"><primary><function>mdb_fread<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-512"><primary><function>mdb_fwrite<gentext type="text">()</gentext></function></primary></indexterm>These functions
provide the ability to read and write data from the object file location corresponding
to the given target virtual address, specified by the <literal>addr</literal>
parameter.  The <function>mdb_fread<gentext type="text">()</gentext></function> function returns <literal>nbytes</literal> for success, or -1 for error; if a read is truncated because
only a portion of the data can be read from the specified address, -1 is returned.
 The <function>mdb_fwrite<gentext type="text">()</gentext></function> function returns the number of bytes
actually written upon success; -1 is returned upon error.</para></sect2><sect2 id="api-34"><title><function>mdb_pread<gentext type="text">()</gentext></function> and <function>mdb_pwrite<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_pread(void *buf, size_t nbytes, uint64_t addr);
ssize_t mdb_pwrite(const void *buf, size_t nbytes, uint64_t addr);</programlisting><para><indexterm id="indexterm-513"><primary><function>mdb_pread<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-514"><primary><function>mdb_pwrite<gentext type="text">()</gentext></function></primary></indexterm>These functions
provide the ability to read and write data from a given target physical address,
specified by the <replaceable>addr</replaceable> parameter. The <function>mdb_pread<gentext type="text">()</gentext></function> function returns <replaceable>nbytes</replaceable> for
success, or -1 for error; if a read is truncated because only a portion of
the data can be read from the specified address, -1 is returned. The <function>mdb_pwrite<gentext type="text">()</gentext></function> function returns the number of bytes actually written
upon success; -1 is returned upon error.</para></sect2><sect2 id="api-33"><title><function>mdb_readstr<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_readstr(char *s, size_t nbytes, uintptr_t addr);</programlisting><para><indexterm id="indexterm-515"><primary><function>mdb_readstr<gentext type="text">()</gentext></function></primary></indexterm>The <function>mdb_readstr<gentext type="text">()</gentext></function> function reads a null-terminated C string beginning
at the target virtual address <replaceable>addr</replaceable> into the buffer
addressed by <replaceable>s</replaceable>. The size of the buffer is specified
by <replaceable>nbytes</replaceable>. If the string is longer than can fit
in the buffer, the string is truncated to the buffer size and a null byte
is stored at <literal>s[nbytes - 1]</literal>. The length of the string stored
in <replaceable>s</replaceable> (not including the terminating null byte)
is returned upon success; otherwise -1 is returned to indicate an error.</para></sect2><sect2 id="api-32"><title><function>mdb_writestr<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_writestr(const char *s, uintptr_t addr);</programlisting><para><indexterm id="indexterm-516"><primary><function>mdb_writestr<gentext type="text">()</gentext></function></primary></indexterm>The <function>mdb_writestr<gentext type="text">()</gentext></function> function writes a null-terminated C string from <replaceable>s</replaceable> (including the trailing null byte) to the target's virtual
address space at the address specified by <replaceable>addr</replaceable>.
The number of bytes written (not including the terminating null byte) is returned
upon success; otherwise, -1 is returned to indicate an error.</para></sect2><sect2 id="api-47"><title><function>mdb_readsym<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_readsym(void *buf, size_t nbytes, const char *name);</programlisting><para><indexterm id="indexterm-517"><primary><function>mdb_readsym<gentext type="text">()</gentext></function></primary></indexterm><function>mdb_readsym<gentext type="text">()</gentext></function> is similar to <function>mdb_vread<gentext type="text">()</gentext></function>, except
that the virtual address at which reading begins is obtained from the value
of the symbol specified by <replaceable>name</replaceable>. If no symbol by
that name is found or a read error occurs, -1 is returned; otherwise <replaceable>nbytes</replaceable> is returned for success. </para><para>The caller can first look up the symbol separately if it is necessary
to distinguish between symbol lookup failure and read failure. The primary
executable's symbol table is used for the symbol lookup; if the symbol resides
in another symbol table, you must first apply <function>mdb_lookup_by_obj<gentext type="text">()</gentext></function>, then <function>mdb_vread<gentext type="text">()</gentext></function>.</para></sect2><sect2 id="api-30"><title><function>mdb_writesym<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_writesym(const void *buf, size_t nbytes, const char *name);</programlisting><para><indexterm id="indexterm-518"><primary><function>mdb_writesym<gentext type="text">()</gentext></function></primary></indexterm><function>mdb_writesym<gentext type="text">()</gentext></function> is identical to <function>mdb_vwrite<gentext type="text">()</gentext></function>, except
that the virtual address at which writing begins is obtained from the value
of the symbol specified by name. If no symbol by that name is found, -1 is
returned. Otherwise, the number of bytes successfully written is returned
on success, and -1 is returned on error. The primary executable's symbol table
is used for the symbol lookup; if the symbol resides in another symbol table,
you must first apply <function>mdb_lookup_by_obj<gentext type="text">()</gentext></function>, then <function>mdb_vwrite<gentext type="text">()</gentext></function>.</para></sect2><sect2 id="api-29"><title><function>mdb_readvar<gentext type="text">()</gentext></function> and <function>mdb_writevar<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_readvar(void *buf, const char *name);
ssize_t mdb_writevar(const void *buf, const char *name);</programlisting><para><indexterm id="indexterm-519"><primary><function>mdb_readvar<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-520"><primary><function>mdb_writevar<gentext type="text">()</gentext></function></primary></indexterm><function>mdb_readvar<gentext type="text">()</gentext></function> is similar to <function>mdb_vread<gentext type="text">()</gentext></function>, except
that the virtual address at which reading begins and the number of bytes to
read are obtained from the value and size of the symbol specified by <replaceable>name</replaceable>.  If no symbol by that name is found, -1 is returned. The
symbol size (the number of bytes read) is returned on success; -1 is returned
on error. This is useful for reading well-known variables whose sizes are
fixed. For example:</para><programlisting format="linespecific">				int hz; 	/* system clock rate */
				mdb_readvar(&amp;hz, "hz");</programlisting><para>The caller can first look up the symbol separately if it is necessary
to distinguish between symbol lookup failure and read failure.  The caller
must also carefully check the definition of the symbol of interest in order
to make sure that the local declaration is the exact same type as the target's
definition. For example, if the caller declares an <literal>int</literal>,
and the symbol of interest is actually a <literal>long</literal>, and the
debugger is examining a 64-bit kernel target, <function>mdb_readvar<gentext type="text">()</gentext></function>
copies back 8 bytes to the caller's buffer, corrupting the 4 bytes following
the storage for the <literal>int</literal>.</para><para><function>mdb_writevar<gentext type="text">()</gentext></function> is identical to <function>mdb_vwrite<gentext type="text">()</gentext></function>, except that the virtual address at which writing begins and the
number of bytes to write are obtained from the value and size of the symbol
specified by name.  If no symbol by that name is found, -1 is returned. Otherwise,
the number of bytes successfully written is returned on success, and -1 is
returned on error.</para><para>For both functions, the primary executable's symbol table is used for
the symbol lookup; if the symbol resides in another symbol table, you must
first apply <function>mdb_lookup_by_obj<gentext type="text">()</gentext></function>, then <function>mdb_vread<gentext type="text">()</gentext></function> or <function>mdb_vwrite<gentext type="text">()</gentext></function>.</para></sect2><sect2 id="api-28"><title><function>mdb_lookup_by_name<gentext type="text">()</gentext></function> and <function>mdb_lookup_by_obj<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_lookup_by_name(const char *name, GElf_Sym *sym);
int mdb_lookup_by_obj(const char *object, const char *name, GElf_Sym *sym);</programlisting><para><indexterm id="indexterm-521"><primary><function>mdb_lookup_by_name<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-522"><primary><function>mdb_lookup_by_obj<gentext type="text">()</gentext></function></primary></indexterm>Look up the specified symbol name and copy the ELF symbol information
into the <structfield>GElf_Sym</structfield> pointed to by <replaceable>sym</replaceable>. If the symbol is found, the function returns 0; otherwise,
-1 is returned. The <replaceable>name</replaceable> parameter specifies the
symbol name. The <replaceable>object</replaceable> parameter tells the debugger
where to look for the symbol. For the <function>mdb_lookup_by_name<gentext type="text">()</gentext></function>
function, the object file defaults to <literal>MDB_OBJ_EXEC</literal>. For <function>mdb_lookup_by_obj<gentext type="text">()</gentext></function>, the object name should be one of the following:</para><variablelist termlength="narrow"><varlistentry><term><literal>MDB_OBJ_EXEC</literal></term><listitem><para><indexterm id="indexterm-523"><primary><literal>MDB_OBJ_EXEC</literal></primary></indexterm>Look in the
executable's symbol table (<literal>.symtab</literal> section). For kernel
crash dumps, this corresponds to the symbol table from the <literal>unix.X</literal> file or from <literal>/dev/ksyms</literal>.</para></listitem></varlistentry><varlistentry><term><literal>MDB_OBJ_RTLD</literal></term><listitem><para><indexterm id="indexterm-524"><primary><literal>MDB_OBJ_RTLD</literal></primary></indexterm>Look in the
runtime link-editor's symbol table. For kernel crash dumps, this corresponds
to the symbol table for the <literal>krtld</literal> module.</para></listitem></varlistentry><varlistentry><term><literal>MDB_OBJ_EVERY</literal></term><listitem><para><indexterm id="indexterm-525"><primary><literal>MDB_OBJ_EVERY</literal></primary></indexterm>Look in all
known symbol tables. For kernel crash dumps, this includes the <literal>.symtab</literal> and <literal>.dynsym</literal> sections from the  <literal>unix.X</literal> file or <literal>/dev/ksyms</literal>, as well as per-module symbol
tables if these have been processed.</para></listitem></varlistentry><varlistentry><term><literal>object</literal></term><listitem><para>If the
name of a particular load object is explicitly specified, the search is restricted
to the symbol table of this object. The object can be named according to the
naming convention for load objects described in <link linkend="syntax-16">Symbol Name Resolution</link>.
      </para></listitem></varlistentry></variablelist></sect2><sect2 id="api-48"><title><function>mdb_lookup_by_addr<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_lookup_by_addr(uintptr_t addr, uint_t flag, char *buf,
				size_t len, GElf_Sym *sym);</programlisting><para><indexterm id="indexterm-526"><primary><function>mdb_lookup_by_addr<gentext type="text">()</gentext></function></primary></indexterm>Locate the symbol corresponding to the specified address and copy
the ELF symbol information into the <structfield>GElf_Sym</structfield> pointed
to by <replaceable>sym</replaceable> and the symbol name into the character
array addressed by <replaceable>buf</replaceable>. If a corresponding symbol
is found, the function returns 0; otherwise -1 is returned.</para><para>The flag parameter specifies the lookup mode and should be one of the
following:<variablelist termlength="narrow"><varlistentry><term><literal>MDB_SYM_FUZZY</literal></term><listitem><para>Allow fuzzy matching to take place, based on the current symbol distance setting.
The symbol distance can be controlled using the <command>::set</command> <option><gentext type="text">-</gentext>s</option> built-in. If an explicit symbol distance has been set (absolute
mode), the address can match a symbol if the distance from the symbol's value
to the address does not exceed the absolute symbol distance. If smart mode
is enabled (symbol distance = 0), then the address can match the symbol if
it is in the range [symbol value, symbol value + symbol size).  <indexterm id="indexterm-527"><primary><literal>MDB_SYM_FUZZY</literal></primary></indexterm>    </para></listitem></varlistentry><varlistentry><term><literal>MDB_SYM_EXACT</literal></term><listitem><para>Disallow fuzzy matching. The symbol can match only the address if the symbol
value exactly equals the specified address.<indexterm id="indexterm-528"><primary><literal>MDB_SYM_EXACT</literal></primary></indexterm></para></listitem></varlistentry></variablelist></para><para>If a symbol match occurs, the name of the symbol is copied into the <replaceable>buf</replaceable> supplied by the caller. The <replaceable>len</replaceable>
parameter specifies the length of this buffer in bytes. The caller's <replaceable>buf</replaceable> should be at least of size <literal>MDB_SYM_NAMLEN</literal>
bytes. The debugger copies the name to this buffer and appends a trailing
null byte. If the name length exceeds the length of the buffer, the name is
truncated but always includes a trailing null byte.</para></sect2><sect2 id="api-26"><title><function>mdb_getopts<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_getopts(int argc, const mdb_arg_t *argv, ...);</programlisting><para><indexterm id="indexterm-529"><primary><function>mdb_getopts<gentext type="text">()</gentext></function></primary></indexterm>Parse
and process options and option arguments from the specified argument array
(<replaceable>argv</replaceable>).  The <replaceable>argc</replaceable> parameter
denotes the length of the argument array. This function processes each argument
in order, and stops and returns the array index of the first argument that
could not be processed.  If all arguments are processed successfully, <replaceable>argc</replaceable> is returned.  </para><para>Following the <replaceable>argc</replaceable> and <replaceable>argv</replaceable> parameters, the <function>mdb_getopts<gentext type="text">()</gentext></function> function accepts
a variable list of arguments describing the options that are expected to appear
in the <replaceable>argv</replaceable> array.  Each option is described by
an option letter (<literal>char</literal> argument), an option type (<literal>uint_t</literal> argument), and one or two additional arguments, as shown
in the table below. The list of option arguments is terminated with a NULL
argument.  The type should be one of one of the following:<variablelist termlength="medium"><varlistentry><term><literal>MDB_OPT_SETBITS</literal></term><listitem><para>The option will <literal>OR</literal> the specified bits into a flag word.
The option is described by these parameters:</para><para><literal>char c, uint_t type, uint_t bits, uint_t *p</literal></para><para>If type is <literal>MDB_OPT_SETBITS</literal> and option <replaceable>c</replaceable> is detected in the <replaceable>argv</replaceable> list, the
debugger will <literal>OR</literal> bits into the integer referenced by pointer <replaceable>p</replaceable>.<indexterm id="indexterm-530"><primary><literal>MDB_OPT_SETBITS</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_OPT_CLRBITS</literal></term><listitem><para>The option clears the specified bits from a flag word. The option is described
by these parameters:</para><para><literal>char c, uint_t type, uint_t bits, uint_t *p</literal></para><para>If type is <literal>MDB_OPT_CLRBITS</literal> and option <replaceable>c</replaceable> is detected in the <replaceable>argv</replaceable> list, the
debugger clears bits from the integer referenced by pointer <replaceable>p</replaceable>.<indexterm id="indexterm-531"><primary><literal>MDB_OPT_CLRBITS</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_OPT_STR</literal></term><listitem><para>The option accepts a string argument. The option is described by these parameters:</para><para><literal>char c, uint_t type, const char **p</literal></para><para>If type is <literal>MDB_OPT_STR</literal> and option <replaceable>c</replaceable> is detected in the <replaceable>argv</replaceable> list, the
debugger stores a pointer to the string argument following <replaceable>c</replaceable> in the pointer referenced by <replaceable>p</replaceable>.<indexterm id="indexterm-532"><primary><literal>MDB_OPT_STR</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_OPT_UINTPTR</literal></term><listitem><para>The option accepts a <literal>uintptr_t</literal> argument. The option is
described by these parameters:</para><para><literal>char c, uint_t type, uintptr_t *p</literal></para><para>If type is <literal>MDB_OPT_UINTPTR</literal> and option c is detected
in the <replaceable>argv</replaceable> list, the debugger stores the integer
argument following <replaceable>c</replaceable> in the <literal>uintptr_t</literal> referenced by <replaceable>p</replaceable>.<indexterm id="indexterm-533"><primary><literal>MDB_OPT_UINTPTR</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_OPT_UINT64</literal></term><listitem><para>The option accepts a <literal>uint64_t</literal> argument. The option is described
by these parameters:</para><para><literal>char c, uint_t type, uint64_t *p</literal></para><para>If type is <literal>MDB_OPT_UINT64</literal> and option <replaceable>c</replaceable> is detected in the <replaceable>argv</replaceable> list, the
debugger stores the integer argument following <replaceable>c</replaceable>
in the <literal>uint64_t</literal> referenced by <replaceable>p</replaceable>.<indexterm id="indexterm-534"><primary><literal>MDB_OPT_UINT64</literal></primary></indexterm></para></listitem></varlistentry></variablelist></para><para>For example, the following source code:<programlisting format="linespecific">int
dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
        uint_t opt_v = FALSE;
        const char *opt_s = NULL;

        if (mdb_getopts(argc, argv,
            'v', MDB_OPT_SETBITS, TRUE, &amp;opt_v,
            's', MDB_OPT_STR, &amp;opt_s, NULL) != argc)
                return (DCMD_USAGE);

        /* ... */
}</programlisting>demonstrates how <function>mdb_getopts<gentext type="text">()</gentext></function> might
be used in a dcmd to accept a boolean option “<option><gentext type="text">-</gentext>v</option>”
that sets the <replaceable>opt_v</replaceable> variable to TRUE, and an option “<option><gentext type="text">-</gentext>s</option>” that accepts a string argument that is stored in the <replaceable>opt_s</replaceable> variable. The <function>mdb_getopts<gentext type="text">()</gentext></function> function
also automatically issues warning messages if it detects an invalid option
letter or missing option argument before returning to the caller. The storage
for argument strings and the <replaceable>argv</replaceable> array is automatically
garbage-collected by the debugger upon completion of the dcmd.</para></sect2><sect2 id="api-25"><title><function>mdb_strtoull<gentext type="text">()</gentext></function></title><programlisting format="linespecific">u_longlong_t mdb_strtoull(const char *s);</programlisting><para><indexterm id="indexterm-535"><primary><function>mdb_strtoull<gentext type="text">()</gentext></function></primary></indexterm>Convert
the specified string <replaceable>s</replaceable> to an <literal>unsigned
long long</literal> representation. This function is intended for use in processing
and converting string arguments in situations where <function>mdb_getopts<gentext type="text">()</gentext></function> is not appropriate. If the string argument cannot be converted
to a valid integer representation, the function fails by printing an appropriate
error message and aborting the dcmd. Therefore, error checking code is not
required. The string can be prefixed with any of the valid base specifiers
(0i, 0I, 0o, 0O, 0t, 0T, 0x, or 0X); otherwise, it is interpreted using the
default base. The function will fail and abort the dcmd if any of the characters
in <replaceable>s</replaceable> are not appropriate for the base, or if integer
overflow occurs.</para></sect2><sect2 id="api-24"><title><function>mdb_alloc<gentext type="text">()</gentext></function>, <function>mdb_zalloc<gentext type="text">()</gentext></function> and <function>mdb_free<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void *mdb_alloc(size_t size, uint_t flags);
void *mdb_zalloc(size_t size, uint_t flags);
void mdb_free(void *buf, size_t size);</programlisting><para><indexterm id="indexterm-536"><primary><function>mdb_alloc<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-537"><primary><function>mdb_zalloc<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-538"><primary><function>mdb_free<gentext type="text">()</gentext></function></primary></indexterm><function>mdb_alloc<gentext type="text">()</gentext></function> allocates <replaceable>size</replaceable> bytes of debugger memory
and returns a pointer to the allocated memory. The allocated memory is at
least double-word aligned, so it can hold any C data structure.  No greater
alignment can be assumed. The <replaceable>flags</replaceable> parameter should
be the bitwise <literal>OR</literal> of one or more of the following values:<variablelist termlength="narrow"><varlistentry><term><literal>UM_NOSLEEP</literal></term><listitem><para>If
sufficient memory to fulfill the request is not immediately available, return
NULL to indicate failure. The caller must check for NULL and handle this case
appropriately.<indexterm id="indexterm-539"><primary><literal>UM_NOSLEEP</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>UM_SLEEP</literal></term><listitem><para>If sufficient
memory to fulfill the request is not immediately available, sleep until such
time as the request can be fulfilled. As a result, <literal>UM_SLEEP</literal>
allocations are guaranteed to succeed. The caller need not check for a NULL
return value.<indexterm id="indexterm-540"><primary><literal>UM_SLEEP</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>UM_GC</literal></term><listitem><para>Garbage-collect
allocation automatically at the end of this debugger command. The caller should
not subsequently call <function>mdb_free<gentext type="text">()</gentext></function> on this block, as the
debugger will take care of de-allocation automatically.  All memory allocation
from within a dcmd must use <literal>UM_GC</literal> so that if the dcmd is
interrupted by the user, the debugger can garbage-collect the memory.<indexterm id="indexterm-541"><primary><literal>UM_GC</literal></primary></indexterm></para></listitem></varlistentry></variablelist></para><para><function>mdb_zalloc<gentext type="text">()</gentext></function> is like <function>mdb_alloc<gentext type="text">()</gentext></function>,
but the allocated memory is filled with zeroes before returning it to the
caller. No guarantees are made about the initial contents of memory returned
by <function>mdb_alloc<gentext type="text">()</gentext></function>.  <function>mdb_free<gentext type="text">()</gentext></function> is used
to free previously allocated memory (unless it was allocated <literal>UM_GC</literal>).  The buffer address and size must exactly match the original
allocation. It is not legal to free only a portion of an allocation with <function>mdb_free<gentext type="text">()</gentext></function>. It is not legal to free an allocation more than once.
An allocation of zero bytes always returns NULL; freeing a NULL pointer with
size zero always succeeds.</para></sect2><sect2 id="api-18"><title><function>mdb_printf<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void mdb_printf(const char *format, ...);</programlisting><para><indexterm id="indexterm-542"><primary><function>mdb_printf<gentext type="text">()</gentext></function></primary></indexterm>Print
formatted output using the specified format string and arguments. Module writers
should use <function>mdb_printf<gentext type="text">()</gentext></function> for all output, except for warning
and error messages. This function automatically triggers the built-in output
pager when appropriate. The <function>mdb_printf<gentext type="text">()</gentext></function> function is similar
to <olink targetdocent="REFMAN3A" localinfo="PRINTF-3C" type="v-only"><citerefentry><refentrytitle>printf</refentrytitle><manvolnum><gentext type="text">(</gentext>3C<gentext type="text">)</gentext></manvolnum></citerefentry></olink>,
with certain exceptions: the <literal>%C</literal>, <literal>%S</literal>,
and <literal>%ws</literal> specifiers for wide character strings are not supported,
the <literal>%f</literal> floating-point format is not supported, the <literal>%e</literal>, <literal>%E</literal>, <literal>%g</literal>, and <literal>%G</literal> specifiers for alternative double formats produce only a single
style of output, and precision specifications of the form <literal>%.n</literal>
are not supported. The list of specifiers that are supported follows:</para><sect3 id="api-23"><title>Flag Specifiers</title><indexterm id="indexterm-543"><primary>flag specifiers</primary></indexterm><variablelist termlength="xtranarrow"><varlistentry><term><literal>%#</literal></term><listitem><para>If the <literal>#</literal> sign is found in the format string, this selects the alternate
form of the given format.  Not all formats have an alternate form; the alternate
form is different depending on the format. Refer to the format descriptions
below for details on the alternate format.</para></listitem></varlistentry><varlistentry><term><literal>%+</literal></term><listitem><para>When printing
signed values, always display the sign (prefix with either '+' or '-').  Without <literal>%+</literal>, positive values have no sign prefix, and negative values have
a '-' prefix prepended to them.</para></listitem></varlistentry><varlistentry><term><literal>%-</literal></term><listitem><para>Left-justify
the output within the specified field width. If the width of the output is
less than the specified field width, the output will be padded with blanks
on the right-hand side. Without <literal>%-</literal>, values are right-justified
by default.</para></listitem></varlistentry><varlistentry><term><literal>%0</literal></term><listitem><para>Zero-fill
the output field if the output is right-justified and the width of the output
is less than the specified field width. Without <literal>%0</literal>, right-justified
values are prepended with blanks in order to fill the field.</para></listitem></varlistentry></variablelist></sect3><sect3 id="api-19"><title>Field Width Specifiers</title><indexterm id="indexterm-544"><primary>field width specifiers</primary></indexterm><variablelist termlength="xtranarrow"><varlistentry><term><literal>%n</literal></term><listitem><para>Field width
is set to the specified decimal value.</para></listitem></varlistentry><varlistentry><term><literal>%?</literal></term><listitem><para>Field width
is set to the maximum width of a hexadecimal pointer value. This is 8 in an
ILP32 environment, and 16 in an LP64 environment.</para></listitem></varlistentry><varlistentry><term><literal>%*</literal></term><listitem><para>Field width
is set to the value specified at the current position in the argument list.
This value is assumed to be an <literal>int</literal>. Note that in the 64-bit
compilation environment, it may be necessary to cast <literal>long</literal>
values to <literal>int</literal>.</para></listitem></varlistentry></variablelist></sect3><sect3 id="api-20"><title>Integer Specifiers</title><indexterm id="indexterm-545"><primary>integer specifiers</primary></indexterm><variablelist termlength="xtranarrow"><varlistentry><term><literal>%h</literal></term><listitem><para>Integer value
to be printed is a <literal>short</literal>.</para></listitem></varlistentry><varlistentry><term><literal>%l</literal></term><listitem><para>Integer value
to be printed is a <literal>long</literal>.</para></listitem></varlistentry><varlistentry><term><literal>%ll</literal></term><listitem><para>Integer value
to be printed is a <literal>long long</literal>.</para></listitem></varlistentry></variablelist></sect3><sect3 id="api-22"><title>Terminal Attribute Specifiers</title><indexterm id="indexterm-546"><primary>terminal attribute specifiers</primary></indexterm><para>If standard output for the debugger is a terminal, and terminal attributes
can be obtained by the terminfo database, the following terminal escape constructs
can be used:</para><variablelist termlength="xtranarrow"><varlistentry><term><literal>%&lt;n&gt;</literal></term><listitem><para>Enable
the terminal attribute corresponding to <replaceable>n</replaceable>. Only
a single attribute can be enabled with each instance of <literal>%&lt;&gt;</literal>.</para></listitem></varlistentry><varlistentry><term><literal>%&lt;/n&gt;</literal></term><listitem><para>Disable
the terminal attribute corresponding to <replaceable>n</replaceable>. Note
that in the case of reverse video, dim text, and bold text, the terminal codes
to disable these attributes might be identical. Therefore, it might not be
possible to disable these attributes independently of one another.</para></listitem></varlistentry></variablelist><para>If no terminal information is available, each terminal
attribute construct is ignored by <function>mdb_printf<gentext type="text">()</gentext></function>. For more
information on terminal attributes, see <olink targetdocent="REFMAN4" localinfo="TERMINFO-4" type="v-only"><citerefentry><refentrytitle>terminfo</refentrytitle><manvolnum><gentext type="text">(</gentext>4<gentext type="text">)</gentext></manvolnum></citerefentry></olink>. The available terminfo attributes are:</para><variablelist termlength="xtranarrow"><varlistentry><term><literal>a</literal></term><listitem><para>Alternate character
set</para></listitem></varlistentry><varlistentry><term><literal>b</literal></term><listitem><para>Bold text</para></listitem></varlistentry><varlistentry><term><literal>d</literal></term><listitem><para>Dim text</para></listitem></varlistentry><varlistentry><term><literal>r</literal></term><listitem><para>Reverse video</para></listitem></varlistentry><varlistentry><term><literal>s</literal></term><listitem><para>Best standout
capability</para></listitem></varlistentry><varlistentry><term><literal>u</literal></term><listitem><para>Underlining</para></listitem></varlistentry></variablelist></sect3><sect3 id="api-21"><title>Format Specifiers</title><indexterm id="indexterm-547"><primary>format specifiers</primary></indexterm><variablelist termlength="xtranarrow"><varlistentry><term><literal>%%</literal></term><listitem><para>The '<literal>%</literal>' symbol is printed.</para></listitem></varlistentry><varlistentry><term><literal>%a</literal></term><listitem><para>Prints an
address in symbolic form. The minimum size of the value associated with <literal>%a</literal> is a <literal>uintptr_t</literal>; specifying <literal>%la</literal>
is not necessary. If address-to-symbol conversion is on, the debugger will
attempt to convert the address to a symbol name followed by an offset in the
current output radix and print this string; otherwise, the value is printed
in the default output radix.  If <literal>%#a</literal> is used, the alternate
format adds a '<literal>:</literal>' suffix to the output.</para></listitem></varlistentry><varlistentry><term><literal>%A</literal></term><listitem><para>This format
is identical to <literal>%a</literal>, except when an address cannot be converted
to a symbol name plus an offset, nothing is printed. If <literal>%#A</literal>
is used, the alternate format prints a '<literal>?</literal>' when address
conversion fails.</para></listitem></varlistentry><varlistentry><term><literal>%b</literal></term><listitem><para>Decode and
print a bit field in symbolic form. This specifier expects two consecutive
arguments: the bit field value (<literal>int</literal> for <literal>%b</literal>, <literal>long</literal> for <literal>%lb</literal>, and so forth), and a pointer to
an array of <structname>mdb_bitmask_t</structname> structures:<indexterm id="indexterm-548"><primary><structname>mdb_bitmask_t</structname></primary></indexterm></para><para><programlisting format="linespecific">typedef struct mdb_bitmask {
		const char *bm_name;       /* String name to print */
		u_longlong_t bm_mask;      /* Mask for bits */
		u_longlong_t bm_bits;      /* Result for value &amp; mask */
} mdb_bitmask_t;</programlisting></para><para>The array should be terminated by a structure whose <literal>bm_name</literal> field is set to NULL. When <literal>%b</literal> is used, the debugger
reads the value argument, then iterates through each <structname>mdb_bitmask</structname> structure checking to see if:</para><para><literal>(value &amp; bitmask-&gt;bm_mask) == bitmask-&gt;bm_bits</literal></para><para>If this expression is true, the <literal>bm_name</literal> string is
printed. Each string printed is separated by a comma. The following example
shows how <literal>%b</literal> can be used to decode the <literal>t_flag</literal> field in a <literal>kthread_t</literal>:</para><para><programlisting format="linespecific">const mdb_bitmask_t t_flag_bits[] = {
		{ "T_INTR_THREAD", T_INTR_THREAD, T_INTR_THREAD },
		{ "T_WAKEABLE", T_WAKEABLE, T_WAKEABLE },
		{ "T_TOMASK", T_TOMASK, T_TOMASK },
		{ "T_TALLOCSTK", T_TALLOCSTK, T_TALLOCSTK },
			...
		{ NULL, 0, 0 }
};

void
thr_dump(kthread_t *t)
{
		mdb_printf("t_flag = &lt;%hb&gt;\n", t-&gt;t_flag, t_flag_bits);

		...
}</programlisting></para><para>If <literal>t_flag</literal> was set to 0x000a, the function would print:</para><para><programlisting format="linespecific">t_flag = &lt;T_WAKEABLE,T_TALLOCSTK&gt;</programlisting></para><para>If <literal>%#b</literal> is specified, the union of all bits that were
not matched by an element in the bitmask array is printed as a hexadecimal
value following the decoded names. </para></listitem></varlistentry><varlistentry><term><literal>%c</literal></term><listitem><para>Print the
specified integer as an ASCII character.</para></listitem></varlistentry><varlistentry><term><literal>%d</literal></term><listitem><para>Print the
specified integer as a signed decimal value. Same as <literal>%i</literal>.
If <literal>%#d</literal> is specified, the alternate format prefixes the
value with '<literal>0t</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%e</literal></term><listitem><para>Print the
specified double in the floating-point format <literal>[+/-]d.ddddddde[+/-]dd</literal>, where there is one digit
before the radix character, seven digits of precision, and at least two digits
following the exponent.</para></listitem></varlistentry><varlistentry><term><literal>%E</literal></term><listitem><para>Print the
specified double using the same rules as <literal>%e</literal>, except that
the exponent character will be '<literal>E</literal>' instead of '<literal>e</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%g</literal></term><listitem><para>Print the
specified double in the same floating-point format as <literal>%e</literal>,
but with sixteen digits of precision. If <literal>%llg</literal> is specified,
the argument is expected to be of type <type>long double</type> (quad-precision
floating-point value).</para></listitem></varlistentry><varlistentry><term><literal>%G</literal></term><listitem><para>Print the
specified double using the same rules as <literal>%g</literal>, except that
the exponent character will be '<literal>E</literal>' instead of '<literal>e</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%i</literal></term><listitem><para>Print the
specified integer as a signed decimal value. Same as <literal>%d</literal>.
If <literal>%#i</literal> is specified, the alternate format prefixes the
value with '<literal>0t</literal>'. </para></listitem></varlistentry><varlistentry><term><literal>%I</literal></term><listitem><para>Print the
specified 32-bit unsigned integer as an Internet IPv4 address in dotted-decimal
format (for example, the hexadecimal value <literal>0xffffffff</literal> would
print as <literal>255.255.255.255</literal>).</para></listitem></varlistentry><varlistentry><term><literal>%m</literal></term><listitem><para>Print a margin
of whitespace. If no field is specified, the default output margin width is
used; otherwise, the field width determines the number of characters of white
space that are printed.</para></listitem></varlistentry><varlistentry><term><literal>%o</literal></term><listitem><para>Print the
specified integer as an unsigned octal value. If <literal>%#o</literal> is
used, the alternate format prefixes the output with '<literal>0</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%p</literal></term><listitem><para>Print the
specified pointer (<literal>void *</literal>) as a hexadecimal value.</para></listitem></varlistentry><varlistentry><term><literal>%q</literal></term><listitem><para>Print the
specified integer as a signed octal value. If <literal>%#o</literal> is used,
the alternate format prefixes the output with '<literal>0</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%r</literal></term><listitem><para>Print the
specified integer as an unsigned value in the current output radix. The user
can change the output radix using the <command>$d</command> dcmd. If <literal>%#r</literal> is specified, the alternate format prefixes the value with the
appropriate base prefix: '<literal>0i</literal>' for binary, '<literal>0o</literal>' for octal, '<literal>0t</literal>' for decimal, or '<literal>0x</literal>' for hexadecimal.</para></listitem></varlistentry><varlistentry><term><literal>%R</literal></term><listitem><para>Print the
specified integer as a signed value in the current output radix. If <literal>%#R</literal> is specified, the alternate format prefixes the value with the
appropriate base prefix.</para></listitem></varlistentry><varlistentry><term><literal>%s</literal></term><listitem><para>Print the
specified string (<literal>char *</literal>). If the string pointer is NULL,
the string '<literal>&lt;NULL&gt;</literal>' is printed.</para></listitem></varlistentry><varlistentry><term><literal>%t</literal></term><listitem><para>Advance one
or more tab stops. If no width is specified, output advances to the next tab
stop; otherwise the field width determines how many tab stops are advanced.</para></listitem></varlistentry><varlistentry><term><literal>%T</literal></term><listitem><para>Advance the
output column to the next multiple of the field width. If no field width is
specified, no action is taken. If the current output column is not a multiple
of the field width, white space is added to advance the output column.</para></listitem></varlistentry><varlistentry><term><literal>%u</literal></term><listitem><para>Print the
specified integer as an unsigned decimal value. If <literal>%#u</literal>
is specified, the alternate format prefixes the value with '<literal>0t</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%x</literal></term><listitem><para>Print the
specified integer as a hexadecimal value. The characters a-f are used as the
digits for the values 10-15. If <literal>%#x</literal> is specified, the alternate
format prefixes the value with '<literal>0x</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%X</literal></term><listitem><para>Print the
specified integer as a hexadecimal value. The characters A-F are used as the
digits for the values 10-15. If <literal>%#X</literal> is specified, the alternate
format prefixes the value with '<literal>0X</literal>'.</para></listitem></varlistentry><varlistentry><term><literal>%Y</literal></term><listitem><para>The specified <literal>time_t</literal> is printed as the string  '<literal>year month day HH:MM:SS</literal>'.</para></listitem></varlistentry></variablelist></sect3></sect2><sect2 id="api-17"><title><function>mdb_snprintf<gentext type="text">()</gentext></function></title><programlisting format="linespecific">size_t mdb_snprintf(char *buf, size_t len, const char *format, ...);</programlisting><para><indexterm id="indexterm-549"><primary><function>mdb_snprintf<gentext type="text">()</gentext></function></primary></indexterm>Construct
a formatted string based on the specified format string and arguments, and
store the resulting string into the specified <replaceable>buf</replaceable>.
The <function>mdb_snprintf<gentext type="text">()</gentext></function> function accepts the same format specifiers
and arguments as the <function>mdb_printf<gentext type="text">()</gentext></function> function. The <replaceable>len</replaceable> parameter specifies the size of <replaceable>buf</replaceable>
in bytes.  No more than <replaceable>len</replaceable> - 1 formatted bytes
are placed in <replaceable>buf</replaceable>; <function>mdb_snprintf<gentext type="text">()</gentext></function>
 always terminates <replaceable>buf</replaceable> with a null byte. The function
returns the number of bytes required for the complete formatted string, not
including the terminating null byte. If the <replaceable>buf</replaceable>
parameter is NULL and <replaceable>len</replaceable> is set to zero, the function
will not store any characters to <replaceable>buf</replaceable> and returns
the number of bytes required for the complete formatted string; this technique
can be used to determine the appropriate size of a buffer for dynamic memory
allocation.</para></sect2><sect2 id="api-16"><title><function>mdb_warn<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void mdb_warn(const char *format, ...);</programlisting><para><indexterm id="indexterm-550"><primary><function>mdb_warn<gentext type="text">()</gentext></function></primary></indexterm>Print
an error or warning message to standard error. The <function>mdb_warn<gentext type="text">()</gentext></function>
function accepts a format string and variable argument list that can contain
any of the specifiers documented for <function>mdb_printf<gentext type="text">()</gentext></function>. However,
the output of <function>mdb_warn<gentext type="text">()</gentext></function> is sent to standard error, which
is not buffered and is not sent through the output pager or processed as part
of a dcmd pipeline.  All error messages are automatically prefixed with the
string “<literal>mdb:</literal>”.  </para><para>In addition, if the <replaceable>format</replaceable> parameter does
not contain a newline (<literal>\n</literal>) character, the format string
is implicitly suffixed with the string “<literal>: %s\n</literal>”, where <literal>%s</literal> is
replaced by the error message string corresponding to the last error recorded
by a module API function. For example, the following source code:</para><programlisting format="linespecific">if (mdb_lookup_by_name("no_such_symbol", &amp;sym) == -1)
       mdb_warn("lookup_by_name failed");</programlisting><para>produces this output:</para><programlisting format="linespecific">mdb: lookup_by_name failed: unknown symbol name</programlisting></sect2><sect2 id="api-56"><title><function>mdb_flush<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void mdb_flush(void);</programlisting><para><indexterm id="indexterm-551"><primary><function>mdb_flush<gentext type="text">()</gentext></function></primary></indexterm>Flush
all currently buffered output. Normally, <literal>mdb</literal>'s standard
output is line-buffered; output generated using <function>mdb_printf<gentext type="text">()</gentext></function>
is not flushed to the terminal (or other standard output destination) until
a newline is encountered, or at the end of the current dcmd. However, in some
situations you might want to explicitly flush standard output prior to printing
a newline; <function>mdb_flush<gentext type="text">()</gentext></function> can be used for this purpose.</para></sect2><sect2 id="api-60"><title><function>mdb_nhconvert<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void mdb_nhconvert(void *dst, const void *src, size_t nbytes);</programlisting><para><indexterm id="indexterm-552"><primary><function>mdb_nhconvert<gentext type="text">()</gentext></function></primary></indexterm>Convert
a sequence of <literal>nbytes</literal> bytes stored at the address specified
by <literal>src</literal> from network byte order to host byte order and store
the result at the address specified by <literal>dst</literal>.  The <literal>src</literal> and <literal>dst</literal> parameters may be the same, in which
case the object is converted in place.  This function may be used to convert
from host order to network order or from network order to host order, since
the conversion is the same in either case.</para></sect2><sect2 id="api-61"><title><function>mdb_dumpptr<gentext type="text">()</gentext></function> and <function>mdb_dump64<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_dumpptr(uintptr_t addr, size_t nbytes, uint_t flags,
                     mdb_dumpptr_cb_t func, void *data);
int mdb_dump64(uint64_t addr, uint64_t nbytes, uint_t flags,
                     mdb_dump64_cb_t func, void *data);</programlisting><para><indexterm id="indexterm-553"><primary><function>mdb_dumpptr<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-554"><primary><function>mdb_dump64<gentext type="text">()</gentext></function></primary></indexterm>These functions
can be used to generate formatted hexadecimal and ASCII       data dumps that
are printed to standard output.  Each function accepts an <literal>addr</literal>
parameter specifying the starting location, a <literal>nbytes</literal> parameter
specifying the number of bytes to display, a set of flags described below,
a func callback function to use to read the data to display, and a data parameter
that is passed to each invocation of the callback func as its last argument.
 The functions are identical in every regard except that <literal>mdb_dumpptr</literal> uses <literal>uintptr_t</literal> for its address parameters and <literal>mdb_dump64</literal> uses <literal>uint64_t</literal>.  This distinction is
useful when combining <literal>mdb_dump64</literal> with <literal>mdb_pread</literal>, for example.  The built-in <command>::dump</command> dcmd uses
these functions to perform its data display.</para><para>The flags parameter should be the bitwise OR of one or more of the following
values:</para><variablelist><varlistentry><term><literal>MDB_DUMP_RELATIVE</literal></term><listitem><para>Number lines relative to the start address instead of with the explicit
address of each line.<indexterm id="indexterm-555"><primary><literal>MDB_DUMP_RELATIVE</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_ALIGN</literal></term><listitem><para>Align the output at a paragraph boundary.<indexterm id="indexterm-556"><primary><literal>MDB_DUMP_ALIGN</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_PEDANT</literal></term><listitem><para>Display full-width addresses instead of truncating the address to fit the
output in 80 columns.<indexterm id="indexterm-557"><primary><literal>MDB_DUMP_PEDANT</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_ASCII</literal></term><listitem><para>Display ASCII values next to the hexadecimal data.<indexterm id="indexterm-558"><primary><literal>MDB_DUMP_ASCII</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_HEADER</literal></term><listitem><para>Display a header line about the data.<indexterm id="indexterm-559"><primary><literal>MDB_DUMP_HEADER</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_TRIM</literal></term><listitem><para>Only read from and display the contents of the specified addresses, instead
of reading and printing entire lines.<indexterm id="indexterm-560"><primary><literal>MDB_DUMP_TRIM</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_SQUISH</literal></term><listitem><para>Elide repeated lines by placing a “*” on a line that is a repeat
of the previous line.<indexterm id="indexterm-561"><primary><literal>MDB_DUMP_SQUISH</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_NEWDOT</literal></term><listitem><para>Update the value of dot to the address beyond the last address read by the
function.<indexterm id="indexterm-562"><primary><literal>MDB_DUMP_NEWDOT</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_ENDIAN</literal></term><listitem><para>Adjust for endian-ness.  This option assumes that the word size is equal to
the current group size, specified by <function>MDB_DUMP_GROUP<gentext type="text">()</gentext></function>.
 This option will always turn off alignment, headers, and ASCII display to
avoid confusing output.  If <literal>MDB_DUMP_TRIM</literal> is set with <literal>MDB_DUMP_ENDIAN</literal>, the number of bytes dumped will be rounded down
to the nearest word size bytes.<indexterm id="indexterm-563"><primary><literal>MDB_DUMP_ENDIAN</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_WIDTH(<replaceable>width</replaceable>)</literal></term><listitem><para>Increase the number of 16-byte paragraphs
per line that are displayed.  The default value of <replaceable>width</replaceable>
is one, and the maximum value is 16.<indexterm id="indexterm-564"><primary><literal>MDB_DUMP_WIDTH</literal></primary></indexterm></para></listitem></varlistentry><varlistentry><term><literal>MDB_DUMP_GROUP(<replaceable>group</replaceable>)</literal></term><listitem><para>Set the byte group size to <replaceable>group</replaceable>.  The default <replaceable>group</replaceable> size is
four bytes.  The <replaceable>group</replaceable> size must be a power of
two that divides the line width.<indexterm id="indexterm-565"><primary><literal>MDB_DUMP_GROUP</literal></primary></indexterm></para></listitem></varlistentry></variablelist></sect2><sect2 id="api-15"><title><function>mdb_one_bit<gentext type="text">()</gentext></function></title><programlisting format="linespecific">const char *mdb_one_bit(int width, int bit, int on);</programlisting><para><indexterm id="indexterm-566"><primary><function>mdb_one_bit<gentext type="text">()</gentext></function></primary></indexterm>The <function>mdb_one_bit<gentext type="text">()</gentext></function> function can be used to print a graphical representation
of a bit field in which a single bit of interest is turned on or off. This
function is useful for creating verbose displays of bit fields similar to
the output from <literal>snoop(1M) -v</literal>.  For example, the following
source code:</para><programlisting format="linespecific">#define FLAG_BUSY       0x1

uint_t flags;

/* ... */

mdb_printf("%s = BUSY\n", mdb_one_bit(8, 0, flags &amp; FLAG_BUSY));</programlisting><para>produces this output:</para><programlisting format="linespecific">.... ...1 = BUSY</programlisting><para>Each bit in the bit field is printed as a period (<literal>.</literal>),
with each 4-bit sequence separated by a white space. The bit of interest is
printed as 1 or 0, depending on the setting of the <replaceable>on</replaceable>
parameter. The total <replaceable>width</replaceable> of the bit field in
bits is specified by the width parameter, and the bit position of the bit
of interest is specified by the <replaceable>bit</replaceable> parameter.
Bits are numbered starting from zero. The function returns a pointer to an
appropriately sized, null-terminated string containing the formatted bit representation.
 The string is automatically garbage-collected upon completion of the current
dcmd.</para></sect2><sect2 id="api-14"><title><function>mdb_inval_bits<gentext type="text">()</gentext></function></title><programlisting format="linespecific">const char *mdb_inval_bits(int width, int start, int stop);</programlisting><para><indexterm id="indexterm-567"><primary><function>mdb_inval_bits<gentext type="text">()</gentext></function></primary></indexterm>The <function>mdb_inval_bits<gentext type="text">()</gentext></function> function is used, along with <function>mdb_one_bit<gentext type="text">()</gentext></function>, to print a graphical representation of a bit field. This function
marks a sequence of bits as invalid or reserved by displaying an '<literal>x</literal>' at the appropriate bit location. Each bit in the bit field is
represented as a period (<literal>.</literal>), except for those bits in the
range of bit positions specified by the start and stop parameters. Bits are
numbered starting from zero. For example, the following source code:</para><programlisting format="linespecific">mdb_printf("%s = reserved\n", mdb_inval_bits(8, 7, 7));</programlisting><para>produces this output:</para><programlisting format="linespecific">x... .... = reserved</programlisting><para>The function returns a pointer to an appropriately sized, null-terminated
string containing the formatted bit representation. The string is automatically
garbage-collected upon completion of the current dcmd.</para></sect2><sect2 id="api-13"><title><function>mdb_inc_indent<gentext type="text">()</gentext></function> and <function>mdb_dec_indent<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ulong_t mdb_inc_indent(ulong_t n);
ulong_t mdb_dec_indent(ulong_t n);</programlisting><para><indexterm id="indexterm-568"><primary><function>mdb_inc_indent<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-569"><primary><function>mdb_dec_indent<gentext type="text">()</gentext></function></primary></indexterm>These functions
increment and decrement the numbers of columns that MDB will auto-indent with
white space before printing a line of output. The size of the delta is specified
by <replaceable>n</replaceable>, a number of columns. Each function returns
the previous absolute value of the indent. Attempts to decrement the indent
below zero have no effect. Following a call to either function, subsequent
calls to <function>mdb_printf<gentext type="text">()</gentext></function> are indented appropriately. If the
dcmd completes or is forcibly terminated by the user, the indent is restored
automatically to its default setting by the debugger.</para></sect2><sect2 id="api-12"><title><function>mdb_eval<gentext type="text">()</gentext></function></title><programlisting format="linespecific">int mdb_eval(const char *s);</programlisting><para><indexterm id="indexterm-570"><primary><function>mdb_eval<gentext type="text">()</gentext></function></primary></indexterm>Evaluate
and execute the specified command string <replaceable>s</replaceable>, as
if it had been read from standard input by the debugger. This function returns
0 for success, or -1 for error.  <function>mdb_eval<gentext type="text">()</gentext></function> fails if the
command string contains a syntax error, or if the command string executed
by <function>mdb_eval<gentext type="text">()</gentext></function> is forcibly aborted by the user using the
pager or by issuing an interrupt.</para></sect2><sect2 id="api-49"><title><function>mdb_set_dot<gentext type="text">()</gentext></function> and <function>mdb_get_dot<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void mdb_set_dot(uintmax_t dot);
uintmax_t mdb_get_dot(void);</programlisting><para><indexterm id="indexterm-571"><primary><function>mdb_set_dot<gentext type="text">()</gentext></function></primary></indexterm><indexterm id="indexterm-572"><primary><function>mdb_get_dot<gentext type="text">()</gentext></function></primary></indexterm>Set or get
the current value of dot (the “<literal>.</literal>” variable).
 Module developers might want to reposition dot so that, for example, it refers
to the address following the last address read by the dcmd.</para></sect2><sect2 id="api-50"><title><function>mdb_get_pipe<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void mdb_get_pipe(mdb_pipe_t *p);</programlisting><para><indexterm id="indexterm-573"><primary><function>mdb_get_pipe<gentext type="text">()</gentext></function></primary></indexterm>Retrieve
the contents of the pipeline input buffer for the current dcmd. The <function>mdb_get_pipe<gentext type="text">()</gentext></function> function is intended to be used by dcmds that want
to consume the complete set of pipe input and execute only once, instead of
being invoked repeatedly by the debugger for each pipe input element. Once <function>mdb_get_pipe<gentext type="text">()</gentext></function> is invoked, the dcmd will not be invoked again by
the debugger as part of the current command. This can be used, for example,
to construct a dcmd that sorts a set of input values. </para><para>The pipe contents are placed in an array that is garbage-collected upon
termination of the dcmd, and the array pointer is stored in <literal>p-&gt;pipe_data</literal>.  The length of the array is placed in <literal>p-&gt;pipe_len</literal>.
 If the dcmd was not executed on the right-hand side of a pipeline (that is,
the <literal>DCMD_PIPE</literal> flag was not set in its <literal>flags</literal>
parameter), <literal>p-&gt;pipe_data</literal> is set to NULL and <literal>p-&gt;pipe_len</literal> is set to zero.</para></sect2><sect2 id="api-51"><title><function>mdb_set_pipe<gentext type="text">()</gentext></function></title><programlisting format="linespecific">void mdb_set_pipe(const mdb_pipe_t *p);</programlisting><para>Set the pipeline output buffer to the contents described by the pipe
structure <replaceable>p</replaceable>. The pipe values are placed in the
array <literal>p-&gt;pipe_data</literal>, and the length of the array is stored
in <literal>p-&gt;pipe_len</literal>.  The debugger makes its own copy of this
information, so the caller must remember to free <literal>p-&gt;pipe_data</literal>
if necessary. If the pipeline output buffer was previously non-empty, its
contents are replaced by the new array. If the dcmd was not executed on the
left side of a pipeline (that is, the <literal>DCMD_PIPE_OUT</literal> flag
was not set in its flags parameter), this function has no effect.</para></sect2><sect2 id="api-52"><title><function>mdb_get_xdata<gentext type="text">()</gentext></function></title><programlisting format="linespecific">ssize_t mdb_get_xdata(const char *name, void *buf, size_t nbytes);</programlisting><para><indexterm id="indexterm-574"><primary><function>mdb_get_xdata<gentext type="text">()</gentext></function></primary></indexterm>Read
the contents of the target external data buffer specified by name into the
buffer specified by <replaceable>buf</replaceable>. The size of <replaceable>buf</replaceable> is specified by the <replaceable>nbytes</replaceable> parameter;
no more than <replaceable>nbytes</replaceable> will be copied to the caller's
buffer. The total number of bytes read will be returned upon success; -1 will
be returned upon error. If the caller wants to determine the size of a particular
named buffer, <replaceable>buf</replaceable> should be specified as NULL and <replaceable>nbytes</replaceable> should be specified as zero. In this case, <function>mdb_get_xdata<gentext type="text">()</gentext></function> will return the total size of the buffer in bytes
but no data will be read. External data buffers provide module writers access
to target data that is not otherwise accessible through the module API. The
set of named buffers exported by the current target can be viewed using the <command>::xdata</command> built-in dcmd.<indexterm id="indexterm-575"><primary>dcmds</primary><secondary><command>::xdata</command></secondary></indexterm></para></sect2><sect2 id="api-57"><title>Additional Functions</title><para>Additionally, module writers can use the following <olink targetdocent="REFMAN3A" localinfo="STRING-3C" type="v-only"><citerefentry><refentrytitle>string</refentrytitle><manvolnum><gentext type="text">(</gentext>3C<gentext type="text">)</gentext></manvolnum></citerefentry></olink> and <olink targetdocent="REFMAN3A" localinfo="BSTRING-3C" type="v-only"><citerefentry><refentrytitle>bstring</refentrytitle><manvolnum><gentext type="text">(</gentext>3C<gentext type="text">)</gentext></manvolnum></citerefentry></olink> functions.
 They are guaranteed to have the same semantics as the functions described
in the corresponding Solaris man page.</para><programlisting format="linespecific">strcat()           strcpy()                strncpy()
strchr()           strrchr()               strcmp()
strncmp()          strcasecmp()            strncasecmp()
strlen()           bcmp()                  bcopy()
bzero()            bsearch()               qsort()</programlisting><indexterm id="indexterm-576"><primary>string functions</primary></indexterm></sect2></sect1></chapter><appendix id="options-1"><gentext type="text">Appendix A</gentext><gentext type="toc">A.&#160;&#160;
				 Options</gentext><title>Options</title><highlights><para>This appendix provides a reference for MDB command-line
options.</para></highlights><sect1 id="options-2"><title>Summary of Command-line Options</title><screen format="linespecific">mdb [ -fkmuwyAFMS ]  [ +o option ]  [ -p pid ]  [ -s distance]   
     [ -I path ]  [ -L path ]  [ -P prompt ]  [ -R root ]  
     [ -V dis-version ]  [ object  [ core ]  | core  | suffix ]</screen><para>The following options are supported:</para><variablelist termlength="narrow"><varlistentry><term><option><gentext type="text">-</gentext>A</option></term><listitem><para>Disables automatic
loading of <command>mdb</command> modules. By default, <command>mdb</command>
attempts to load debugger modules corresponding to the active shared libraries
in a user process or core file, or to the loaded kernel modules in the live
operating system or an operating system crash dump.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>F</option></term><listitem><para>Forcibly takes
over the specified user process, if necessary. By default, <command>mdb</command>
refuses to attach to a user process that is already under the control of another
debugging tool, such as <olink targetdocent="REFMAN1" localinfo="TRUSS-1"><citerefentry><refentrytitle>truss</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink>.
With the <option><gentext type="text">-</gentext>F</option> option, <command>mdb</command> attaches to these
processes anyway. This can produce unexpected interactions between <command>mdb</command> and the other tools attempting to control the process.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>f</option></term><listitem><para>Force raw file
debugging mode. By default, <command>mdb</command> attempts to infer whether
the object and core file operands refer to a user executable and core dump
or to a pair of operating system crash dump files. If the file type cannot
be inferred, the debugger will default to examining the files as plain binary
data. The <option><gentext type="text">-</gentext>f</option>option forces <command>mdb</command> to interpret
the arguments as a set of raw files to examine</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>I</option></term><listitem><para>Sets default
path for locating macro files. Macro files are read using the <command>$&lt;</command> or <command>$&lt;&lt;</command> dcmds. The path is a sequence of
directory names delimited by colon ( <literal>:</literal>) characters. The <option><gentext type="text">-</gentext>I</option> <literal>include</literal> path and <option><gentext type="text">-</gentext>L</option> <literal>library</literal> path (see below) can also contain any of the following tokens:<variablelist termlength="xtranarrow"><varlistentry><term>%i</term><listitem><para>Expands to the current instruction
set architecture (<acronym>ISA</acronym>) name ('sparc', 'sparcv9', or 'i386').</para></listitem></varlistentry><varlistentry><term>%o</term><listitem><para>Expands to the old value of the
path being modified. This is useful for appending or prepending directories
to an existing path.</para></listitem></varlistentry><varlistentry><term>%p</term><listitem><para>Expands to the current platform
string (either <command>uname</command> <option><gentext type="text">-</gentext>i</option> or the platform
string stored in the process core file or crash dump).</para></listitem></varlistentry><varlistentry><term>%r</term><listitem><para>Expands to the path name of the
root directory. An alternate root directory can be specified using the <option><gentext type="text">-</gentext>R</option> option. If no <option><gentext type="text">-</gentext>R</option> option is present, the root directory
is derived dynamically from the path to the <command>mdb</command> executable
itself. For example, if <command>/bin/mdb</command> is executed, the root
directory is <filename>/</filename>.  If <command>/net/hostname/bin/mdb</command>
were executed, the root directory would be derived as <filename>/net/hostname</filename>.</para></listitem></varlistentry><varlistentry><term>%t</term><listitem><para>Expands to the name of the current
target. This is either the literal string '<literal>proc</literal>' (a user
process or user process core file), or '<literal>kvm</literal>' (a kernel
crash dump or the live operating system).</para></listitem></varlistentry></variablelist></para><para>The default include path for 32-bit <command>mdb</command> is:<informalexample><para><literal>%r/usr/platform/%p/lib/adb:%r/usr/lib/adb</literal></para></informalexample></para><para>The default include path for 64-bit <command>mdb</command> is:<informalexample><para><literal>%r/usr/platform/%p/lib/adb/%i:%r/usr/lib/adb/%i</literal></para></informalexample></para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>k</option></term><listitem><para>Forces kernel
debugging mode. By default, <command>mdb</command> attempts to infer whether
the object and core file operands refer to a user executable and core dump,
or to a pair of operating system crash dump files. The <option><gentext type="text">-</gentext>k</option>
option forces <command>mdb</command> to assume these files are operating system
crash dump files. If no object or core operand is specified, but the <option><gentext type="text">-</gentext>k</option> option is specified, <command>mdb</command> defaults to an object
file of <filename>/dev/ksyms</filename> and a core file of <filename>/dev/kmem</filename>. Access to <filename>/dev/kmem</filename> is restricted to group
sys.<indexterm id="indexterm-577"><primary><filename>/dev/ksyms</filename></primary></indexterm><indexterm id="indexterm-578"><primary><filename>/dev/kmem</filename></primary></indexterm></para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>L</option></term><listitem><para>Sets default
path for locating debugger modules. Modules are loaded automatically on startup
or by using the <command>::load</command> dcmd. The path is a sequence of
directory names delimited by colon (<literal>:</literal>) characters. The <option><gentext type="text">-</gentext>L</option> library path can also contain any of the tokens shown for <option><gentext type="text">-</gentext>I</option> above.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>m</option></term><listitem><para>Disables demand-loading
of kernel module symbols. By default, <command>mdb</command> processes the
list of loaded kernel modules and performs demand loading of per-module symbol
tables. If the <option><gentext type="text">-</gentext>m</option> option is specified, <command>mdb</command>
does not attempt to process the kernel module list or provide per-module symbol
tables. As a result, <command>mdb</command> modules corresponding to active
kernel modules are not loaded on startup.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>M</option></term><listitem><para>Preloads all
kernel module symbols. By default, <command>mdb</command> performs demand-loading
for kernel module symbols: the complete symbol table for a module is read
when an address is that module's text or data section is referenced. With
the <option><gentext type="text">-</gentext>M</option> option, <command>mdb</command> loads the complete symbol
table of all kernel modules during startup.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>o</option> <replaceable>option</replaceable></term><listitem><para>Enables the specified debugger option. If the <option role="plus"><gentext type="text">+</gentext>o</option> form of the option is used, the specified option is disabled. Unless
noted below, each option is off by default. <command>mdb</command> recognizes
the following option arguments:<variablelist termlength="wholeline"><varlistentry><term>adb</term><listitem><para>Enable stricter <olink targetdocent="REFMAN1" localinfo="ADB-1"><citerefentry><refentrytitle>adb</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink> compatibility. The prompt is set to the
empty string and many <command>mdb</command> features, such as the output
pager, are disabled.</para></listitem></varlistentry><varlistentry><term>array_mem_limit=<replaceable>limit</replaceable></term><listitem><para>Set the default limit on the number of array members that <command>::print</command> will display. If <replaceable>limit</replaceable> is the
special token none, all array members will be displayed by default. </para></listitem></varlistentry><varlistentry><term>array_str_limit=<replaceable>limit</replaceable></term><listitem><para>Set the default limit on the number of characters that <command>::print</command> will attempt to display as an ASCII string when printing
a <literal>char</literal> array. If <replaceable>limit</replaceable> is the
special token none, the entire <literal>char</literal> array will be displayed
as a <literal>string</literal> by default.</para></listitem></varlistentry><varlistentry><term>follow_exec_mode=mode</term><listitem><para>Set the debugger
behavior for following an exec(2) system call. The mode should be one of the
following named constants:</para><informaltable frame="topbot"><tgroup cols="2" colsep="1" rowsep="1"><colspec colwidth="13.38*"/><colspec colwidth="86.62*"/><tbody><row><entry><para>ask</para></entry><entry><para>If <literal>stdout</literal>
is a terminal device, the debugger will stop after the exec(2) system call
has returned and then prompt the user to decide whether to follow the exec
or stop. If <literal>stdout</literal> is not a terminal device, the ask mode
will default to stop.</para></entry></row><row><entry><para>follow</para></entry><entry><para>The debugger will follow
the exec by automatically continuing the target process and resetting all
of its mappings and symbol tables based on the new executable. The follow
behavior is discussed in more detail under <link linkend="exec-ctrl-12">Interaction With <command>exec</command></link>.</para></entry></row><row><entry><para>stop</para></entry><entry><para>The debugger will stop following
return from the exec system call.  The stop behavior is discussed in more
detail under <link linkend="exec-ctrl-12">Interaction With <command>exec</command></link>.</para></entry></row></tbody></tgroup></informaltable></listitem></varlistentry><varlistentry><term>follow_fork_mode=mode</term><listitem><para>Set the debugger
behavior for following a fork(2), fork1(2), or vfork(2) system call.  The
mode should be one of the following named constants:</para><informaltable frame="topbot"><tgroup cols="2" colsep="1" rowsep="1"><colspec colwidth="13.38*"/><colspec colwidth="86.62*"/><tbody><row><entry><para>ask</para></entry><entry><para>If <literal>stdout</literal>
is a terminal device, the debugger will stop after the fork system call has
returned and then prompt the user to decide whether to follow the parent or
child.  If stdout is not a terminal device, the ask mode will default to parent.</para></entry></row><row><entry><para>parent</para></entry><entry><para>The debugger will follow
the parent process, and will detach from the child process and set it running.</para></entry></row><row><entry><para>child</para></entry><entry><para>The debugger will follow
the child process, and will detach from the parent process and set it running.</para></entry></row></tbody></tgroup></informaltable></listitem></varlistentry><varlistentry><term>ignoreeof</term><listitem><para>The debugger does not
exit when an <systemitem class="macro">EOF</systemitem> sequence (<literal>^D</literal>) is entered at the terminal. The <command>::quit</command> dcmd
must be used to quit.</para></listitem></varlistentry><varlistentry><term>nostop</term><listitem><para>Do not stop a user process
when attaching to it when the <literal>-p</literal> option is specified or
when the <command>::attach</command> or <command>:A</command> dcmds are applied.
 The nostop behavior is described in more detail under <link linkend="exec-ctrl-14">Process Attach and Release</link>.</para></listitem></varlistentry><varlistentry><term>pager</term><listitem><para>The output pager is enabled
(default).</para></listitem></varlistentry><varlistentry><term>repeatlast</term><listitem><para>If a <symbol>NEWLINE</symbol> is entered as the complete command at the terminal, <command>mdb</command> repeats the previous command with the current value of dot. This
option is implied by <option><gentext type="text">-</gentext>o</option> <command>adb</command>.</para></listitem></varlistentry><varlistentry><term>showlmid</term><listitem><para>MDB provides support for
symbol naming and identification in user applications that make use of link
maps other than LM_ID_BASE and LM_ID_LDSO, as described in <link linkend="syntax-16">Symbol Name Resolution</link>.
Symbols on link maps other than LM_ID_BASE or LM_ID_LDSO will be shown as <literal>LMlmid`library`symbol</literal>, where <literal>lmid</literal> is the link-map
ID in the default output radix (16). The user may optionally configure MDB
to show the link-map ID scope of all symbols and objects, including those
associated with LM_ID_BASE and LM_ID_LDSO, by enabling the <literal>showlmid</literal> option. Built-in dcmds that deal with object file names will display
link-map IDs according to the value of showlmid above, including <command>::nm</command>, <command>::mappings</command>, <command>$m</command>, and <command>::objects</command>.</para></listitem></varlistentry></variablelist></para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>p</option> <replaceable>pid</replaceable></term><listitem><para>Attaches to and stops the specified process id. <command>mdb</command> uses the <filename>/proc/<replaceable>pid</replaceable>/object/a.out</filename> file as the executable file path name.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>P</option></term><listitem><para>Sets the command
prompt. The default prompt is '<literal>&gt;</literal> '.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>R</option></term><listitem><para>Sets root directory
for path name expansion. By default, the root directory is derived from the
path name of the <command>mdb</command> executable itself. The root directory
is substituted in place of the <literal>%r</literal> token during path name
expansion.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>s</option> <replaceable>distance</replaceable></term><listitem><para>Sets the symbol matching distance for address-to-symbol-name
conversions to the specified <replaceable>distance</replaceable>. By default, <command>mdb</command> sets the distance to zero, which enables a smart-matching mode.
Each <acronym>ELF</acronym> symbol table entry includes a value V and size
S, representing the size of the function or data object in bytes. In smart
mode, <command>mdb</command> matches an address A with the given symbol if
A is in the range [ V, V + S ). If any non-zero distance is specified, the
same algorithm is used, but S in the given expression is always the specified
absolute distance and the symbol size is ignored.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>S</option></term><listitem><para>Suppresses processing
of the user's <filename>~/.mdbrc</filename> file. By default, <command>mdb</command> reads and processes the macro file <literal>.mdbrc</literal> if
one is present in the user's home directory, as defined by $<envar>HOME</envar>.
If the <option><gentext type="text">-</gentext>S</option> option is present, this file is not read.<indexterm id="indexterm-579"><primary><filename>.mdbrc</filename></primary></indexterm></para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>u</option></term><listitem><para>Forces user debugging
mode. By default, <command>mdb</command> attempts to infer whether the object
and core file operands refer to a user executable and core dump, or to a pair
of operating system crash dump files. The <option><gentext type="text">-</gentext>u</option> option forces <command>mdb</command> to assume these files are not operating system crash dump files.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>V</option></term><listitem><para>Sets disassembler
version. By default, <command>mdb</command> attempts to infer the appropriate
disassembler version for the debug target. The disassembler can be set explicitly
using the <option><gentext type="text">-</gentext>V</option> option. The <command>::disasms</command> dcmd
lists the available disassembler versions.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>w</option></term><listitem><para>Opens the specified
object and core files for writing.</para></listitem></varlistentry><varlistentry><term><option><gentext type="text">-</gentext>y</option></term><listitem><para>Sends explicit
terminal initialization sequences for tty mode. Some terminals require explicit
initialization sequences to switch into a tty mode. Without this initialization
sequence, terminal features such as standout mode might not be available to <command>mdb</command>.</para></listitem></varlistentry></variablelist></sect1><sect1 id="options-3"><title>Operands</title><para>The following operands are supported: </para><variablelist><varlistentry><term>object</term><listitem><para>Specifies an ELF format object
file to  examine.  <command>mdb</command> provides  the  ability to examine
and edit ELF format executables  (<filename>ET_EXEC</filename>),  ELF dynamic
library files (<filename>ET_DYN</filename>),  ELF  relocatable object files
(<filename>ET_REL</filename>), and operating system <filename>unix.X</filename>
symbol table files.</para></listitem></varlistentry><varlistentry><term>core</term><listitem><para>Specifies an ELF process core
file  (<filename>ET_CORE</filename>),  or an operating system crash dump <filename>vmcore.X</filename> file. If an ELF core file operand is provided without
a corresponding object file, <command>mdb</command> will attempt to infer
the name of the executable file that produced the core using several different
algorithms.  If no executable is found, <command>mdb</command> will still
execute, but some symbol information may be unavailable.</para></listitem></varlistentry><varlistentry><term>suffix</term><listitem><para>Specifies the numerical suffix
representing a pair of operating system crash dump files. For example, if
the suffix is '<literal>3</literal>', <command>mdb</command> infers that it
should  examine  the files  '<filename>unix.3</filename>'  and  '<filename>vmcore.3</filename>'. The string of digits will not be interpreted as a suffix
if an actual file of the same name is present in the current directory.</para></listitem></varlistentry></variablelist></sect1><sect1 id="options-4"><title>Exit Status</title><para>The following exit values are returned:</para><variablelist><varlistentry><term>0</term><listitem><para>Debugger completed execution successfully.</para></listitem></varlistentry><varlistentry><term>1</term><listitem><para>A fatal error occurred.</para></listitem></varlistentry><varlistentry><term>2</term><listitem><para>Invalid command line options were
specified.</para></listitem></varlistentry></variablelist></sect1><sect1 id="options-5"><title>Environment Variables</title><para>The following environment variables are supported:</para><variablelist><varlistentry><term>HISTSIZE</term><listitem><para>This variable is used to
determine the maximum  length of the command history list. If this variable
is not present, the default length is 128.</para></listitem></varlistentry><varlistentry><term>HOME</term><listitem><para>This variable is used to determine
the pathname of the user's home directory, where a <filename>.mdbrc</filename>
file may reside. If this variable is not present, no <filename>.mdbrc</filename>
processing will occur.</para></listitem></varlistentry><varlistentry><term>SHELL</term><listitem><para>This variable is used to determine
the pathname of the shell used to process shell escapes requested using  
         the <literal>!</literal> meta-character. If this variable is not
present, <command>/bin/sh</command> is used.</para></listitem></varlistentry></variablelist></sect1></appendix><appendix id="notes-1"><gentext type="text">Appendix B</gentext><gentext type="toc">B.&#160;&#160;
				 Notes</gentext><title>Notes</title><sect1 id="notes-2"><title>Warnings</title><para>The following warning information applies to the use of MDB.</para><sect2 id="notes-4"><title>Use of the Error Recovery Mechanism</title><para>The debugger and its dmods execute in the same address space, and  thus
it is quite possible that a buggy dmod can cause MDB to dump core or otherwise
misbehave. The MDB <command>resume</command> capability,  described in <link linkend="interaction-2">Signal Handling</link>, provides a limited recovery mechanism for these
situations. However, it is not possible for MDB to know definitively whether
the dmod in question has corrupted only its own state, or the debugger's global
state. Therefore a <command>resume</command> operation cannot be guaranteed
to be safe, or to prevent a subsequent crash of the debugger. The safest course
of action following a <command>resume</command> is to save any important debug
information, and then quit and restart the debugger.</para></sect2><sect2 id="notes-5"><title>Use of the Debugger to Modify the Live Operating System</title><para>The use of the debugger to modify (that is,  write  to)  the address
space of live running operating system is extremely dangerous, and may result
in a system panic in the event the user damages a kernel data structure.</para></sect2></sect1><sect1 id="notes-3"><title>Notes</title><sect2 id="notes-6"><title>Limitations on Examining Process Core Files</title><para>MDB does not provide support for examining process core files that were
generated by a release of the Solaris operating environment preceding Solaris
2.6. If a core file from one operating system release is examined on a different
operating system release, the run-time link-editor debugging interface  (<filename>librtld_db)</filename>  may not be able to initialize. In this case, symbol
information for shared libraries will not be available.  Furthermore, since
shared mappings  are not present in user core files,  the text section and
read-only data of shared libraries  may not match the data that was present
in the process at the time it dumped core. Core files from Solaris Intel systems
may not be examined on Solaris SPARC systems, and vice-versa.</para></sect2><sect2 id="notes-7"><title>Limitations on Examining Crash Dump Files</title><para>Crash dumps from Solaris 7 and earlier releases may only be examined
with the aid of the <filename>libkvm</filename> from the corresponding operating
system release.  If a crash dump from one operating  system release is examined
using the dmods from a different operating system release, changes in the
kernel implementation may prevent some dcmds or walkers from working properly.
MDB will issue a warning message if it detects this condition. Crash dumps
from Solaris Intel systems may not be examined on Solaris SPARC systems, and
vice-versa.</para></sect2><sect2 id="notes-8"><title>Relationship Between 32-bit and 64-bit Debugger</title><para>MDB provides support for debugging both 32-bit and 64-bit programs.
Once it has examined the target and determined its data model, MDB will automatically
re-execute the mdb binary that has the same data model as the target, if necessary.
This  approach simplifies the task of writing debugger modules, because the
modules that are loaded will use the same data model as the primary target.
Only the 64-bit debugger  may be used to debug 64-bit target programs. The
64-bit debugger can only be used on a system that is running the 64-bit operating
environment.</para></sect2><sect2 id="notes-9"><title>Developer Information</title><para>The <literal>mdb</literal>(1) man page provides a detailed description
of built-in <command>mdb</command> features for easy developer reference.
The header file &lt;<filename>sys/mdb_modapi.h</filename>&gt; contains prototypes
for the functions in the MDB Module API, and the <literal>SUNWmdbdm</literal>
package provides source code for an example module in the directory <filename>/usr/demo/mdb</filename>. </para></sect2></sect1></appendix><appendix id="adb-trans-1"><gentext type="text">Appendix C</gentext><gentext type="toc">C.&#160;&#160;
				 Transition From adb</gentext><title>Transition From <command>adb</command></title><para>The transition from using the legacy <literal>adb</literal>(1) utility
to using <literal>mdb</literal>(1) is relatively simple: MDB provides evolutionary
compatibility for the <literal>adb</literal> syntax, built-in commands, and
command-line options. MDB attempts to provide compatibility for all existing <literal>adb</literal>(1) features, but it is not bug-for-bug compatible with <literal>adb</literal>(1). This appendix briefly discusses     several features of <literal>adb</literal>(1) that are not precisely emulated by <literal>mdb</literal>(1)
in order to guide users to the new functionality</para><sect1 id="adb-trans-6"><title>Command-line Options</title><para>MDB provides a superset of the command-line options recognized by <literal>adb</literal>(1). All the <literal>adb</literal>(1) options are supported
and have the same meaning as before. The <filename>/usr/bin/adb</filename>
pathname is delivered as a link that invokes <literal>mdb</literal>(1), and
automatically enables enhanced <literal>adb</literal>(1) compatibility mode.
Executing the <filename>/usr/bin/adb</filename> link is equivalent to executing
mdb with the <option><gentext type="text">-</gentext>o</option> <literal>adb</literal> option, or executing <literal>::set -o adb</literal> once the debugger has started. </para></sect1><sect1 id="adb-trans-7"><title>Syntax</title><para>The MDB language adheres to the same syntax as the <literal>adb</literal>(1)
language, in order to provide compatibility for legacy macros and script files.
New MDB dcmds use the extended form <literal>::name</literal>, in order to
distinguish them from legacy commands that are prefixed with either <literal>:</literal> or <literal>$</literal>. Expressions can also be evaluated on
the right-hand side of a dcmd name by enclosing them in square brackets preceded
by a dollar sign (<literal>$[ ]</literal>). Similar to <literal>adb</literal>(1),
an input line that begins with an exclamation mark (<literal>!) </literal>indicates
that the command line should be executed by the user's shell. In MDB, a debugger
command may also be suffixed with an exclamation mark to indicate that its
output should be piped to the shell command following the exclamation mark. </para><para>In <literal>adb</literal>(1), binary operators are left associative
and have lower precedence than unary operators. Binary operators are evaluated
in strict left-to-right     order on the input line. In MDB, binary operators
are left associative and have lower precedence than unary operators, but the
binary operators operate in order of precedence according to the table in <link linkend="syntax-19">Binary Operators</link>. The operators conform to the order of precedence in
ANSI C. Legacy <literal>adb</literal>(1) macro files that do not explicitly
parenthesize ambiguous expressions may need to be updated to work with MDB.
For example, in <literal>adb</literal> the following command evaluates to
the integer value nine: </para><screen format="linespecific">$ echo "4-1*3=X" | adb
        9</screen><para> In MDB, as in ANSI C, operator "<literal>*</literal>" has higher precedence
than "<literal>-</literal>" and therefore the result is the integer value
one: </para><screen format="linespecific">$ echo "4-1*3=X" | mdb
        1</screen></sect1><sect1 id="adb-trans-8"><title>Watchpoint Length Specifier</title><para>The watchpoint length specifier syntax recognized by MDB is different
from the syntax described in <literal>adb</literal>(1). In particular, the <literal>adb</literal> watchpoint     commands <literal>:w</literal>, <literal>:a</literal>,
and <literal>:p</literal> allow an integer length in bytes to be inserted
between the colon and the command character. In MDB, the count should be specified
following the initial address as a repeat count. Stated simply, these <literal>adb</literal>(1) commands: </para><screen format="linespecific">123:456w
123:456a
123:456p</screen><para> are specified in MDB as</para><screen format="linespecific">123,456:w
123,456:a
123,456:p</screen><para>The MDB <literal>::wp</literal> dcmd provides more complete facilities
for creating user process watchpoints.  </para></sect1><sect1 id="adb-trans-9"><title>Address Map Modifier</title><para>The <literal>adb</literal>(1) commands to modify segments of the virtual
address map and object file map are not present in MDB. Specifically, the <literal>/m</literal>, <literal>/*m</literal>, <literal>?m</literal>, and <literal>?*m</literal> format specifiers are not recognized or supported by MDB. These
specifiers were used to manually modify the valid addressable range of the
current object and core files. MDB properly recognizes the addressable range
of such files automatically, and updates the ranges when a live     process
is being debugged, so these commands are no longer necessary. </para></sect1><sect1 id="adb-trans-10"><title>Output</title><para>The precise text output form of some commands is different in MDB. Macro
    files are formatted using the same basic rules, but shell scripts that
depend on the precise character-by-character output of certain commands may
need to change. Users who have shell scripts that parse the output of <literal>adb</literal> commands will need to revalidate and update such scripts as
part of the transition to MDB. </para></sect1></appendix><appendix id="crash-4"><gentext type="text">Appendix D</gentext><gentext type="toc">D.&#160;&#160;
				 Transition From crash</gentext><title>Transition From <command>crash</command></title><highlights><para>The transition from using the legacy <olink targetdocent="REFMAN1M" localinfo="CRASH-1M" type="v-only"><citerefentry><refentrytitle>crash</refentrytitle><manvolnum><gentext type="text">(</gentext>1M<gentext type="text">)</gentext></manvolnum></citerefentry></olink> utility to using <olink targetdocent="REFMAN1" localinfo="MDB-1" type="v-only"><citerefentry><refentrytitle>mdb</refentrytitle><manvolnum><gentext type="text">(</gentext>1<gentext type="text">)</gentext></manvolnum></citerefentry></olink> is relatively simple: MDB
provides most of the “canned” crash commands. The additional extensibility
and interactive features of MDB allow the programmer to explore aspects of
the system not examined by the current set of commands. </para><para>This appendix briefly discusses several features of <olink targetdocent="REFMAN1M" localinfo="CRASH-1M" type="v-only"><citerefentry><refentrytitle>crash</refentrytitle><manvolnum><gentext type="text">(</gentext>1M<gentext type="text">)</gentext></manvolnum></citerefentry></olink> and provides pointers to
equivalent MDB functionality. </para></highlights><indexterm id="indexterm-580"><primary><literal>crash(1M)</literal></primary></indexterm><sect1 id="crash-5"><title>Command-line Options</title><para>The <literal>crash</literal> <option><gentext type="text">-</gentext>d</option>, <option><gentext type="text">-</gentext>n</option>,
and <option><gentext type="text">-</gentext>w</option> command-line options are not supported by <command>mdb</command>. The <literal>crash</literal> dump file and name list (symbol
table file) are specified as arguments to <command>mdb</command> in the order
of name list, crash dump file.  To examine the live kernel, the <literal>mdb</literal> <option><gentext type="text">-</gentext>k</option> option should be specified with no additional
arguments.  Users who want to redirect the output of <literal>mdb</literal>
to a file or other output destination, should either employ the appropriate
shell redirection operator following the <command>mdb</command> invocation
on the command line, or use the <command>::log</command> built-in dcmd.</para></sect1><sect1 id="crash-1"><title>Input in MDB</title><para>In general, input in MDB is similar to <command>crash</command>, except
that function names (in MDB, dcmd names) are prefixed with “<literal>::</literal>”.  Some MDB dcmds accept a leading expression argument
that precedes the dcmd name.  Like <command>crash</command>, string options
can follow the dcmd name.  If a ! character follows a function invocation,
MDB will also create a pipeline to the specified shell pipeline.  All immediate
values specified in MDB are interpreted in hexadecimal by default. The radix
specifiers for immediate values are different in <command>crash</command>
and MDB as shown in <link linkend="crash-tbl-3">Table D–1</link>:</para><table frame="topbot" id="crash-tbl-3"><gentext type="text">Table D&#8211;1 </gentext><title>Radix Specifiers</title><tgroup cols="3" colsep="0" rowsep="0"><colspec colname="colspec3" colwidth="33*"/><colspec colname="colspec4" colwidth="33*"/><colspec colname="colspec5" colwidth="33*"/><thead><row rowsep="1"><entry><para>crash</para></entry><entry><para>mdb</para></entry><entry><para>Radix</para></entry></row></thead><tbody><row><entry><para>0x</para></entry><entry><para>0x</para></entry><entry><para>hexadecimal (base 16)</para></entry></row><row><entry><para>0d</para></entry><entry><para>0t</para></entry><entry><para>decimal (base 10)</para></entry></row><row><entry colname="colspec3"><para>0b</para></entry><entry colname="colspec4"><para>0i</para></entry><entry colname="colspec5"><para>binary (base 2)</para></entry></row></tbody></tgroup></table><para>Many <command>crash</command> commands accepted slot numbers or slot
ranges as input arguments. The Solaris operating environment is no longer
structured in terms of slots, so MDB dcmds do not provide support for slot-number
processing.</para></sect1><sect1 id="crash-2"><title>Functions</title><para></para><informaltable frame="topbot"><tgroup cols="3" colsep="0" rowsep="0"><colspec colname="colspec0" colwidth="18.00*"/><colspec colname="colspec1" colwidth="18.25*"/><colspec colname="colspec2" colwidth="62.75*"/><thead><row rowsep="1"><entry><para>crash function</para></entry><entry><para>mdb
dcmd</para></entry><entry><para>Comments</para></entry></row></thead><tbody><row><entry><para>?</para></entry><entry><para>::dcmds</para></entry><entry><para>List available functions.</para></entry></row><row><entry><para>!command</para></entry><entry><para>!command</para></entry><entry><para>Escape to the shell and execute commmand.</para></entry></row><row><entry><para>base</para></entry><entry><para>=</para></entry><entry><para>In mdb, the = format character can be used to convert the left-hand expression
value to any of the known formats. Formats for octal, decimal, and hexadecimal
are provided.</para></entry></row><row><entry><para>callout</para></entry><entry><para>::callout</para></entry><entry><para>Print the callout table.</para></entry></row><row><entry><para>class</para></entry><entry><para>::class</para></entry><entry><para>Print scheduling classes.</para></entry></row><row><entry><para>cpu</para></entry><entry><para>::cpuinfo</para></entry><entry><para>Print information about the threads dispatched on the system
CPUs. If the contents of a particular CPU structure are needed, the user should
apply the <literal>$&lt;cpu</literal>
macro to the CPU address in mdb.</para></entry></row><row><entry><para>help</para></entry><entry><para>::help</para></entry><entry><para>Print a description of the named dcmd, or general help information.</para></entry></row><row><entry><para>kfp</para></entry><entry><para>::regs</para></entry><entry><para>The mdb ::regs dcmd displays the complete kernel register set, including the
current stack frame pointer. The $C dcmd can be used to display a stack backtrace
including frame pointers.</para></entry></row><row><entry><para>kmalog</para></entry><entry><para>::kmalog</para></entry><entry><para>Display events in kernel memory allocator transaction log.</para></entry></row><row><entry><para>kmastat</para></entry><entry><para>::kmastat</para></entry><entry><para>Print kernel memory allocator transaction log.</para></entry></row><row><entry><para>kmausers</para></entry><entry><para>::kmausers</para></entry><entry><para>Print information about the medium and large users of the kernel
memory allocator that have current memory allocations.</para></entry></row><row><entry><para>mount</para></entry><entry><para>::fsinfo</para></entry><entry><para>Print information about mounted file systems.</para></entry></row><row><entry><para>nm</para></entry><entry><para>::nm</para></entry><entry><para>Print symbol type and value information.</para></entry></row><row><entry><para>od</para></entry><entry><para>::dump</para></entry><entry><para>Print a formatted memory dump of a given region. In mdb, ::dump displays a
mixed ASCII and hexadecimal display of the region.</para></entry></row><row><entry><para>proc</para></entry><entry><para>::ps</para></entry><entry><para>Print a table of the active processes.</para></entry></row><row><entry colname="colspec0"><para>quit</para></entry><entry colname="colspec1"><para>::quit</para></entry><entry colname="colspec2"><para>Quit the debugger.</para></entry></row><row><entry colname="colspec0"><para>rd</para></entry><entry colname="colspec1"><para>::dump</para></entry><entry colname="colspec2"><para>Print a formatted memory
dump of a given region. In mdb, ::dump displays a mixed ASCII and hexadecimal
display of the region.</para></entry></row><row><entry><para>redirect</para></entry><entry><para>::log</para></entry><entry><para>In mdb, output for input and output can be globally redirected
to a log file using ::log.</para></entry></row><row><entry><para>search</para></entry><entry><para>::kgrep</para></entry><entry><para>In mdb, the ::kgrep dcmd can be used to search the kernel's address
space for a particular value. The pattern match built-in dcmds can also be
used to search the physical, virtual, or object files address spaces for patterns.</para></entry></row><row><entry><para>stack</para></entry><entry><para>::stack</para></entry><entry><para>The current stack trace can be obtained using ::stack.  The stack
trace of a particular kernel thread can be determined using the ::findstack
dcmd.  A memory dump of the current stack can be obtained using the / or ::dump
dcmds and the current stack pointer. The <literal>$&lt;stackregs</literal>
macro can be applied to a stack pointer to obtain the per-frame saved register
values.</para></entry></row><row><entry><para>status</para></entry><entry><para>::status</para></entry><entry><para>Display status information about the system or dump being examined
by the debugger.</para></entry></row><row><entry colname="colspec0"><para>stream</para></entry><entry colname="colspec1"><para>::stream</para></entry><entry colname="colspec2"><para>The mdb ::stream dcmd
can be used to format and display the structure of a particular kernel STREAM.
If the list of active STREAM strucures is needed, the user should execute
::walk stream_head_cache in mdb and pipe the resulting addresses to an appropriate
formatting dcmd or macro.</para></entry></row><row><entry colname="colspec0"><para>strstat</para></entry><entry colname="colspec1"><para>::kmastat</para></entry><entry colname="colspec2"><para>The ::kmastat
dcmd displays a superset of the information reported by the <command>strstat</command> function.</para></entry></row><row><entry colname="colspec0"><para>trace</para></entry><entry colname="colspec1"><para>::stack</para></entry><entry colname="colspec2"><para>The current stack trace
can be obtained using ::stack. The stack trace of a particular kernel thread
can be determined using the ::findstack dcmd. A memory dump of the current
stack can be obtained using the / or ::dump dcmds and the current stack pointer.
The <literal>$&lt;stackregs</literal> macro can be applied to a stack pointer
to obtain the per-frame saved register values.</para></entry></row><row><entry colname="colspec0"><para>var</para></entry><entry colname="colspec1"><para>$&lt;v</para></entry><entry colname="colspec2"><para>Print the tunable system
parameters in the global <structname>var</structname> structure.</para></entry></row><row><entry colname="colspec0"><para>vfs</para></entry><entry colname="colspec1"><para>::fsinfo</para></entry><entry colname="colspec2"><para>Print information about
mounted file systems.</para></entry></row><row><entry colname="colspec0"><para>vtop</para></entry><entry colname="colspec1"><para>::vtop</para></entry><entry colname="colspec2"><para>Print the physical address
translation of the given virtual address.</para></entry></row></tbody></tgroup></informaltable></sect1></appendix><index><gentext type="text">Index</gentext><gentext type="toc">Index</gentext><indexdiv><title>Numbers and Symbols</title><indexentry><primaryie><literal>0xbaddcafe</literal></primaryie><indexlocation>indexterm-461</indexlocation></indexentry><indexentry><primaryie><literal>0xdeadbeef</literal></primaryie><indexlocation>indexterm-453</indexlocation></indexentry><indexentry><primaryie><literal>0xfeedface</literal></primaryie><indexlocation>indexterm-455</indexlocation></indexentry></indexdiv><indexdiv><title>A</title><indexentry><primaryie>Arithmetic Expansion</primaryie><indexlocation>indexterm-18</indexlocation><secondaryie>Binary operators</secondaryie><indexlocation>indexterm-20</indexlocation><secondaryie>Unary operators</secondaryie><indexlocation>indexterm-19</indexlocation></indexentry></indexdiv><indexdiv><title>B</title><indexentry><primaryie><literal>bcp</literal></primaryie><indexlocation>indexterm-463</indexlocation></indexentry><indexentry><primaryie>bufctl</primaryie><indexlocation>indexterm-462</indexlocation><indexlocation>indexterm-465</indexlocation></indexentry><indexentry><primaryie>buftag</primaryie><indexlocation>indexterm-456</indexlocation></indexentry><indexentry><primaryie><literal>bxstat</literal></primaryie><indexlocation>indexterm-464</indexlocation></indexentry></indexdiv><indexdiv><title>C</title><indexentry><primaryie>command reentry</primaryie><indexlocation>indexterm-41</indexlocation></indexentry><indexentry><primaryie>Commands</primaryie><indexlocation>indexterm-13</indexlocation></indexentry><indexentry><primaryie>Comments</primaryie><indexlocation>indexterm-15</indexlocation></indexentry><indexentry><primaryie>Configuration</primaryie><secondaryie>dcmds</secondaryie><tertiaryie><command>::system</command></tertiaryie><indexlocation>indexterm-347</indexlocation></indexentry><indexentry><primaryie>contents log</primaryie><indexlocation>indexterm-475</indexlocation></indexentry><indexentry><primaryie>CPUs and the Dispatcher</primaryie><secondaryie>dcmds</secondaryie><tertiaryie><command>::callout</command></tertiaryie><indexlocation>indexterm-197</indexlocation><tertiaryie><command>::class</command></tertiaryie><indexlocation>indexterm-199</indexlocation><tertiaryie><command>::cpuinfo</command></tertiaryie><indexlocation>indexterm-201</indexlocation><secondaryie>Walkers</secondaryie><tertiaryie>cpu</tertiaryie><indexlocation>indexterm-203</indexlocation></indexentry><indexentry><primaryie><literal>crash(1M)</literal></primaryie><indexlocation>indexterm-580</indexlocation></indexentry><indexentry><primaryie>Cyclics</primaryie><secondaryie>dcmds</secondaryie><tertiaryie><command>::cyccover</command></tertiaryie><indexlocation>indexterm-329</indexlocation><tertiaryie><command>::cycinfo</command></tertiaryie><indexlocation>indexterm-325</indexlocation><tertiaryie><command>::cyclic</command></tertiaryie><indexlocation>indexterm-327</indexlocation><tertiaryie><command>::cyctrace</command></tertiaryie><indexlocation>indexterm-331</indexlocation><secondaryie>Walkers</secondaryie><tertiaryie>cyccpu</tertiaryie><indexlocation>indexterm-333</indexlocation><tertiaryie>cyctrace</tertiaryie><indexlocation>indexterm-335</indexlocation></indexentry></indexdiv><indexdiv><title>D</title><indexentry><primaryie>dcmd, definition</primaryie><indexlocation>indexterm-1</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_ABORT</literal></primaryie><indexlocation>indexterm-494</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_ADDRSPEC</literal></primaryie><indexlocation>indexterm-485</indexlocation></indexentry><indexentry><primaryie>dcmd and Walker Name Resolution</primaryie><indexlocation>indexterm-29</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_ERR</literal></primaryie><indexlocation>indexterm-491</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_LOOP</literal></primaryie><indexlocation>indexterm-486</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_LOOPFIRST</literal></primaryie><indexlocation>indexterm-487</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_NEXT</literal></primaryie><indexlocation>indexterm-493</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_OK</literal></primaryie><indexlocation>indexterm-490</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_PIPE</literal></primaryie><indexlocation>indexterm-488</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_PIPE_OUT</literal></primaryie><indexlocation>indexterm-489</indexlocation></indexentry><indexentry><primaryie><literal>DCMD_USAGE</literal></primaryie><indexlocation>indexterm-492</indexlocation></indexentry><indexentry><primaryie>dcmds</primaryie><secondaryie><literal>$&gt;</literal></secondaryie><indexlocation>indexterm-83</indexlocation><secondaryie><literal>$&lt;</literal></secondaryie><indexlocation>indexterm-46</indexlocation><secondaryie><literal>$?</literal></secondaryie><indexlocation>indexterm-48</indexlocation><secondaryie><literal>$&lt;&lt;</literal></secondaryie><indexlocation>indexterm-47</indexlocation><secondaryie><literal>$C</literal></secondaryie><indexlocation>indexterm-49</indexlocation><secondaryie><literal>$c</literal></secondaryie><indexlocation>indexterm-99</indexlocation><secondaryie><literal>$d</literal></secondaryie><indexlocation>indexterm-50</indexlocation><secondaryie><literal>$e</literal></secondaryie><indexlocation>indexterm-51</indexlocation><secondaryie><literal>$f</literal></secondaryie><indexlocation>indexterm-72</indexlocation><secondaryie><literal>$m</literal></secondaryie><indexlocation>indexterm-86</indexlocation><secondaryie><literal>$P</literal></secondaryie><indexlocation>indexterm-52</indexlocation><secondaryie><literal>$p</literal></secondaryie><indexlocation>indexterm-61</indexlocation><secondaryie><command>$q</command></secondaryie><indexlocation>indexterm-92</indexlocation><secondaryie><command>$r</command></secondaryie><indexlocation>indexterm-94</indexlocation><secondaryie><literal>$s</literal></secondaryie><indexlocation>indexterm-53</indexlocation><secondaryie><literal>$V</literal></secondaryie><indexlocation>indexterm-66</indexlocation><secondaryie><literal>$v</literal></secondaryie><indexlocation>indexterm-54</indexlocation><secondaryie><literal>$W</literal></secondaryie><indexlocation>indexterm-56</indexlocation><secondaryie><literal>$w</literal></secondaryie><indexlocation>indexterm-55</indexlocation><secondaryie><literal>$X</literal></secondaryie><indexlocation>indexterm-76</indexlocation><secondaryie><literal>$x</literal></secondaryie><indexlocation>indexterm-75</indexlocation><secondaryie><literal>$Y</literal></secondaryie><indexlocation>indexterm-78</indexlocation><secondaryie><literal>$y</literal></secondaryie><indexlocation>indexterm-77</indexlocation><secondaryie><command>:A</command></secondaryie><indexlocation>indexterm-58</indexlocation><secondaryie><command>::addr2smap</command></secondaryie><indexlocation>indexterm-172</indexlocation><secondaryie><command>::memlist</command></secondaryie><indexlocation>indexterm-176</indexlocation><secondaryie><command>::memstat</command></secondaryie><indexlocation>indexterm-178</indexlocation><secondaryie><command>::page</command></secondaryie><indexlocation>indexterm-180</indexlocation><secondaryie><command>::allocdby</command></secondaryie><indexlocation>indexterm-115</indexlocation><indexlocation>indexterm-479</indexlocation><secondaryie><command>::as2proc</command></secondaryie><indexlocation>indexterm-174</indexlocation><secondaryie><command>::attach</command></secondaryie><indexlocation>indexterm-57</indexlocation><secondaryie><command>::bufctl</command></secondaryie><indexlocation>indexterm-117</indexlocation><indexlocation>indexterm-478</indexlocation><secondaryie><command>::callout</command></secondaryie><indexlocation>indexterm-198</indexlocation><secondaryie><command>::cat</command></secondaryie><indexlocation>indexterm-59</indexlocation><secondaryie><command>::class</command></secondaryie><indexlocation>indexterm-200</indexlocation><secondaryie><command>::context</command></secondaryie><indexlocation>indexterm-60</indexlocation><secondaryie><command>::cpuinfo</command></secondaryie><indexlocation>indexterm-202</indexlocation><secondaryie><command>::cyccover</command></secondaryie><indexlocation>indexterm-330</indexlocation><secondaryie><command>::cycinfo</command></secondaryie><indexlocation>indexterm-326</indexlocation><secondaryie><command>::cyclic</command></secondaryie><indexlocation>indexterm-328</indexlocation><secondaryie><command>::cyctrace</command></secondaryie><indexlocation>indexterm-332</indexlocation><secondaryie><command>::dcmds</command></secondaryie><indexlocation>indexterm-62</indexlocation><secondaryie><command>::binding_hash_entry</command></secondaryie><indexlocation>indexterm-206</indexlocation><secondaryie><command>::devbindings</command></secondaryie><indexlocation>indexterm-208</indexlocation><secondaryie><command>::devinfo2driver</command></secondaryie><indexlocation>indexterm-212</indexlocation><secondaryie><command>::devinfo</command></secondaryie><indexlocation>indexterm-210</indexlocation><secondaryie><command>::devnames</command></secondaryie><indexlocation>indexterm-214</indexlocation><secondaryie><command>::dis</command></secondaryie><indexlocation>indexterm-63</indexlocation><secondaryie><command>::disasms</command></secondaryie><indexlocation>indexterm-64</indexlocation><secondaryie><command>::dismode</command></secondaryie><indexlocation>indexterm-65</indexlocation><secondaryie><command>::dmods</command></secondaryie><indexlocation>indexterm-67</indexlocation><secondaryie><command>::dump</command></secondaryie><indexlocation>indexterm-68</indexlocation><secondaryie><command>::echo</command></secondaryie><indexlocation>indexterm-69</indexlocation><secondaryie><command>::eval</command></secondaryie><indexlocation>indexterm-70</indexlocation><secondaryie><command>::fd</command></secondaryie><indexlocation>indexterm-290</indexlocation><secondaryie><command>::mi</command></secondaryie><indexlocation>indexterm-266</indexlocation><secondaryie><command>::netstat</command></secondaryie><indexlocation>indexterm-268</indexlocation><secondaryie><command>::sonode</command></secondaryie><indexlocation>indexterm-270</indexlocation><secondaryie><command>::tcpb</command></secondaryie><indexlocation>indexterm-272</indexlocation><secondaryie><command>::files</command></secondaryie><indexlocation>indexterm-71</indexlocation><secondaryie><command>::findleaks</command></secondaryie><indexlocation>indexterm-119</indexlocation><indexlocation>indexterm-469</indexlocation><secondaryie><command>::findstack</command></secondaryie><indexlocation>indexterm-292</indexlocation><secondaryie><command>::formats</command></secondaryie><indexlocation>indexterm-36</indexlocation><indexlocation>indexterm-73</indexlocation><secondaryie><command>::fpregs</command></secondaryie><indexlocation>indexterm-74</indexlocation><secondaryie><command>::freedby</command></secondaryie><indexlocation>indexterm-121</indexlocation><indexlocation>indexterm-480</indexlocation><secondaryie><command>::fsinfo</command></secondaryie><indexlocation>indexterm-164</indexlocation><secondaryie><command>::grep</command></secondaryie><indexlocation>indexterm-79</indexlocation><secondaryie><command>::help</command></secondaryie><indexlocation>indexterm-80</indexlocation><secondaryie><command>::errorq</command></secondaryie><indexlocation>indexterm-342</indexlocation><secondaryie><command>::ipcs</command></secondaryie><indexlocation>indexterm-350</indexlocation><secondaryie><command>::msg</command></secondaryie><indexlocation>indexterm-352</indexlocation><secondaryie><command>::msqid</command></secondaryie><indexlocation>indexterm-354</indexlocation><secondaryie><command>::system</command></secondaryie><indexlocation>indexterm-348</indexlocation><secondaryie><command>::taskq_entry</command></secondaryie><indexlocation>indexterm-338</indexlocation><secondaryie><command>::ire</command></secondaryie><indexlocation>indexterm-381</indexlocation><secondaryie><command>::kgrep</command></secondaryie><indexlocation>indexterm-123</indexlocation><indexlocation>indexterm-472</indexlocation><secondaryie><command>::kmalog</command></secondaryie><indexlocation>indexterm-125</indexlocation><secondaryie><command>::kmastat</command></secondaryie><indexlocation>indexterm-127</indexlocation><indexlocation>indexterm-446</indexlocation><secondaryie><command>::kmausers</command></secondaryie><indexlocation>indexterm-129</indexlocation><secondaryie><command>::kmem_cache</command></secondaryie><indexlocation>indexterm-131</indexlocation><indexlocation>indexterm-447</indexlocation><secondaryie><command>::kmem_log</command></secondaryie><indexlocation>indexterm-133</indexlocation><indexlocation>indexterm-477</indexlocation><secondaryie><command>::kmem_verify</command></secondaryie><indexlocation>indexterm-135</indexlocation><indexlocation>indexterm-473</indexlocation><secondaryie><command>::lminfo</command></secondaryie><indexlocation>indexterm-166</indexlocation><secondaryie><command>::lnode</command></secondaryie><indexlocation>indexterm-373</indexlocation><secondaryie><command>::lnode2dev</command></secondaryie><indexlocation>indexterm-375</indexlocation><secondaryie><command>::lnode2rdev</command></secondaryie><indexlocation>indexterm-377</indexlocation><secondaryie><command>::load</command></secondaryie><indexlocation>indexterm-81</indexlocation><secondaryie><command>::log</command></secondaryie><indexlocation>indexterm-82</indexlocation><secondaryie><command>::major2name</command></secondaryie><indexlocation>indexterm-218</indexlocation><secondaryie><command>::map</command></secondaryie><indexlocation>indexterm-84</indexlocation><secondaryie><command>::mappings</command></secondaryie><indexlocation>indexterm-85</indexlocation><secondaryie><command>::modctl</command></secondaryie><indexlocation>indexterm-385</indexlocation><secondaryie><command>::modctl2devinfo</command></secondaryie><indexlocation>indexterm-220</indexlocation><secondaryie><command>::modhdrs</command></secondaryie><indexlocation>indexterm-387</indexlocation><secondaryie><command>::modinfo</command></secondaryie><indexlocation>indexterm-389</indexlocation><secondaryie><command>::msqid_ds</command></secondaryie><indexlocation>indexterm-356</indexlocation><secondaryie><command>::semid</command></secondaryie><indexlocation>indexterm-358</indexlocation><secondaryie><command>::name2major</command></secondaryie><indexlocation>indexterm-222</indexlocation><secondaryie><command>::nm</command></secondaryie><indexlocation>indexterm-87</indexlocation><secondaryie><command>::nmadd</command></secondaryie><indexlocation>indexterm-88</indexlocation><secondaryie><command>::nmdel</command></secondaryie><indexlocation>indexterm-89</indexlocation><secondaryie><command>::objects</command></secondaryie><indexlocation>indexterm-90</indexlocation><secondaryie><command>::pid2proc</command></secondaryie><indexlocation>indexterm-294</indexlocation><secondaryie><command>::pmap</command></secondaryie><indexlocation>indexterm-296</indexlocation><secondaryie><command>::prtconf</command></secondaryie><indexlocation>indexterm-216</indexlocation><secondaryie><command>::ps</command></secondaryie><indexlocation>indexterm-298</indexlocation><secondaryie><command>::ptree</command></secondaryie><indexlocation>indexterm-300</indexlocation><secondaryie><command>::task</command></secondaryie><indexlocation>indexterm-302</indexlocation><secondaryie><command>::thread</command></secondaryie><indexlocation>indexterm-304</indexlocation><secondaryie><command>::q2otherq</command></secondaryie><indexlocation>indexterm-246</indexlocation><secondaryie><command>::q2rdq</command></secondaryie><indexlocation>indexterm-248</indexlocation><secondaryie><command>::q2syncq</command></secondaryie><indexlocation>indexterm-244</indexlocation><secondaryie><command>::q2wrq</command></secondaryie><indexlocation>indexterm-250</indexlocation><secondaryie><command>::queue</command></secondaryie><indexlocation>indexterm-242</indexlocation><secondaryie><command>::quit</command></secondaryie><indexlocation>indexterm-91</indexlocation><secondaryie><command>:R</command></secondaryie><indexlocation>indexterm-96</indexlocation><secondaryie><command>::regs</command></secondaryie><indexlocation>indexterm-93</indexlocation><secondaryie><command>::release</command></secondaryie><indexlocation>indexterm-95</indexlocation><secondaryie><command>::rwlock</command></secondaryie><indexlocation>indexterm-314</indexlocation><secondaryie><command>::sobj2ts</command></secondaryie><indexlocation>indexterm-316</indexlocation><secondaryie><command>::turnstile</command></secondaryie><indexlocation>indexterm-318</indexlocation><secondaryie><command>::seg</command></secondaryie><indexlocation>indexterm-182</indexlocation><secondaryie><command>::swapinfo</command></secondaryie><indexlocation>indexterm-184</indexlocation><secondaryie><command>::semid_ds</command></secondaryie><indexlocation>indexterm-360</indexlocation><secondaryie><command>::shmid</command></secondaryie><indexlocation>indexterm-362</indexlocation><secondaryie><command>::set</command></secondaryie><indexlocation>indexterm-97</indexlocation><secondaryie><command>::shmid_ds</command></secondaryie><indexlocation>indexterm-363</indexlocation><secondaryie><command>::softint</command></secondaryie><indexlocation>indexterm-421</indexlocation><secondaryie><command>::softstate</command></secondaryie><indexlocation>indexterm-224</indexlocation><secondaryie><command>::stack</command></secondaryie><indexlocation>indexterm-98</indexlocation><secondaryie><command>::status</command></secondaryie><indexlocation>indexterm-101</indexlocation><secondaryie><command>::stream</command></secondaryie><indexlocation>indexterm-252</indexlocation><secondaryie><command>::syncq</command></secondaryie><indexlocation>indexterm-254</indexlocation><secondaryie><command>::syncq2q</command></secondaryie><indexlocation>indexterm-256</indexlocation><secondaryie><command>::ttctl</command></secondaryie><indexlocation>indexterm-423</indexlocation><secondaryie><command>::ttrace</command></secondaryie><indexlocation>indexterm-413</indexlocation><indexlocation>indexterm-417</indexlocation><indexlocation>indexterm-425</indexlocation><secondaryie><command>::uhci_qh</command></secondaryie><indexlocation>indexterm-393</indexlocation><secondaryie><command>::uhci_td</command></secondaryie><indexlocation>indexterm-395</indexlocation><secondaryie><command>::usb_device</command></secondaryie><indexlocation>indexterm-405</indexlocation><secondaryie><command>::usb_hcdi_cb</command></secondaryie><indexlocation>indexterm-403</indexlocation><secondaryie><command>::usb_pipe_handle</command></secondaryie><indexlocation>indexterm-407</indexlocation><secondaryie><command>::usba_debug_buf</command></secondaryie><indexlocation>indexterm-401</indexlocation><secondaryie><command>::typeset</command></secondaryie><indexlocation>indexterm-102</indexlocation><secondaryie><command>::unload</command></secondaryie><indexlocation>indexterm-103</indexlocation><secondaryie><command>::unset</command></secondaryie><indexlocation>indexterm-104</indexlocation><secondaryie><command>::vars</command></secondaryie><indexlocation>indexterm-105</indexlocation><secondaryie><command>::version</command></secondaryie><indexlocation>indexterm-106</indexlocation><secondaryie><command>::vmem</command></secondaryie><indexlocation>indexterm-137</indexlocation><secondaryie><command>::vmem_seg</command></secondaryie><indexlocation>indexterm-139</indexlocation><secondaryie><command>::vnode2path</command></secondaryie><indexlocation>indexterm-168</indexlocation><secondaryie><command>::vnode2smap</command></secondaryie><indexlocation>indexterm-186</indexlocation><secondaryie><command>::vtop</command></secondaryie><indexlocation>indexterm-107</indexlocation><secondaryie><command>::walk</command></secondaryie><indexlocation>indexterm-108</indexlocation><secondaryie><command>::walkers</command></s