xref: /xnu-8796.101.5/tools/lldbmacros/README.md (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
1*aca3beaaSApple OSS DistributionsTable of Contents
2*aca3beaaSApple OSS Distributions=================
3*aca3beaaSApple OSS Distributions
4*aca3beaaSApple OSS Distributions      A. How to use lldb for kernel debugging
5*aca3beaaSApple OSS Distributions      B. Design of lldb kernel debugging platform.
6*aca3beaaSApple OSS Distributions      C. Kernel debugging commands.
7*aca3beaaSApple OSS Distributions          i. Using commands.
8*aca3beaaSApple OSS Distributions         ii. Writing new commands.
9*aca3beaaSApple OSS Distributions      D. Kernel type summaries.
10*aca3beaaSApple OSS Distributions          i. Using summaries
11*aca3beaaSApple OSS Distributions         ii. Writing new summary functions
12*aca3beaaSApple OSS Distributions      E. FAQ and General Coding Guidelines
13*aca3beaaSApple OSS Distributions          i. Frequently Asked Questions
14*aca3beaaSApple OSS Distributions         ii. Formatted Output printing guidelines [MUST READ]
15*aca3beaaSApple OSS Distributions        iii. Coding conventions.  [MUST READ]
16*aca3beaaSApple OSS Distributions         iv. Submitting changes in lldbmacros [MUST READ]
17*aca3beaaSApple OSS Distributions          v. Common utility functions and paradigms
18*aca3beaaSApple OSS Distributions      F. Development and Debugging on lldb kernel debugging platform.
19*aca3beaaSApple OSS Distributions          i. Reading a exception backtrace
20*aca3beaaSApple OSS Distributions         ii. Loading custom or local lldbmacros and operating_system plugin
21*aca3beaaSApple OSS Distributions        iii. Adding debug related 'printf's
22*aca3beaaSApple OSS Distributions
23*aca3beaaSApple OSS DistributionsA. How to use lldb for kernel debugging
24*aca3beaaSApple OSS Distributions========================================
25*aca3beaaSApple OSS Distributions
26*aca3beaaSApple OSS Distributionslldb can be used for kernel debugging the same way as gdb. The simplest way is to start lldb with kernel symbol file. The lldb environment by default does not allow loading automatic python modules. Please add the following setting in
27*aca3beaaSApple OSS Distributions
28*aca3beaaSApple OSS Distributions    File: ~/.lldbinit
29*aca3beaaSApple OSS Distributions    settings set target.load-script-from-symbol-file true
30*aca3beaaSApple OSS Distributions
31*aca3beaaSApple OSS DistributionsNow lldb will be ready to connect over kdp-remote '\<hostname:port>' or 'gdb-remote \<hostname:port>'. In case using a core file please do 'file --core /path/to/corefile'
32*aca3beaaSApple OSS Distributions
33*aca3beaaSApple OSS DistributionsFollowing are detailed steps on how to debug a panic'ed / NMI'ed machine (For the curious souls).
34*aca3beaaSApple OSS Distributions
35*aca3beaaSApple OSS Distributionslldb debugging in detail:-
36*aca3beaaSApple OSS Distributions
37*aca3beaaSApple OSS Distributions  * start lldb with the right symbols file. If you do not know the version apriori, then enable dsymForUUID to load symbols dynamically.
38*aca3beaaSApple OSS Distributions        bash$ dsymForUUID --enable
39*aca3beaaSApple OSS Distributions        bash$ lldb /path/to/mach_kernel.symbols
40*aca3beaaSApple OSS Distributions        Current executable set to '/Sources/Symbols/xnu/xnu-2253~2/mach_kernel' (x86_64).
41*aca3beaaSApple OSS Distributions        (lldb)
42*aca3beaaSApple OSS Distributions
43*aca3beaaSApple OSS Distributions  * connect to remote device or load a core file
44*aca3beaaSApple OSS Distributions        #for kdp
45*aca3beaaSApple OSS Distributions        (lldb) process connect --plugin kdp-remote udp://17.123.45.67:41139
46*aca3beaaSApple OSS Distributions        #for gdb (eg with astris)
47*aca3beaaSApple OSS Distributions        (lldb) process connect --plugin gdb-remote gdb://17.123.45.67:8000
48*aca3beaaSApple OSS Distributions        #for loading a core file
49*aca3beaaSApple OSS Distributions        (lldb) file --core /path/to/core/file  /path/to/kernel_symbol_file
50*aca3beaaSApple OSS Distributions
51*aca3beaaSApple OSS Distributions  * Once connected you can debug with basic lldb commands like print, bt, expr etc. The xnu debug macros will also be loaded automatically from the dSYM files.
52*aca3beaaSApple OSS Distributions  In case if you are working with older kernel files you can load kernel specific commands by doing -
53*aca3beaaSApple OSS Distributions        (lldb) command script import /path/to/xnu/tools/lldbmacros/xnu.py
54*aca3beaaSApple OSS Distributions        (lldb) showbootargs
55*aca3beaaSApple OSS Distributions        debug=0x14e ncpus=2
56*aca3beaaSApple OSS Distributions
57*aca3beaaSApple OSS Distributions  * You can do `kgmhelp` to get a list of commands available through xnu.py
58*aca3beaaSApple OSS Distributions
59*aca3beaaSApple OSS DistributionsSPECIAL: The `xnu.py` script brings in kernel type summary functions. To enable these please do -
60*aca3beaaSApple OSS Distributions
61*aca3beaaSApple OSS Distributions    (lldb) showlldbtypesummaries
62*aca3beaaSApple OSS Distributions
63*aca3beaaSApple OSS DistributionsThese could be very handy in printing important information from structures easily.
64*aca3beaaSApple OSS DistributionsFor ex.
65*aca3beaaSApple OSS Distributions
66*aca3beaaSApple OSS Distributions    (lldb) print (thread_t)0x80d6a620
67*aca3beaaSApple OSS Distributions    (thread_t) $45 = 0x80d6a620
68*aca3beaaSApple OSS Distributions    thread                   thread_id  processor            pri    io_policy  state wait_queue           wait_event           wmesg                thread_name
69*aca3beaaSApple OSS Distributions    0x80d6a620               0x317      0x902078c8           61                W     0x910cadd4           0x0                                       SystemSoundServer
70*aca3beaaSApple OSS Distributions
71*aca3beaaSApple OSS Distributions
72*aca3beaaSApple OSS Distributions
73*aca3beaaSApple OSS DistributionsB. Design of lldb kernel debugging platform.
74*aca3beaaSApple OSS Distributions=============================================
75*aca3beaaSApple OSS Distributions
76*aca3beaaSApple OSS DistributionsThe lldb debugger provides python scripting bridge for customizing commands and summaries in lldb. Following is the stack of platforms and how commands and summaries interact with it.
77*aca3beaaSApple OSS Distributions
78*aca3beaaSApple OSS Distributions    |------- xnu scripts ----------|
79*aca3beaaSApple OSS Distributions    | |- lldb Command/Scripting-|  |   <-- provides scriptability for kernel data structures through summary/command invocation.
80*aca3beaaSApple OSS Distributions    | |    |--lldb core--|      |  |   <-- interacts with remote kernel or corefile.
81*aca3beaaSApple OSS Distributions    | |-------------------------|  |
82*aca3beaaSApple OSS Distributions    |------------------------------|
83*aca3beaaSApple OSS Distributions
84*aca3beaaSApple OSS DistributionsThe xnu script in xnu/tools/lldbmacros provides the following:
85*aca3beaaSApple OSS Distributions
86*aca3beaaSApple OSS Distributions  * Custom functions to do plumbing of lldb command invocation to python function call. (see doc strings for @lldb_command)
87*aca3beaaSApple OSS Distributions    The command interface provides some common features (which can be invoked after passing '--' on cmd line) like -
88*aca3beaaSApple OSS Distributions
89*aca3beaaSApple OSS Distributions      i. send the output of command to file on disk
90*aca3beaaSApple OSS Distributions      ii. search for a string in the output and selectively print the line containing it.
91*aca3beaaSApple OSS Distributions      iii. -v options to increase verbosity levels in commands.
92*aca3beaaSApple OSS Distributions        For example: (lldb)showalltasks -- -s kernel_task --o /tmp/kernel_task.output -v
93*aca3beaaSApple OSS Distributions        will show task summary output with lines matching string 'kernel_task' into a file /tmp/kernel_task.output and with a verbosity level of (default +1)
94*aca3beaaSApple OSS Distributions
95*aca3beaaSApple OSS Distributions  * Customization for plugging in summary functions for lldb type summaries. (see doc strings for @lldb_summary)
96*aca3beaaSApple OSS Distributions     It will automatically register given types with the functions within the kernel category.
97*aca3beaaSApple OSS Distributions
98*aca3beaaSApple OSS Distributions  * Ability to register test cases for macros (see doc strings for @xnudebug_test).
99*aca3beaaSApple OSS Distributions
100*aca3beaaSApple OSS DistributionsThe file layout is like following
101*aca3beaaSApple OSS Distributions
102*aca3beaaSApple OSS Distributions    xnu/
103*aca3beaaSApple OSS Distributions     |-tools/
104*aca3beaaSApple OSS Distributions       |-lldbmacros/
105*aca3beaaSApple OSS Distributions         |-core/       # Core logic about kernel, lldb value abstraction, configs etc. **DO NOT TOUCH THIS DIR**
106*aca3beaaSApple OSS Distributions         |-plugins/    # Holds plugins for kernel commands.
107*aca3beaaSApple OSS Distributions         |-xnu.py      # xnu debug framework along with kgmhelp, xnudebug commands.
108*aca3beaaSApple OSS Distributions         |-xnudefines.py
109*aca3beaaSApple OSS Distributions         |-utils.py
110*aca3beaaSApple OSS Distributions         |-process.py  # files containing commands/summaries code for each subsystem
111*aca3beaaSApple OSS Distributions         |-...
112*aca3beaaSApple OSS Distributions
113*aca3beaaSApple OSS Distributions
114*aca3beaaSApple OSS DistributionsThe lldbmacros directory has a Makefile that follows the build process for xnu. This packages lldbmacros scripts into the dSYM of each kernel build. This helps in rev-locking the lldb commands with changes in kernel sources.
115*aca3beaaSApple OSS Distributions
116*aca3beaaSApple OSS Distributions
117*aca3beaaSApple OSS DistributionsC. Kernel debugging commands.
118*aca3beaaSApple OSS Distributions==============================
119*aca3beaaSApple OSS Distributionsi. Using commands.
120*aca3beaaSApple OSS Distributions------------------
121*aca3beaaSApple OSS DistributionsUsing xnu debug commands is very similar to kgmacros in gdb. You can use 'kgmhelp' to get a listing of available commands.
122*aca3beaaSApple OSS DistributionsIf you need detailed help for a command please type 'help <command name>' and the documentation for the command will be displayed.
123*aca3beaaSApple OSS DistributionsFor ex.
124*aca3beaaSApple OSS Distributions
125*aca3beaaSApple OSS Distributions    (lldb) help pmap_walk
126*aca3beaaSApple OSS Distributions    Perform a page-table walk in <pmap> for <virtual_address>.
127*aca3beaaSApple OSS Distributions         You can pass -- -v for verbose output. To increase the verbosity add more -v args after the '--'.
128*aca3beaaSApple OSS Distributions    Syntax: pmap_walk <pmap> <virtual_address>
129*aca3beaaSApple OSS Distributions
130*aca3beaaSApple OSS DistributionsThe basic format for every command provided under kgmhelp is like follows
131*aca3beaaSApple OSS Distributions
132*aca3beaaSApple OSS Distributions    (lldb) command_name [cmd_args..] [-CMDOPTIONS] [-xnuoptions]
133*aca3beaaSApple OSS Distributions    where:
134*aca3beaaSApple OSS Distributions      command_name : name of command as registed using the @lldb_command decorator and described in 'kgmhelp'
135*aca3beaaSApple OSS Distributions      cmd_args     : shell like arguments that are passed as is to the registered python function.
136*aca3beaaSApple OSS Distributions                     If there is error in these arguments than the implementor may display according error message.
137*aca3beaaSApple OSS Distributions      xnuoptions   : common options for stream based operations on the output of command_name.
138*aca3beaaSApple OSS Distributions                     Allowed options are
139*aca3beaaSApple OSS Distributions                     -h          : show help string of a command
140*aca3beaaSApple OSS Distributions                     -s <regexp> : print only the lines matching <regexp>
141*aca3beaaSApple OSS Distributions                     -o <file>   : direct the output of command to <file>. Will not display anything on terminal
142*aca3beaaSApple OSS Distributions                     -v          : increase the verbosity of the command. Each '-v' encountered will increase verbosity by 1.
143*aca3beaaSApple OSS Distributions                     -p <plugin> : pass the output of command to <plugin> for processing and followup with command requests by it.
144*aca3beaaSApple OSS Distributions      CMDOPTIONS   : These are command level options (always a CAPITAL letter option) that are defined by the macro developer. Please do
145*aca3beaaSApple OSS Distributions                     help <cmdname> to know how each option operates on that particular command. For an example of how to use CMDOPTIONS, take a look at vm_object_walk_pages in memory.py
146*aca3beaaSApple OSS Distributions
147*aca3beaaSApple OSS Distributionsii. Writing new commands.
148*aca3beaaSApple OSS Distributions--------------------------
149*aca3beaaSApple OSS DistributionsThe python modules are designed in such a way that the command from lldb invokes a python function with the arguments passed at lldb prompt.
150*aca3beaaSApple OSS Distributions
151*aca3beaaSApple OSS DistributionsIt is recommended that you do a decoupled development for command interface and core utility function so that any function/code can be called as a simple util function and get the same output. i.e.
152*aca3beaaSApple OSS Distributions
153*aca3beaaSApple OSS Distributions    (lldb)showtask 0xabcdef000 is same as python >>> GetTaskSummary(0xabcdef000) or equivalent
154*aca3beaaSApple OSS Distributions
155*aca3beaaSApple OSS DistributionsFollowing is a step by step guideline on how to add a new command ( e.g showtaskvme ). [extra tip: Always good idea to wrap your macro code within # Macro: , # EndMacro.]
156*aca3beaaSApple OSS Distributions
157*aca3beaaSApple OSS Distributions  1. register a command to a function. Use the lldb_command decorator to map a 'command_name' to a function. Optionally you can provide getopt compatible option string for customizing your command invocation. Note: Only CAPITAL letter options are allowed. lowercase options are reserved for the framework level features.
158*aca3beaaSApple OSS Distributions
159*aca3beaaSApple OSS Distributions  2. Immediately after the register define the function to handle the command invocation. The signature is always like Abc(cmd_args=None, cmd_options={})
160*aca3beaaSApple OSS Distributions
161*aca3beaaSApple OSS Distributions  3. Add documentation for Abc(). This is very important for lldb to show help for each command. [ Follow the guidelines above with documentation ]
162*aca3beaaSApple OSS Distributions
163*aca3beaaSApple OSS Distributions  4. Use cmd_args array to get args passed on command. For example a command like `showtaskvme 0xabcdef00` will put have cmd_args=['0xabcdef00']
164*aca3beaaSApple OSS Distributions      - note that we use core.value class as an interface to underlying C structures. Refer [Section B] for more details.
165*aca3beaaSApple OSS Distributions      - use kern.globals.\<variable_name> & kern.GetValueFromAddress for building values from addresses.
166*aca3beaaSApple OSS Distributions      - remember that the ideal type of object to be passed around is core.value
167*aca3beaaSApple OSS Distributions      - Anything you 'print' will be relayed to lldb terminal output.
168*aca3beaaSApple OSS Distributions
169*aca3beaaSApple OSS Distributions  5. If the user has passed any custom options they would be in cmd_options dict. the format is `{'-<optionflag>':'<value>'}`. The \<value> will be '' (empty string) for non-option flags.
170*aca3beaaSApple OSS Distributions
171*aca3beaaSApple OSS Distributions  6. If your function finds issue with the passed argument then you can `raise ArgumentError('error_message')` to notify the user. The framework will automatically catch this and show appropriate help using the function doc string.
172*aca3beaaSApple OSS Distributions
173*aca3beaaSApple OSS Distributions  7. Please use "##" for commenting your code. This is important because single "#" based strings may be mistakenly considered in `unifdef` program.
174*aca3beaaSApple OSS Distributions
175*aca3beaaSApple OSS Distributions Time for some code example? Try reading the code for function ShowTaskVmeHelper in memory.py.
176*aca3beaaSApple OSS Distributions
177*aca3beaaSApple OSS DistributionsSPECIAL Note: Very often you will find yourself making changes to a file for some command/summary and would like to test it out in lldb.
178*aca3beaaSApple OSS Distributions
179*aca3beaaSApple OSS DistributionsTo easily reload your changes in lldb please follow the below example.
180*aca3beaaSApple OSS Distributions
181*aca3beaaSApple OSS Distributions  * you fire up lldb and start using zprint. And soon you need to add functionality to zprint.
182*aca3beaaSApple OSS Distributions
183*aca3beaaSApple OSS Distributions  * you happily change a function code in memory.py file to zprint macro.
184*aca3beaaSApple OSS Distributions
185*aca3beaaSApple OSS Distributions  * now to reload that particular changes without killing your debug session do
186*aca3beaaSApple OSS Distributions        (lldb) xnudebug reload memory
187*aca3beaaSApple OSS Distributions         memory is reloaded from ./memory.py
188*aca3beaaSApple OSS Distributions        (lldb)
189*aca3beaaSApple OSS Distributions
190*aca3beaaSApple OSS Distributions  * Alternatively, you can use lldb`s command for script loading as
191*aca3beaaSApple OSS Distributions        (lldb) command script import /path/to/memory.py
192*aca3beaaSApple OSS Distributions    You can re-run the same command every time you update the code in file.
193*aca3beaaSApple OSS Distributions
194*aca3beaaSApple OSS Distributions It is very important that you do reload using xnudebug command as it does the plumbing of commands and types for your change in the module. Otherwise you could easily get confused
195*aca3beaaSApple OSS Distributions why your changes are not reflected in the command.
196*aca3beaaSApple OSS Distributions
197*aca3beaaSApple OSS Distributions
198*aca3beaaSApple OSS DistributionsD. Kernel type summaries.
199*aca3beaaSApple OSS Distributions==========================
200*aca3beaaSApple OSS Distributionsi. Using summaries
201*aca3beaaSApple OSS Distributions------------------
202*aca3beaaSApple OSS DistributionsThe lldb debugger provides ways for user to customize how a particular type of object be described when printed. These are very useful in displaying complex and large structures
203*aca3beaaSApple OSS Distributionswhere only certain fields are important based on some flag or value in some field or variable. The way it works is every time lldb wants to print an object it checks
204*aca3beaaSApple OSS Distributionsfor registered summaries. We can define python functions and hook it up with lldb as callbacks for type summaries.  For example.
205*aca3beaaSApple OSS Distributions
206*aca3beaaSApple OSS Distributions    (lldb) print first_zone
207*aca3beaaSApple OSS Distributions    (zone_t) $49 = 0xd007c000
208*aca3beaaSApple OSS Distributions          ZONE            TOT_SZ ALLOC_ELTS  FREE_ELTS    FREE_SZ ELT_SZ  ALLOC(ELTS  PGS  SLK)     FLAGS      NAME
209*aca3beaaSApple OSS Distributions    0x00000000d007c000      29808        182         25       3600    144   4096   28    1   64   X$          zones
210*aca3beaaSApple OSS Distributions    (lldb)
211*aca3beaaSApple OSS DistributionsJust printing the value of first_zone as (zone_t) 0xd007c000 wouldnt have been much help. But with the registered summary for zone_t we can see all the interesting info easily.
212*aca3beaaSApple OSS Distributions
213*aca3beaaSApple OSS DistributionsYou do not need to do anything special to use summaries. Once they are registered with lldb they show info automatically when printing objects. However if you wish to
214*aca3beaaSApple OSS Distributionssee all the registered type summaries run the command `type summary list -w kernel` on lldb prompt.
215*aca3beaaSApple OSS DistributionsAlso if you wish to quickly disable the summaries for a particular command use the `showraw` command.
216*aca3beaaSApple OSS Distributions
217*aca3beaaSApple OSS Distributionsii. Writing new summary functions
218*aca3beaaSApple OSS Distributions---------------------------------
219*aca3beaaSApple OSS Distributionslldb provides really flexible interface for building summaries for complex objects and data. If you find that a struct or list can be
220*aca3beaaSApple OSS Distributionsdiagnosed better if displayed differently, then feel free to add a type summary for that type. Following is an easy guide on how to do that.
221*aca3beaaSApple OSS Distributions
222*aca3beaaSApple OSS Distributions  1. Register a function as a callback for displaying information for a type. Use the `@lldb_type_summary()` decorator with an array of types you wish to register for callback
223*aca3beaaSApple OSS Distributions
224*aca3beaaSApple OSS Distributions  2. Provide a header for the summary using `@header()` decorator. This is a strong requirement for summaries. This gets displayed before the output
225*aca3beaaSApple OSS Distributions     of `GetTypeSummary()` is displayed. [In case you do not wish to have header then still define it as "" (empty string) ]
226*aca3beaaSApple OSS Distributions
227*aca3beaaSApple OSS Distributions  3. Define the function with signature of `GetSomeTypeSummary(valobj)`. It is highly recommended that the naming be consistent to `Get.*?Summary(valobj)`
228*aca3beaaSApple OSS Distributions     The valobj argument holds the core.value object for display.
229*aca3beaaSApple OSS Distributions
230*aca3beaaSApple OSS Distributions  4. Use the utility functions and memory read operations to pull out the required information.
231*aca3beaaSApple OSS Distributions     [ use `kern.globals` & `kern.GetValueFromAddress` for building args to core functions. ]
232*aca3beaaSApple OSS Distributions     [ remember that the ideal type of object to be passed around is core.value ]
233*aca3beaaSApple OSS Distributions
234*aca3beaaSApple OSS Distributions  5. return a string that would be printed by the caller. When lldb makes a call back it expects a str to be returned. So do not print
235*aca3beaaSApple OSS Distributions     directly out to console. [ debug info or logs output is okay to be printed anywhere :) ]
236*aca3beaaSApple OSS Distributions
237*aca3beaaSApple OSS DistributionsTime for some code example? Try reading the code for GetTaskSummary() in process.py.
238*aca3beaaSApple OSS Distributions
239*aca3beaaSApple OSS Distributions
240*aca3beaaSApple OSS Distributions
241*aca3beaaSApple OSS DistributionsE. FAQs and Generel Coding Guidelines
242*aca3beaaSApple OSS Distributions======================================
243*aca3beaaSApple OSS Distributions
244*aca3beaaSApple OSS Distributionsi. Frequently Asked Questions
245*aca3beaaSApple OSS Distributions-----------------------------
246*aca3beaaSApple OSS Distributions
247*aca3beaaSApple OSS Distributions  Q. How do I avoid printing the summary and see the actual data in a structure?
248*aca3beaaSApple OSS Distributions
249*aca3beaaSApple OSS Distributions  A. There is a command called `showraw`. This will disable all kernel specific type summaries and execute any command you provide. For ex.
250*aca3beaaSApple OSS Distributions
251*aca3beaaSApple OSS Distributions    (lldb) print (thread_t) 0x80d6a620
252*aca3beaaSApple OSS Distributions    (thread_t) $45 = 0x80d6a620
253*aca3beaaSApple OSS Distributions    thread                   thread_id  processor            pri    io_policy  state wait_queue           wait_event           wmesg                thread_name
254*aca3beaaSApple OSS Distributions    0x80d6a620               0x317      0x902078c8           61                W     0x910cadd4           0x0                                       SystemSoundServer
255*aca3beaaSApple OSS Distributions    (lldb) showraw print (thread_t) 0x80d6a620
256*aca3beaaSApple OSS Distributions    (thread_t) $48 = 0x80d6a620
257*aca3beaaSApple OSS Distributions
258*aca3beaaSApple OSS Distributions  Q. I typed `showallvnodes` and nothing happens for a long time? OR How do I get output of long running command instantly on the terminal?
259*aca3beaaSApple OSS Distributions
260*aca3beaaSApple OSS Distributions  A. The lldb command interface tries to build result object from output of a python function. So in case of functions with very long output or runtime it may
261*aca3beaaSApple OSS Distributions     seem that the lldb process is hung. But it is not. You can use "-i" option to get immediate output on terminal.
262*aca3beaaSApple OSS Distributions
263*aca3beaaSApple OSS Distributions        ex. (lldb) showallvnodes -- -i
264*aca3beaaSApple OSS Distributions         Immediate Output
265*aca3beaaSApple OSS Distributions         ....
266*aca3beaaSApple OSS Distributions
267*aca3beaaSApple OSS Distributions  Q. I made a change in a python file for a command or summary, but the output is not reflected in the lldb command?
268*aca3beaaSApple OSS Distributions
269*aca3beaaSApple OSS Distributions  A. The python framework does not allow for removing a loaded module and then reloading it. So sometimes if a command has a cached value from
270*aca3beaaSApple OSS Distributions     old code that it will still call the old function and hence will not display new changes in file on disk. If you find yourself in such a situation
271*aca3beaaSApple OSS Distributions     please see [Section C. -> SPECIAL Note]. If the change is to basic class or caching mechanism than it is advised to quit lldb and re-load all modules again.
272*aca3beaaSApple OSS Distributions
273*aca3beaaSApple OSS Distributions  Q. I am new to python. I get an error message that I do not understand. what should I do?
274*aca3beaaSApple OSS Distributions
275*aca3beaaSApple OSS Distributions  A. The syntax for python is different from conventional programming languages. If you get any message with SyntaxError or TypeError or ValueError then please review your code and look for common errors like
276*aca3beaaSApple OSS Distributions
277*aca3beaaSApple OSS Distributions  - wrong level of indentation?
278*aca3beaaSApple OSS Distributions  - missed a ':' at the end of an if, elif, for, while statement?
279*aca3beaaSApple OSS Distributions  - referencing a key in dictionary that doesn't exist? You might see KeyError in such cases.
280*aca3beaaSApple OSS Distributions  - mistakenly used python reserved keyword as variable? (check http://docs.python.org/release/3.0.1/reference/lexical_analysis.html#id8)
281*aca3beaaSApple OSS Distributions  - Trying to modify a string value? You can only create new strings but never modify existing ones.
282*aca3beaaSApple OSS Distributions  - Trying to add a non string value to a string? This typically happens in print "time is " + gettime(). here gettime() returns int and not str.
283*aca3beaaSApple OSS Distributions  - using a local variable with same name as global variable?
284*aca3beaaSApple OSS Distributions  - assigning a value to global variable without declaring first? Its highly recommended to always declare global variable with 'global' keyword
285*aca3beaaSApple OSS Distributions  If you still have difficulty you can look at the python documentation at http://docs.python.org
286*aca3beaaSApple OSS Distributions
287*aca3beaaSApple OSS Distributions
288*aca3beaaSApple OSS Distributions  Q. I wish to pass value of variable/expression to xnu lldb macro that accepts only pointers. How can I achieve that?
289*aca3beaaSApple OSS Distributions
290*aca3beaaSApple OSS Distributions  A. Many lldb macros have syntax that accepts pointers (eg showtaskstacks etc). In order to have your expression be evaluated before passing to command use `back ticks`. For example:
291*aca3beaaSApple OSS Distributions
292*aca3beaaSApple OSS Distributions        (lldb) showtaskstacks  `(task_t)tasks.next`
293*aca3beaaSApple OSS Distributions        This way the expressing withing ` ` is evaluated by lldb and the value is passed to the command.
294*aca3beaaSApple OSS Distributions        Note that if your argument pointer is bad or the memory is corrupted lldb macros will fail with a long backtrace that may not make sense. gdb used to fail silently but lldb does not.
295*aca3beaaSApple OSS Distributions        Please see Section F(i) for more information on reading backtraces.
296*aca3beaaSApple OSS Distributions
297*aca3beaaSApple OSS Distributions  Q. I connected to a coredump file with lldb --core corefile and I got RuntimeError: Unable to find lldb thread for tid=XYZ. What should I do?
298*aca3beaaSApple OSS Distributions
299*aca3beaaSApple OSS Distributions  A. This is most likely the case that lldb ignored the operating system plugin in the dSYM and hence threads are not populated. Please put the line 'settings set target.load-script-from-symbol-file true' in your ~/.lldbinit file. If you do not have access you can alternatively do
300*aca3beaaSApple OSS Distributions
301*aca3beaaSApple OSS Distributions        bash# lldb
302*aca3beaaSApple OSS Distributions        (lldb) settings set target.load-script-from-symbol-file true
303*aca3beaaSApple OSS Distributions        (lldb) file --core corefile
304*aca3beaaSApple OSS Distributions
305*aca3beaaSApple OSS Distributions
306*aca3beaaSApple OSS Distributionsii. Formatted output printing - zen and peace for life
307*aca3beaaSApple OSS Distributions------------------------------------------------------
308*aca3beaaSApple OSS Distributions
309*aca3beaaSApple OSS DistributionsTo avoid the horrors of printing a tabular data on console and then 2 weeks later again messing with it for a new field, it is recommended to follow these guidelines.
310*aca3beaaSApple OSS Distributions
311*aca3beaaSApple OSS Distributions  * any python string can be invoked to "".format() and hence makes it very easy to play with formats
312*aca3beaaSApple OSS Distributions
313*aca3beaaSApple OSS Distributions  * As a convention, I suggest that for printing pointer values in hex use "{0: <#020x}".format(some_int_value). This will print nice 0x prefixed strings with length padded to 20.
314*aca3beaaSApple OSS Distributions
315*aca3beaaSApple OSS Distributions  * If you need help with format options take a look at http://docs.python.org/library/string.html#format-string-syntax
316*aca3beaaSApple OSS Distributions
317*aca3beaaSApple OSS Distributions  * [ I'd first create a format string for data and then for the header just change the x's and d's to s and pass the header strings to format command. see GetTaskSummary()]
318*aca3beaaSApple OSS Distributions
319*aca3beaaSApple OSS Distributions  * If you need to print a string from a core.value object then use str() to get string representation of value.
320*aca3beaaSApple OSS Distributions
321*aca3beaaSApple OSS Distributions
322*aca3beaaSApple OSS Distributionsiii. Coding conventions
323*aca3beaaSApple OSS Distributions-----------------------
324*aca3beaaSApple OSS DistributionsIt is very very HIGHLY RECOMMENDED to follow these guidelines for writing any python code.
325*aca3beaaSApple OSS Distributions
326*aca3beaaSApple OSS Distributions * Python is very sensitive to tabs and spaces for alignment. So please make sure you **INDENT YOUR CODE WITH SPACES** at all times.
327*aca3beaaSApple OSS Distributions
328*aca3beaaSApple OSS Distributions * The standard tab width is 4 spaces. Each increasing indent adds 4 spaces beginning of the line.
329*aca3beaaSApple OSS Distributions
330*aca3beaaSApple OSS Distributions * The format for documentation is -
331*aca3beaaSApple OSS Distributions        """ A one line summary describing what this function / class does
332*aca3beaaSApple OSS Distributions            Detailed explanation if necessary along with params and return values.
333*aca3beaaSApple OSS Distributions        """
334*aca3beaaSApple OSS Distributions
335*aca3beaaSApple OSS Distributions * All Classes and functions should have a doc string describing what the function does
336*aca3beaaSApple OSS Distributions   A consistent format is expected. For ex.
337*aca3beaaSApple OSS Distributions    def SumOfNumbers(a, b, c, d):
338*aca3beaaSApple OSS Distributions        """ Calculate sum of numbers.
339*aca3beaaSApple OSS Distributions            params:
340*aca3beaaSApple OSS Distributions                a - int, value to be added. can be 0
341*aca3beaaSApple OSS Distributions                b - int/float, value to be added.
342*aca3beaaSApple OSS Distributions            returns:
343*aca3beaaSApple OSS Distributions                int/float - Sum of two values
344*aca3beaaSApple OSS Distributions            raises:
345*aca3beaaSApple OSS Distributions                TypeError - If any type is not identified in the params
346*aca3beaaSApple OSS Distributions        """
347*aca3beaaSApple OSS Distributions
348*aca3beaaSApple OSS Distributions * A Class or Function should always start with CAPITAL letter and be CamelCase. If a function is for internal use only than it starts with '_'.
349*aca3beaaSApple OSS Distributions
350*aca3beaaSApple OSS Distributions * Function params should always be lower_case and be word separated with '_'
351*aca3beaaSApple OSS Distributions
352*aca3beaaSApple OSS Distributions * A local variable inside a function should be lower_case and separated with '_'
353*aca3beaaSApple OSS Distributions
354*aca3beaaSApple OSS Distributions * A variable for internal use in object should start with '_'.
355*aca3beaaSApple OSS Distributions
356*aca3beaaSApple OSS Distributions * if a class variable is supposed to hold non native type of object, it is good idea to comment what type it holds
357*aca3beaaSApple OSS Distributions
358*aca3beaaSApple OSS Distributions * A class function with name matching `Get(.*?)Summary()` is always supposed to return a string which can be printed on stdout or any file.
359*aca3beaaSApple OSS Distributions
360*aca3beaaSApple OSS Distributions * Functions beginning with "Get" (eg. GetVnodePath())  mean they return a value and will not print any output to stdout.
361*aca3beaaSApple OSS Distributions
362*aca3beaaSApple OSS Distributions * Functions beginning with "Show"  (eg. ShowZTrace()) mean they will print data on screen and may not return any value.
363*aca3beaaSApple OSS Distributions
364*aca3beaaSApple OSS Distributions
365*aca3beaaSApple OSS Distributionsiv. Submitting changes in lldbmacros
366*aca3beaaSApple OSS Distributions------------------------------------
367*aca3beaaSApple OSS Distributions
368*aca3beaaSApple OSS DistributionsTo contribute new commands or fixes to existing one, it is recommended that you follow the procedure below.
369*aca3beaaSApple OSS Distributions
370*aca3beaaSApple OSS Distributions  * Save the changes requried for new command or fix into lldbmacros directory.
371*aca3beaaSApple OSS Distributions
372*aca3beaaSApple OSS Distributions  * Make sure that the coding conventions are strictly followed.
373*aca3beaaSApple OSS Distributions
374*aca3beaaSApple OSS Distributions  * Run syntax checker on each of the modified files. It will find basic formatting errors in the changed files for you.
375*aca3beaaSApple OSS Distributions
376*aca3beaaSApple OSS Distributions  * If you are adding new file then please update the Makefile and xnu.py imports to ensure they get compiled during kernel build.
377*aca3beaaSApple OSS Distributions
378*aca3beaaSApple OSS Distributions  * Do a clean build of kernel from xnu top level directory.
379*aca3beaaSApple OSS Distributions
380*aca3beaaSApple OSS Distributions  * Verify that your changes are present in the dSYM directory of new build.
381*aca3beaaSApple OSS Distributions
382*aca3beaaSApple OSS Distributions  * Re-run all your test and verification steps with the lldbmacros from the newly packaged dSYM/Contents/Resources/Python/lldbmacros.
383*aca3beaaSApple OSS Distributions
384*aca3beaaSApple OSS Distributionsv. Common utility functions and paradigms
385*aca3beaaSApple OSS Distributions-----------------------------------------
386*aca3beaaSApple OSS DistributionsPlease search and look around the code for common util functions and paradigm
387*aca3beaaSApple OSS Distributions
388*aca3beaaSApple OSS Distributions  * Take a peek at utils.py for common utility like sizeof_fmt() to humanize size strings in KB, MB etc. The convention is to have functions that do self contained actions and does not require intricate knowledge of kernel structures in utils.py
389*aca3beaaSApple OSS Distributions
390*aca3beaaSApple OSS Distributions  * If you need to get pagesize of the traget system, do not hard code any value. kern.globals.page_size is your friend. Similarly use config['verbosity'] for finding about configs.
391*aca3beaaSApple OSS Distributions
392*aca3beaaSApple OSS Distributions  * If you are developing a command for structure that is different based on development/release kernels please use "hasattr()" functionality to conditionalize referencing #ifdef'ed fields in structure. See example in def GetTaskSummary(task) in process.py
393*aca3beaaSApple OSS Distributions
394*aca3beaaSApple OSS Distributions
395*aca3beaaSApple OSS DistributionsF. Development and Debugging on lldb kernel debugging platform.
396*aca3beaaSApple OSS Distributions===============================================================
397*aca3beaaSApple OSS Distributions
398*aca3beaaSApple OSS Distributionsi. Reading a exception backtrace
399*aca3beaaSApple OSS Distributions--------------------------------
400*aca3beaaSApple OSS DistributionsIn case of an error the lldbmacros may print out an exception backtrace and halt immediately. The important thing is to
401*aca3beaaSApple OSS Distributionsisolate possible causes of failure, and eventually filing a bug with kernel team. Following are some common ways where
402*aca3beaaSApple OSS Distributionsyou may see an exception instead of your expected result.
403*aca3beaaSApple OSS Distributions
404*aca3beaaSApple OSS Distributions  * The lldbmacros cannot divine the type of memory by inspection. If a wrong pointer is passed from commandline then,
405*aca3beaaSApple OSS Distributions    the command code will try to read and show some results. It may still be junk or plain erronous. Please make sure
406*aca3beaaSApple OSS Distributions	your command arguments are correct. For example: a common mistake is to pass task address to showactstack. In such
407*aca3beaaSApple OSS Distributions	a case lldb command may fail and show you a confusing backtrace.
408*aca3beaaSApple OSS Distributions
409*aca3beaaSApple OSS Distributions  * Kernel debugging is particularly tricky. Many parts of memory may not be readable. There could be failure in network,
410*aca3beaaSApple OSS Distributions    debugging protocol or just plain bad memory. In such a case please try to see if you can examine memory for the object
411*aca3beaaSApple OSS Distributions	you are trying to access.
412*aca3beaaSApple OSS Distributions
413*aca3beaaSApple OSS Distributions  * In case of memory corruption, the lldbmacros may have followed wrong pointer dereferencing. This might lead to failure
414*aca3beaaSApple OSS Distributions    and a exception to be thrown.
415*aca3beaaSApple OSS Distributions
416*aca3beaaSApple OSS DistributionsThere are few more options that you can use when a macro is raising exceptions:
417*aca3beaaSApple OSS Distributions
418*aca3beaaSApple OSS Distributions  * Add --debug to your macro invocation to provide more detailed/verbose exception output.
419*aca3beaaSApple OSS Distributions  * Add --radar to generate tar.gz archive when filling a new radar for kernel team.
420*aca3beaaSApple OSS Distributions  * Add --pdb to attach pdb to exception stack for debugging.
421*aca3beaaSApple OSS Distributions
422*aca3beaaSApple OSS Distributionsii. Loading custom or local lldbmacros and operating_system plugin
423*aca3beaaSApple OSS Distributions------------------------------------------------------------------
424*aca3beaaSApple OSS Distributions
425*aca3beaaSApple OSS DistributionsThe lldbmacros are packaged right into the dSYM for the kernel executable. This makes debugging very easy since they can get loaded automatically when symbols are loaded.
426*aca3beaaSApple OSS DistributionsHowever, this setup makes it difficult for a lldbmacro developer to load custom/local macros. Following is the suggested solution for customizing your debugging setup:
427*aca3beaaSApple OSS Distributions
428*aca3beaaSApple OSS Distributions  * set up environment variable DEBUG_XNU_LLDBMACROS=1 on your shell. This will disable the automatic setup of lldbmacros and the operating_system.py from the symbols.
429*aca3beaaSApple OSS Distributions     - bash$ export DEBUG_XNU_LLDBMACROS=1
430*aca3beaaSApple OSS Distributions
431*aca3beaaSApple OSS Distributions  * start lldb from the shell
432*aca3beaaSApple OSS Distributions     - bash$ lldb
433*aca3beaaSApple OSS Distributions
434*aca3beaaSApple OSS Distributions  * [optional] If you are making changes in the operating_system plugin then you need to set the plugin path for lldb to find your custom operating_system plugin file.
435*aca3beaaSApple OSS Distributions     - (lldb)settings set target.process.python-os-plugin-path /path/to/xnu/tools/lldbmacros/core/operating_system.py
436*aca3beaaSApple OSS Distributions     If you do not wish to change anything in operating_system plugin then just leave the setting empty. The symbol loading module will set one up for you.
437*aca3beaaSApple OSS Distributions
438*aca3beaaSApple OSS Distributions  * Load the xnu debug macros from your custom location.
439*aca3beaaSApple OSS Distributions     - (lldb)command script import /path/to/xnu/tools/lldbmacros/xnu.py
440*aca3beaaSApple OSS Distributions
441*aca3beaaSApple OSS Distributions
442*aca3beaaSApple OSS Distributionsiii. Adding debug related 'printf's
443*aca3beaaSApple OSS Distributions-----------------------------------
444*aca3beaaSApple OSS Distributions
445*aca3beaaSApple OSS DistributionsThe xnu debug framework provides a utility function (debuglog) in utils.py. Please use this for any of your debugging needs. It will not print any output unless the user turns on debug logging on the command. Please check the documentaiton of debuglog for usage and options.
446*aca3beaaSApple OSS Distributions
447*aca3beaaSApple OSS Distributions  * To enable/disable logging
448*aca3beaaSApple OSS Distributions     - (lldb) xnudebug debug
449*aca3beaaSApple OSS Distributions       Enabled debug logging.
450*aca3beaaSApple OSS Distributions
451*aca3beaaSApple OSS Distributions
452