1*2c2f96dcSApple OSS DistributionsTable of Contents 2*2c2f96dcSApple OSS Distributions================= 3*2c2f96dcSApple OSS Distributions 4*2c2f96dcSApple OSS Distributions A. How to use lldb for kernel debugging 5*2c2f96dcSApple OSS Distributions B. Design of lldb kernel debugging platform. 6*2c2f96dcSApple OSS Distributions C. Kernel debugging commands. 7*2c2f96dcSApple OSS Distributions i. Using commands. 8*2c2f96dcSApple OSS Distributions ii. Writing new commands. 9*2c2f96dcSApple OSS Distributions D. Kernel type summaries. 10*2c2f96dcSApple OSS Distributions i. Using summaries 11*2c2f96dcSApple OSS Distributions ii. Writing new summary functions 12*2c2f96dcSApple OSS Distributions E. FAQ and General Coding Guidelines 13*2c2f96dcSApple OSS Distributions i. Frequently Asked Questions 14*2c2f96dcSApple OSS Distributions ii. Formatted Output printing guidelines [MUST READ] 15*2c2f96dcSApple OSS Distributions iii. Coding conventions. [MUST READ] 16*2c2f96dcSApple OSS Distributions iv. Submitting changes in lldbmacros [MUST READ] 17*2c2f96dcSApple OSS Distributions v. Common utility functions and paradigms 18*2c2f96dcSApple OSS Distributions F. Development and Debugging on lldb kernel debugging platform. 19*2c2f96dcSApple OSS Distributions i. Reading a exception backtrace 20*2c2f96dcSApple OSS Distributions ii. Loading custom or local lldbmacros and operating_system plugin 21*2c2f96dcSApple OSS Distributions iii. Adding debug related 'printf's 22*2c2f96dcSApple OSS Distributions 23*2c2f96dcSApple OSS DistributionsA. How to use lldb for kernel debugging 24*2c2f96dcSApple OSS Distributions======================================== 25*2c2f96dcSApple OSS Distributions 26*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 28*2c2f96dcSApple OSS Distributions File: ~/.lldbinit 29*2c2f96dcSApple OSS Distributions settings set target.load-script-from-symbol-file true 30*2c2f96dcSApple OSS Distributions 31*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 33*2c2f96dcSApple OSS DistributionsFollowing are detailed steps on how to debug a panic'ed / NMI'ed machine (For the curious souls). 34*2c2f96dcSApple OSS Distributions 35*2c2f96dcSApple OSS Distributionslldb debugging in detail:- 36*2c2f96dcSApple OSS Distributions 37*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions bash$ dsymForUUID --enable 39*2c2f96dcSApple OSS Distributions bash$ lldb /path/to/mach_kernel.symbols 40*2c2f96dcSApple OSS Distributions Current executable set to '/Sources/Symbols/xnu/xnu-2253~2/mach_kernel' (x86_64). 41*2c2f96dcSApple OSS Distributions (lldb) 42*2c2f96dcSApple OSS Distributions 43*2c2f96dcSApple OSS Distributions * connect to remote device or load a core file 44*2c2f96dcSApple OSS Distributions #for kdp 45*2c2f96dcSApple OSS Distributions (lldb) process connect --plugin kdp-remote udp://17.123.45.67:41139 46*2c2f96dcSApple OSS Distributions #for gdb (eg with astris) 47*2c2f96dcSApple OSS Distributions (lldb) process connect --plugin gdb-remote gdb://17.123.45.67:8000 48*2c2f96dcSApple OSS Distributions #for loading a core file 49*2c2f96dcSApple OSS Distributions (lldb) file --core /path/to/core/file /path/to/kernel_symbol_file 50*2c2f96dcSApple OSS Distributions 51*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions In case if you are working with older kernel files you can load kernel specific commands by doing - 53*2c2f96dcSApple OSS Distributions (lldb) command script import /path/to/xnu/tools/lldbmacros/xnu.py 54*2c2f96dcSApple OSS Distributions (lldb) showbootargs 55*2c2f96dcSApple OSS Distributions debug=0x14e ncpus=2 56*2c2f96dcSApple OSS Distributions 57*2c2f96dcSApple OSS Distributions * You can do `kgmhelp` to get a list of commands available through xnu.py 58*2c2f96dcSApple OSS Distributions 59*2c2f96dcSApple OSS DistributionsSPECIAL: The `xnu.py` script brings in kernel type summary functions. To enable these please do - 60*2c2f96dcSApple OSS Distributions 61*2c2f96dcSApple OSS Distributions (lldb) showlldbtypesummaries 62*2c2f96dcSApple OSS Distributions 63*2c2f96dcSApple OSS DistributionsThese could be very handy in printing important information from structures easily. 64*2c2f96dcSApple OSS DistributionsFor ex. 65*2c2f96dcSApple OSS Distributions 66*2c2f96dcSApple OSS Distributions (lldb) print (thread_t)0x80d6a620 67*2c2f96dcSApple OSS Distributions (thread_t) $45 = 0x80d6a620 68*2c2f96dcSApple OSS Distributions thread thread_id processor pri io_policy state wait_queue wait_event wmesg thread_name 69*2c2f96dcSApple OSS Distributions 0x80d6a620 0x317 0x902078c8 61 W 0x910cadd4 0x0 SystemSoundServer 70*2c2f96dcSApple OSS Distributions 71*2c2f96dcSApple OSS Distributions 72*2c2f96dcSApple OSS Distributions 73*2c2f96dcSApple OSS DistributionsB. Design of lldb kernel debugging platform. 74*2c2f96dcSApple OSS Distributions============================================= 75*2c2f96dcSApple OSS Distributions 76*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 78*2c2f96dcSApple OSS Distributions |------- xnu scripts ----------| 79*2c2f96dcSApple OSS Distributions | |- lldb Command/Scripting-| | <-- provides scriptability for kernel data structures through summary/command invocation. 80*2c2f96dcSApple OSS Distributions | | |--lldb core--| | | <-- interacts with remote kernel or corefile. 81*2c2f96dcSApple OSS Distributions | |-------------------------| | 82*2c2f96dcSApple OSS Distributions |------------------------------| 83*2c2f96dcSApple OSS Distributions 84*2c2f96dcSApple OSS DistributionsThe xnu script in xnu/tools/lldbmacros provides the following: 85*2c2f96dcSApple OSS Distributions 86*2c2f96dcSApple OSS Distributions * Custom functions to do plumbing of lldb command invocation to python function call. (see doc strings for @lldb_command) 87*2c2f96dcSApple OSS Distributions The command interface provides some common features (which can be invoked after passing '--' on cmd line) like - 88*2c2f96dcSApple OSS Distributions 89*2c2f96dcSApple OSS Distributions i. send the output of command to file on disk 90*2c2f96dcSApple OSS Distributions ii. search for a string in the output and selectively print the line containing it. 91*2c2f96dcSApple OSS Distributions iii. -v options to increase verbosity levels in commands. 92*2c2f96dcSApple OSS Distributions For example: (lldb)showalltasks -- -s kernel_task --o /tmp/kernel_task.output -v 93*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 95*2c2f96dcSApple OSS Distributions * Customization for plugging in summary functions for lldb type summaries. (see doc strings for @lldb_summary) 96*2c2f96dcSApple OSS Distributions It will automatically register given types with the functions within the kernel category. 97*2c2f96dcSApple OSS Distributions 98*2c2f96dcSApple OSS Distributions * Ability to register test cases for macros (see doc strings for @xnudebug_test). 99*2c2f96dcSApple OSS Distributions 100*2c2f96dcSApple OSS DistributionsThe file layout is like following 101*2c2f96dcSApple OSS Distributions 102*2c2f96dcSApple OSS Distributions xnu/ 103*2c2f96dcSApple OSS Distributions |-tools/ 104*2c2f96dcSApple OSS Distributions |-lldbmacros/ 105*2c2f96dcSApple OSS Distributions |-core/ # Core logic about kernel, lldb value abstraction, configs etc. **DO NOT TOUCH THIS DIR** 106*2c2f96dcSApple OSS Distributions |-plugins/ # Holds plugins for kernel commands. 107*2c2f96dcSApple OSS Distributions |-xnu.py # xnu debug framework along with kgmhelp, xnudebug commands. 108*2c2f96dcSApple OSS Distributions |-xnudefines.py 109*2c2f96dcSApple OSS Distributions |-utils.py 110*2c2f96dcSApple OSS Distributions |-process.py # files containing commands/summaries code for each subsystem 111*2c2f96dcSApple OSS Distributions |-... 112*2c2f96dcSApple OSS Distributions 113*2c2f96dcSApple OSS Distributions 114*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 116*2c2f96dcSApple OSS Distributions 117*2c2f96dcSApple OSS DistributionsC. Kernel debugging commands. 118*2c2f96dcSApple OSS Distributions============================== 119*2c2f96dcSApple OSS Distributionsi. Using commands. 120*2c2f96dcSApple OSS Distributions------------------ 121*2c2f96dcSApple OSS DistributionsUsing xnu debug commands is very similar to kgmacros in gdb. You can use 'kgmhelp' to get a listing of available commands. 122*2c2f96dcSApple OSS DistributionsIf you need detailed help for a command please type 'help <command name>' and the documentation for the command will be displayed. 123*2c2f96dcSApple OSS DistributionsFor ex. 124*2c2f96dcSApple OSS Distributions 125*2c2f96dcSApple OSS Distributions (lldb) help pmap_walk 126*2c2f96dcSApple OSS Distributions Perform a page-table walk in <pmap> for <virtual_address>. 127*2c2f96dcSApple OSS Distributions You can pass -- -v for verbose output. To increase the verbosity add more -v args after the '--'. 128*2c2f96dcSApple OSS Distributions Syntax: pmap_walk <pmap> <virtual_address> 129*2c2f96dcSApple OSS Distributions 130*2c2f96dcSApple OSS DistributionsThe basic format for every command provided under kgmhelp is like follows 131*2c2f96dcSApple OSS Distributions 132*2c2f96dcSApple OSS Distributions (lldb) command_name [cmd_args..] [-CMDOPTIONS] [-xnuoptions] 133*2c2f96dcSApple OSS Distributions where: 134*2c2f96dcSApple OSS Distributions command_name : name of command as registed using the @lldb_command decorator and described in 'kgmhelp' 135*2c2f96dcSApple OSS Distributions cmd_args : shell like arguments that are passed as is to the registered python function. 136*2c2f96dcSApple OSS Distributions If there is error in these arguments than the implementor may display according error message. 137*2c2f96dcSApple OSS Distributions xnuoptions : common options for stream based operations on the output of command_name. 138*2c2f96dcSApple OSS Distributions Allowed options are 139*2c2f96dcSApple OSS Distributions -h : show help string of a command 140*2c2f96dcSApple OSS Distributions -s <regexp> : print only the lines matching <regexp> 141*2c2f96dcSApple OSS Distributions -o <file> : direct the output of command to <file>. Will not display anything on terminal 142*2c2f96dcSApple OSS Distributions -v : increase the verbosity of the command. Each '-v' encountered will increase verbosity by 1. 143*2c2f96dcSApple OSS Distributions -p <plugin> : pass the output of command to <plugin> for processing and followup with command requests by it. 144*2c2f96dcSApple OSS Distributions CMDOPTIONS : These are command level options (always a CAPITAL letter option) that are defined by the macro developer. Please do 145*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 147*2c2f96dcSApple OSS Distributionsii. Writing new commands. 148*2c2f96dcSApple OSS Distributions-------------------------- 149*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 151*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 153*2c2f96dcSApple OSS Distributions (lldb)showtask 0xabcdef000 is same as python >>> GetTaskSummary(0xabcdef000) or equivalent 154*2c2f96dcSApple OSS Distributions 155*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 157*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 159*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 161*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 163*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions - note that we use core.value class as an interface to underlying C structures. Refer [Section B] for more details. 165*2c2f96dcSApple OSS Distributions - use kern.globals.\<variable_name> & kern.GetValueFromAddress for building values from addresses. 166*2c2f96dcSApple OSS Distributions - remember that the ideal type of object to be passed around is core.value 167*2c2f96dcSApple OSS Distributions - Anything you 'print' will be relayed to lldb terminal output. 168*2c2f96dcSApple OSS Distributions 169*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 171*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 173*2c2f96dcSApple OSS Distributions 7. Please use "##" for commenting your code. This is important because single "#" based strings may be mistakenly considered in `unifdef` program. 174*2c2f96dcSApple OSS Distributions 175*2c2f96dcSApple OSS Distributions Time for some code example? Try reading the code for function ShowTaskVmeHelper in memory.py. 176*2c2f96dcSApple OSS Distributions 177*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 179*2c2f96dcSApple OSS DistributionsTo easily reload your changes in lldb please follow the below example. 180*2c2f96dcSApple OSS Distributions 181*2c2f96dcSApple OSS Distributions * you fire up lldb and start using zprint. And soon you need to add functionality to zprint. 182*2c2f96dcSApple OSS Distributions 183*2c2f96dcSApple OSS Distributions * you happily change a function code in memory.py file to zprint macro. 184*2c2f96dcSApple OSS Distributions 185*2c2f96dcSApple OSS Distributions * now to reload that particular changes without killing your debug session do 186*2c2f96dcSApple OSS Distributions (lldb) xnudebug reload memory 187*2c2f96dcSApple OSS Distributions memory is reloaded from ./memory.py 188*2c2f96dcSApple OSS Distributions (lldb) 189*2c2f96dcSApple OSS Distributions 190*2c2f96dcSApple OSS Distributions * Alternatively, you can use lldb`s command for script loading as 191*2c2f96dcSApple OSS Distributions (lldb) command script import /path/to/memory.py 192*2c2f96dcSApple OSS Distributions You can re-run the same command every time you update the code in file. 193*2c2f96dcSApple OSS Distributions 194*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions why your changes are not reflected in the command. 196*2c2f96dcSApple OSS Distributions 197*2c2f96dcSApple OSS Distributions 198*2c2f96dcSApple OSS DistributionsD. Kernel type summaries. 199*2c2f96dcSApple OSS Distributions========================== 200*2c2f96dcSApple OSS Distributionsi. Using summaries 201*2c2f96dcSApple OSS Distributions------------------ 202*2c2f96dcSApple 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*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributionsfor registered summaries. We can define python functions and hook it up with lldb as callbacks for type summaries. For example. 205*2c2f96dcSApple OSS Distributions 206*2c2f96dcSApple OSS Distributions (lldb) print first_zone 207*2c2f96dcSApple OSS Distributions (zone_t) $49 = 0xd007c000 208*2c2f96dcSApple OSS Distributions ZONE TOT_SZ ALLOC_ELTS FREE_ELTS FREE_SZ ELT_SZ ALLOC(ELTS PGS SLK) FLAGS NAME 209*2c2f96dcSApple OSS Distributions 0x00000000d007c000 29808 182 25 3600 144 4096 28 1 64 X$ zones 210*2c2f96dcSApple OSS Distributions (lldb) 211*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 213*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributionssee all the registered type summaries run the command `type summary list -w kernel` on lldb prompt. 215*2c2f96dcSApple OSS DistributionsAlso if you wish to quickly disable the summaries for a particular command use the `showraw` command. 216*2c2f96dcSApple OSS Distributions 217*2c2f96dcSApple OSS Distributionsii. Writing new summary functions 218*2c2f96dcSApple OSS Distributions--------------------------------- 219*2c2f96dcSApple 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*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 222*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 224*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions of `GetTypeSummary()` is displayed. [In case you do not wish to have header then still define it as "" (empty string) ] 226*2c2f96dcSApple OSS Distributions 227*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions The valobj argument holds the core.value object for display. 229*2c2f96dcSApple OSS Distributions 230*2c2f96dcSApple OSS Distributions 4. Use the utility functions and memory read operations to pull out the required information. 231*2c2f96dcSApple OSS Distributions [ use `kern.globals` & `kern.GetValueFromAddress` for building args to core functions. ] 232*2c2f96dcSApple OSS Distributions [ remember that the ideal type of object to be passed around is core.value ] 233*2c2f96dcSApple OSS Distributions 234*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions directly out to console. [ debug info or logs output is okay to be printed anywhere :) ] 236*2c2f96dcSApple OSS Distributions 237*2c2f96dcSApple OSS DistributionsTime for some code example? Try reading the code for GetTaskSummary() in process.py. 238*2c2f96dcSApple OSS Distributions 239*2c2f96dcSApple OSS Distributions 240*2c2f96dcSApple OSS Distributions 241*2c2f96dcSApple OSS DistributionsE. FAQs and Generel Coding Guidelines 242*2c2f96dcSApple OSS Distributions====================================== 243*2c2f96dcSApple OSS Distributions 244*2c2f96dcSApple OSS Distributionsi. Frequently Asked Questions 245*2c2f96dcSApple OSS Distributions----------------------------- 246*2c2f96dcSApple OSS Distributions 247*2c2f96dcSApple OSS Distributions Q. How do I avoid printing the summary and see the actual data in a structure? 248*2c2f96dcSApple OSS Distributions 249*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 251*2c2f96dcSApple OSS Distributions (lldb) print (thread_t) 0x80d6a620 252*2c2f96dcSApple OSS Distributions (thread_t) $45 = 0x80d6a620 253*2c2f96dcSApple OSS Distributions thread thread_id processor pri io_policy state wait_queue wait_event wmesg thread_name 254*2c2f96dcSApple OSS Distributions 0x80d6a620 0x317 0x902078c8 61 W 0x910cadd4 0x0 SystemSoundServer 255*2c2f96dcSApple OSS Distributions (lldb) showraw print (thread_t) 0x80d6a620 256*2c2f96dcSApple OSS Distributions (thread_t) $48 = 0x80d6a620 257*2c2f96dcSApple OSS Distributions 258*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 260*2c2f96dcSApple 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*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 263*2c2f96dcSApple OSS Distributions ex. (lldb) showallvnodes -- -i 264*2c2f96dcSApple OSS Distributions Immediate Output 265*2c2f96dcSApple OSS Distributions .... 266*2c2f96dcSApple OSS Distributions 267*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 269*2c2f96dcSApple 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*2c2f96dcSApple 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*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 273*2c2f96dcSApple OSS Distributions Q. I am new to python. I get an error message that I do not understand. what should I do? 274*2c2f96dcSApple OSS Distributions 275*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 277*2c2f96dcSApple OSS Distributions - wrong level of indentation? 278*2c2f96dcSApple OSS Distributions - missed a ':' at the end of an if, elif, for, while statement? 279*2c2f96dcSApple OSS Distributions - referencing a key in dictionary that doesn't exist? You might see KeyError in such cases. 280*2c2f96dcSApple OSS Distributions - mistakenly used python reserved keyword as variable? (check http://docs.python.org/release/3.0.1/reference/lexical_analysis.html#id8) 281*2c2f96dcSApple OSS Distributions - Trying to modify a string value? You can only create new strings but never modify existing ones. 282*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions - using a local variable with same name as global variable? 284*2c2f96dcSApple OSS Distributions - assigning a value to global variable without declaring first? Its highly recommended to always declare global variable with 'global' keyword 285*2c2f96dcSApple OSS Distributions If you still have difficulty you can look at the python documentation at http://docs.python.org 286*2c2f96dcSApple OSS Distributions 287*2c2f96dcSApple OSS Distributions 288*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 290*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 292*2c2f96dcSApple OSS Distributions (lldb) showtaskstacks `(task_t)tasks.next` 293*2c2f96dcSApple OSS Distributions This way the expressing withing ` ` is evaluated by lldb and the value is passed to the command. 294*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions Please see Section F(i) for more information on reading backtraces. 296*2c2f96dcSApple OSS Distributions 297*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 299*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 301*2c2f96dcSApple OSS Distributions bash# lldb 302*2c2f96dcSApple OSS Distributions (lldb) settings set target.load-script-from-symbol-file true 303*2c2f96dcSApple OSS Distributions (lldb) file --core corefile 304*2c2f96dcSApple OSS Distributions 305*2c2f96dcSApple OSS Distributions 306*2c2f96dcSApple OSS Distributionsii. Formatted output printing - zen and peace for life 307*2c2f96dcSApple OSS Distributions------------------------------------------------------ 308*2c2f96dcSApple OSS Distributions 309*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 311*2c2f96dcSApple OSS Distributions * any python string can be invoked to "".format() and hence makes it very easy to play with formats 312*2c2f96dcSApple OSS Distributions 313*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 315*2c2f96dcSApple OSS Distributions * If you need help with format options take a look at http://docs.python.org/library/string.html#format-string-syntax 316*2c2f96dcSApple OSS Distributions 317*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 319*2c2f96dcSApple OSS Distributions * If you need to print a string from a core.value object then use str() to get string representation of value. 320*2c2f96dcSApple OSS Distributions 321*2c2f96dcSApple OSS Distributions 322*2c2f96dcSApple OSS Distributionsiii. Coding conventions 323*2c2f96dcSApple OSS Distributions----------------------- 324*2c2f96dcSApple OSS DistributionsIt is very very HIGHLY RECOMMENDED to follow these guidelines for writing any python code. 325*2c2f96dcSApple OSS Distributions 326*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 328*2c2f96dcSApple OSS Distributions * The standard tab width is 4 spaces. Each increasing indent adds 4 spaces beginning of the line. 329*2c2f96dcSApple OSS Distributions 330*2c2f96dcSApple OSS Distributions * The format for documentation is - 331*2c2f96dcSApple OSS Distributions """ A one line summary describing what this function / class does 332*2c2f96dcSApple OSS Distributions Detailed explanation if necessary along with params and return values. 333*2c2f96dcSApple OSS Distributions """ 334*2c2f96dcSApple OSS Distributions 335*2c2f96dcSApple OSS Distributions * All Classes and functions should have a doc string describing what the function does 336*2c2f96dcSApple OSS Distributions A consistent format is expected. For ex. 337*2c2f96dcSApple OSS Distributions def SumOfNumbers(a, b, c, d): 338*2c2f96dcSApple OSS Distributions """ Calculate sum of numbers. 339*2c2f96dcSApple OSS Distributions params: 340*2c2f96dcSApple OSS Distributions a - int, value to be added. can be 0 341*2c2f96dcSApple OSS Distributions b - int/float, value to be added. 342*2c2f96dcSApple OSS Distributions returns: 343*2c2f96dcSApple OSS Distributions int/float - Sum of two values 344*2c2f96dcSApple OSS Distributions raises: 345*2c2f96dcSApple OSS Distributions TypeError - If any type is not identified in the params 346*2c2f96dcSApple OSS Distributions """ 347*2c2f96dcSApple OSS Distributions 348*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 350*2c2f96dcSApple OSS Distributions * Function params should always be lower_case and be word separated with '_' 351*2c2f96dcSApple OSS Distributions 352*2c2f96dcSApple OSS Distributions * A local variable inside a function should be lower_case and separated with '_' 353*2c2f96dcSApple OSS Distributions 354*2c2f96dcSApple OSS Distributions * A variable for internal use in object should start with '_'. 355*2c2f96dcSApple OSS Distributions 356*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 358*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 360*2c2f96dcSApple OSS Distributions * Functions beginning with "Get" (eg. GetVnodePath()) mean they return a value and will not print any output to stdout. 361*2c2f96dcSApple OSS Distributions 362*2c2f96dcSApple OSS Distributions * Functions beginning with "Show" (eg. ShowZTrace()) mean they will print data on screen and may not return any value. 363*2c2f96dcSApple OSS Distributions 364*2c2f96dcSApple OSS Distributions 365*2c2f96dcSApple OSS Distributionsiv. Submitting changes in lldbmacros 366*2c2f96dcSApple OSS Distributions------------------------------------ 367*2c2f96dcSApple OSS Distributions 368*2c2f96dcSApple OSS DistributionsTo contribute new commands or fixes to existing one, it is recommended that you follow the procedure below. 369*2c2f96dcSApple OSS Distributions 370*2c2f96dcSApple OSS Distributions * Save the changes requried for new command or fix into lldbmacros directory. 371*2c2f96dcSApple OSS Distributions 372*2c2f96dcSApple OSS Distributions * Make sure that the coding conventions are strictly followed. 373*2c2f96dcSApple OSS Distributions 374*2c2f96dcSApple OSS Distributions * Run syntax checker on each of the modified files. It will find basic formatting errors in the changed files for you. 375*2c2f96dcSApple OSS Distributions 376*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 378*2c2f96dcSApple OSS Distributions * Do a clean build of kernel from xnu top level directory. 379*2c2f96dcSApple OSS Distributions 380*2c2f96dcSApple OSS Distributions * Verify that your changes are present in the dSYM directory of new build. 381*2c2f96dcSApple OSS Distributions 382*2c2f96dcSApple OSS Distributions * Re-run all your test and verification steps with the lldbmacros from the newly packaged dSYM/Contents/Resources/Python/lldbmacros. 383*2c2f96dcSApple OSS Distributions 384*2c2f96dcSApple OSS Distributionsv. Common utility functions and paradigms 385*2c2f96dcSApple OSS Distributions----------------------------------------- 386*2c2f96dcSApple OSS DistributionsPlease search and look around the code for common util functions and paradigm 387*2c2f96dcSApple OSS Distributions 388*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 390*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 392*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 394*2c2f96dcSApple OSS Distributions 395*2c2f96dcSApple OSS DistributionsF. Development and Debugging on lldb kernel debugging platform. 396*2c2f96dcSApple OSS Distributions=============================================================== 397*2c2f96dcSApple OSS Distributions 398*2c2f96dcSApple OSS Distributionsi. Reading a exception backtrace 399*2c2f96dcSApple OSS Distributions-------------------------------- 400*2c2f96dcSApple OSS DistributionsIn case of an error the lldbmacros may print out an exception backtrace and halt immediately. The important thing is to 401*2c2f96dcSApple OSS Distributionsisolate possible causes of failure, and eventually filing a bug with kernel team. Following are some common ways where 402*2c2f96dcSApple OSS Distributionsyou may see an exception instead of your expected result. 403*2c2f96dcSApple OSS Distributions 404*2c2f96dcSApple OSS Distributions * The lldbmacros cannot divine the type of memory by inspection. If a wrong pointer is passed from commandline then, 405*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions your command arguments are correct. For example: a common mistake is to pass task address to showactstack. In such 407*2c2f96dcSApple OSS Distributions a case lldb command may fail and show you a confusing backtrace. 408*2c2f96dcSApple OSS Distributions 409*2c2f96dcSApple OSS Distributions * Kernel debugging is particularly tricky. Many parts of memory may not be readable. There could be failure in network, 410*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions you are trying to access. 412*2c2f96dcSApple OSS Distributions 413*2c2f96dcSApple OSS Distributions * In case of memory corruption, the lldbmacros may have followed wrong pointer dereferencing. This might lead to failure 414*2c2f96dcSApple OSS Distributions and a exception to be thrown. 415*2c2f96dcSApple OSS Distributions 416*2c2f96dcSApple OSS DistributionsThere are few more options that you can use when a macro is raising exceptions: 417*2c2f96dcSApple OSS Distributions 418*2c2f96dcSApple OSS Distributions * Add --debug to your macro invocation to provide more detailed/verbose exception output. 419*2c2f96dcSApple OSS Distributions * Add --radar to generate tar.gz archive when filling a new radar for kernel team. 420*2c2f96dcSApple OSS Distributions * Add --pdb to attach pdb to exception stack for debugging. 421*2c2f96dcSApple OSS Distributions 422*2c2f96dcSApple OSS Distributionsii. Loading custom or local lldbmacros and operating_system plugin 423*2c2f96dcSApple OSS Distributions------------------------------------------------------------------ 424*2c2f96dcSApple OSS Distributions 425*2c2f96dcSApple 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*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 428*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions - bash$ export DEBUG_XNU_LLDBMACROS=1 430*2c2f96dcSApple OSS Distributions 431*2c2f96dcSApple OSS Distributions * start lldb from the shell 432*2c2f96dcSApple OSS Distributions - bash$ lldb 433*2c2f96dcSApple OSS Distributions 434*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions - (lldb)settings set target.process.python-os-plugin-path /path/to/xnu/tools/lldbmacros/core/operating_system.py 436*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 438*2c2f96dcSApple OSS Distributions * Load the xnu debug macros from your custom location. 439*2c2f96dcSApple OSS Distributions - (lldb)command script import /path/to/xnu/tools/lldbmacros/xnu.py 440*2c2f96dcSApple OSS Distributions 441*2c2f96dcSApple OSS Distributions 442*2c2f96dcSApple OSS Distributionsiii. Adding debug related 'printf's 443*2c2f96dcSApple OSS Distributions----------------------------------- 444*2c2f96dcSApple OSS Distributions 445*2c2f96dcSApple 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*2c2f96dcSApple OSS Distributions 447*2c2f96dcSApple OSS Distributions * To enable/disable logging 448*2c2f96dcSApple OSS Distributions - (lldb) xnudebug debug 449*2c2f96dcSApple OSS Distributions Enabled debug logging. 450*2c2f96dcSApple OSS Distributions 451*2c2f96dcSApple OSS Distributions 452