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