1d047e25cSshahar salzman# GDB Macros User Guide {#gdb_macros} 2d047e25cSshahar salzman 31e1fd9acSwawryk## Introduction 4d047e25cSshahar salzman 5d047e25cSshahar salzmanWhen debugging an spdk application using gdb we may need to view data structures 6d047e25cSshahar salzmanin lists, e.g. information about bdevs or threads. 7d047e25cSshahar salzman 8d047e25cSshahar salzmanIf, for example I have several bdevs, and I wish to get information on bdev by 9d047e25cSshahar salzmanthe name 'test_vols3', I will need to manually iterate over the list as follows: 10d047e25cSshahar salzman 11d047e25cSshahar salzman~~~{.sh} 12d047e25cSshahar salzman(gdb) p g_bdev_mgr->bdevs->tqh_first->name 13d047e25cSshahar salzman$5 = 0x7f7dcc0b21b0 "test_vols1" 14d047e25cSshahar salzman(gdb) p g_bdev_mgr->bdevs->tqh_first->internal->link->tqe_next->name 15d047e25cSshahar salzman$6 = 0x7f7dcc0b1a70 "test_vols2" 16d047e25cSshahar salzman(gdb) p 17d047e25cSshahar salzmang_bdev_mgr->bdevs->tqh_first->internal->link->tqe_next->internal->link->tqe_next->name 18d047e25cSshahar salzman$7 = 0x7f7dcc215a00 "test_vols3" 19d047e25cSshahar salzman(gdb) p 20d047e25cSshahar salzmang_bdev_mgr->bdevs->tqh_first->internal->link->tqe_next->internal->link->tqe_next 21d047e25cSshahar salzman$8 = (struct spdk_bdev *) 0x7f7dcc2c7c08 22d047e25cSshahar salzman~~~ 23d047e25cSshahar salzman 24d047e25cSshahar salzmanAt this stage, we can start looking at the relevant fields of our bdev which now 25d047e25cSshahar salzmanwe know is in address 0x7f7dcc2c7c08. 26d047e25cSshahar salzman 27d047e25cSshahar salzmanThis can be somewhat troublesome if there are 100 bdevs, and the one we need is 28d047e25cSshahar salzman56th in the list... 29d047e25cSshahar salzman 30d047e25cSshahar salzmanInstead, we can use a gdb macro in order to get information about all the 31d047e25cSshahar salzmandevices. 32d047e25cSshahar salzman 33d047e25cSshahar salzmanExamples: 34d047e25cSshahar salzman 35d047e25cSshahar salzmanPrinting bdevs: 36d047e25cSshahar salzman 37d047e25cSshahar salzman~~~{.sh} 38d047e25cSshahar salzman(gdb) spdk_print_bdevs 39d047e25cSshahar salzman 40d047e25cSshahar salzmanSPDK object of type struct spdk_bdev at 0x7f7dcc1642a8 41d047e25cSshahar salzman((struct spdk_bdev*) 0x7f7dcc1642a8) 42d047e25cSshahar salzmanname 0x7f7dcc0b21b0 "test_vols1" 43d047e25cSshahar salzman 44d047e25cSshahar salzman--------------- 45d047e25cSshahar salzman 46d047e25cSshahar salzmanSPDK object of type struct spdk_bdev at 0x7f7dcc216008 47d047e25cSshahar salzman((struct spdk_bdev*) 0x7f7dcc216008) 48d047e25cSshahar salzmanname 0x7f7dcc0b1a70 "test_vols2" 49d047e25cSshahar salzman 50d047e25cSshahar salzman--------------- 51d047e25cSshahar salzman 52d047e25cSshahar salzmanSPDK object of type struct spdk_bdev at 0x7f7dcc2c7c08 53d047e25cSshahar salzman((struct spdk_bdev*) 0x7f7dcc2c7c08) 54d047e25cSshahar salzmanname 0x7f7dcc215a00 "test_vols3" 55d047e25cSshahar salzman 56d047e25cSshahar salzman--------------- 57d047e25cSshahar salzman~~~ 58d047e25cSshahar salzman 59d047e25cSshahar salzmanFinding a bdev by name: 60d047e25cSshahar salzman 61d047e25cSshahar salzman~~~{.sh} 62d047e25cSshahar salzman(gdb) spdk_find_bdev test_vols1 63d047e25cSshahar salzmantest_vols1 64d047e25cSshahar salzman 65d047e25cSshahar salzmanSPDK object of type struct spdk_bdev at 0x7f7dcc1642a8 66d047e25cSshahar salzman((struct spdk_bdev*) 0x7f7dcc1642a8) 67d047e25cSshahar salzmanname 0x7f7dcc0b21b0 "test_vols1" 68d047e25cSshahar salzman~~~ 69d047e25cSshahar salzman 70d047e25cSshahar salzmanPrinting spdk threads: 71d047e25cSshahar salzman 72d047e25cSshahar salzman~~~{.sh} 73d047e25cSshahar salzman(gdb) spdk_print_threads 74d047e25cSshahar salzman 75d047e25cSshahar salzmanSPDK object of type struct spdk_thread at 0x7fffd0008b50 76d047e25cSshahar salzman((struct spdk_thread*) 0x7fffd0008b50) 77d047e25cSshahar salzmanname 0x7fffd00008e0 "reactor_1" 78d047e25cSshahar salzmanIO Channels: 79d047e25cSshahar salzman SPDK object of type struct spdk_io_channel at 0x7fffd0052610 80d047e25cSshahar salzman ((struct spdk_io_channel*) 0x7fffd0052610) 81d047e25cSshahar salzman name 82d047e25cSshahar salzman ref 1 83d047e25cSshahar salzman device 0x7fffd0008c80 (0x7fffd0008ce0 "nvmf_tgt") 84d047e25cSshahar salzman --------------- 85d047e25cSshahar salzman 86d047e25cSshahar salzman SPDK object of type struct spdk_io_channel at 0x7fffd0056cd0 87d047e25cSshahar salzman ((struct spdk_io_channel*) 0x7fffd0056cd0) 88d047e25cSshahar salzman name 89d047e25cSshahar salzman ref 2 90d047e25cSshahar salzman device 0x7fffd0056bf0 (0x7fffd0008e70 "test_vol1") 91d047e25cSshahar salzman --------------- 92d047e25cSshahar salzman 93d047e25cSshahar salzman SPDK object of type struct spdk_io_channel at 0x7fffd00582e0 94d047e25cSshahar salzman ((struct spdk_io_channel*) 0x7fffd00582e0) 95d047e25cSshahar salzman name 96d047e25cSshahar salzman ref 1 97d047e25cSshahar salzman device 0x7fffd0056c50 (0x7fffd0056cb0 "bdev_test_vol1") 98d047e25cSshahar salzman --------------- 99d047e25cSshahar salzman 100d047e25cSshahar salzman SPDK object of type struct spdk_io_channel at 0x7fffd00583b0 101d047e25cSshahar salzman ((struct spdk_io_channel*) 0x7fffd00583b0) 102d047e25cSshahar salzman name 103d047e25cSshahar salzman ref 1 104d047e25cSshahar salzman device 0x7fffd0005630 (0x7fffd0005690 "bdev_mgr") 105d047e25cSshahar salzman --------------- 106d047e25cSshahar salzman~~~ 107d047e25cSshahar salzman 108d047e25cSshahar salzmanPrinting nvmf subsystems: 109d047e25cSshahar salzman 110d047e25cSshahar salzman~~~{.sh} 111d047e25cSshahar salzman(gdb) spdk_print_nvmf_subsystems 112d047e25cSshahar salzman 113d047e25cSshahar salzmanSPDK object of type struct spdk_nvmf_subsystem at 0x7fffd0008d00 114d047e25cSshahar salzman((struct spdk_nvmf_subsystem*) 0x7fffd0008d00) 115d047e25cSshahar salzmanname "nqn.2014-08.org.nvmexpress.discovery", '\000' <repeats 187 times> 116d047e25cSshahar salzmannqn "nqn.2014-08.org.nvmexpress.discovery", '\000' <repeats 187 times> 117d047e25cSshahar salzmanID 0 118d047e25cSshahar salzman 119d047e25cSshahar salzman--------------- 120d047e25cSshahar salzman 121d047e25cSshahar salzmanSPDK object of type struct spdk_nvmf_subsystem at 0x7fffd0055760 122d047e25cSshahar salzman((struct spdk_nvmf_subsystem*) 0x7fffd0055760) 123d047e25cSshahar salzmanname "nqn.2016-06.io.spdk.umgmt:cnode1", '\000' <repeats 191 times> 124d047e25cSshahar salzmannqn "nqn.2016-06.io.spdk.umgmt:cnode1", '\000' <repeats 191 times> 125d047e25cSshahar salzmanID 1 126d047e25cSshahar salzman~~~ 127d047e25cSshahar salzman 128*adc2ca50SMike GerdtsPrinting SPDK spinlocks: 129*adc2ca50SMike Gerdts 130*adc2ca50SMike GerdtsIn this example, the spinlock has been initialized and locked but has never been unlocked. 131*adc2ca50SMike GerdtsAfter it is unlocked the first time the last unlocked stack will be present and the 132*adc2ca50SMike Gerdts`Locked by spdk_thread` line will say `not locked`. 133*adc2ca50SMike Gerdts 134*adc2ca50SMike Gerdts~~~{.sh} 135*adc2ca50SMike GerdtsBreakpoint 2, spdk_spin_unlock (sspin=0x655110 <g_bdev_mgr+80>) at thread.c:2915 136*adc2ca50SMike Gerdts2915 struct spdk_thread *thread = spdk_get_thread(); 137*adc2ca50SMike Gerdts(gdb) print *sspin 138*adc2ca50SMike Gerdts$2 = struct spdk_spinlock: 139*adc2ca50SMike Gerdts Locked by spdk_thread: 0x658080 140*adc2ca50SMike Gerdts Initialized at: 141*adc2ca50SMike Gerdts 0x43e677 <spdk_spin_init+213> thread.c:2878 142*adc2ca50SMike Gerdts 0x404feb <_bdev_init+16> /build/spdk/spdk-review-public/lib/bdev/bdev.c:116 143*adc2ca50SMike Gerdts 0x44483d <__libc_csu_init+77> 144*adc2ca50SMike Gerdts 0x7ffff62c9d18 <__libc_start_main+120> 145*adc2ca50SMike Gerdts 0x40268e <_start+46> 146*adc2ca50SMike Gerdts Last locked at: 147*adc2ca50SMike Gerdts 0x43e936 <spdk_spin_lock+436> thread.c:2909 148*adc2ca50SMike Gerdts 0x40ca9c <bdev_name_add+129> /build/spdk/spdk-review-public/lib/bdev/bdev.c:3855 149*adc2ca50SMike Gerdts 0x411a3c <bdev_register+641> /build/spdk/spdk-review-public/lib/bdev/bdev.c:6660 150*adc2ca50SMike Gerdts 0x412e1e <spdk_bdev_register+24> /build/spdk/spdk-review-public/lib/bdev/bdev.c:7171 151*adc2ca50SMike Gerdts 0x417895 <num_blocks_test+119> bdev_ut.c:878 152*adc2ca50SMike Gerdts 0x7ffff7bc38cb <run_single_test.constprop+379> 153*adc2ca50SMike Gerdts 0x7ffff7bc3b61 <run_single_suite.constprop+433> 154*adc2ca50SMike Gerdts 0x7ffff7bc3f76 <CU_run_all_tests+118> 155*adc2ca50SMike Gerdts 0x43351f <main+1439> bdev_ut.c:6295 156*adc2ca50SMike Gerdts 0x7ffff62c9d85 <__libc_start_main+229> 157*adc2ca50SMike Gerdts 0x40268e <_start+46> 158*adc2ca50SMike Gerdts Last unlocked at: 159*adc2ca50SMike Gerdts~~~ 160*adc2ca50SMike Gerdts 161*adc2ca50SMike GerdtsPrint a single spinlock stack: 162*adc2ca50SMike Gerdts 163*adc2ca50SMike Gerdts~~~{.sh} 164*adc2ca50SMike Gerdts(gdb) print sspin->internal.lock_stack 165*adc2ca50SMike Gerdts$1 = struct sspin_stack: 166*adc2ca50SMike Gerdts 0x40c6a1 <spdk_spin_lock+436> /build/spdk/spdk-review-public/lib/thread/thread.c:2909 167*adc2ca50SMike Gerdts 0x413f48 <spdk_spin+552> thread_ut.c:1831 168*adc2ca50SMike Gerdts 0x7ffff7bc38cb <run_single_test.constprop+379> 169*adc2ca50SMike Gerdts 0x7ffff7bc3b61 <run_single_suite.constprop+433> 170*adc2ca50SMike Gerdts 0x7ffff7bc3f76 <CU_run_all_tests+118> 171*adc2ca50SMike Gerdts 0x4148fa <main+547> thread_ut.c:1948 172*adc2ca50SMike Gerdts 0x7ffff62c9d85 <__libc_start_main+229> 173*adc2ca50SMike Gerdts 0x40248e <_start+46> 174*adc2ca50SMike Gerdts~~~ 175*adc2ca50SMike Gerdts 1761e1fd9acSwawryk## Loading The gdb Macros 177d047e25cSshahar salzman 178d047e25cSshahar salzmanCopy the gdb macros to the host where you are about to debug. 179d047e25cSshahar salzmanIt is best to copy the file either to somewhere within the PYTHONPATH, or to add 180d047e25cSshahar salzmanthe destination directory to the PYTHONPATH. This is not mandatory, and can be 181d047e25cSshahar salzmanworked around, but can save a few steps when loading the module to gdb. 182d047e25cSshahar salzman 183d047e25cSshahar salzmanFrom gdb, with the application core open, invoke python and load the modules. 184d047e25cSshahar salzman 185d047e25cSshahar salzmanIn the example below, I copied the macros to the /tmp directory which is not in 186d047e25cSshahar salzmanthe PYTHONPATH, so I had to manually add the directory to the path. 187d047e25cSshahar salzman 188d047e25cSshahar salzman~~~{.sh} 189d047e25cSshahar salzman(gdb) python 190d047e25cSshahar salzman>import sys 191d047e25cSshahar salzman>sys.path.append('/tmp') 192d047e25cSshahar salzman>import gdb_macros 193d047e25cSshahar salzman>end 194d047e25cSshahar salzman(gdb) spdk_load_macros 195d047e25cSshahar salzman~~~ 196d047e25cSshahar salzman 1971e1fd9acSwawryk## Using the gdb Data Directory 198d047e25cSshahar salzman 199d047e25cSshahar salzmanOn most systems, the data directory is /usr/share/gdb. The python script should 200d047e25cSshahar salzmanbe copied into the python/gdb/function (or python/gdb/command) directory under 201d047e25cSshahar salzmanthe data directory, e.g. /usr/share/gdb/python/gdb/function. 202d047e25cSshahar salzman 203d047e25cSshahar salzmanIf the python script is in there, then the only thing you need to do when 204d047e25cSshahar salzmanstarting gdb is type "spdk_load_macros". 205d047e25cSshahar salzman 2061e1fd9acSwawryk## Using .gdbinit To Load The Macros 207d047e25cSshahar salzman 208d047e25cSshahar salzman.gdbinit can also be used in order to run automatically run the manual steps 209d047e25cSshahar salzmanabove prior to starting gdb. 210d047e25cSshahar salzman 211a82b365bSJosh SorefExample .gdbinit: 212d047e25cSshahar salzman 213d047e25cSshahar salzman~~~{.sh} 214d047e25cSshahar salzmansource /opt/km/install/tools/gdb_macros/gdb_macros.py 215d047e25cSshahar salzman~~~ 216d047e25cSshahar salzman 217d047e25cSshahar salzmanWhen starting gdb you still have to call spdk_load_macros. 218d047e25cSshahar salzman 2191e1fd9acSwawryk## Why Do We Need to Explicitly Call spdk_load_macros 220d047e25cSshahar salzman 221d047e25cSshahar salzmanThe reason is that the macros need to use globals provided by spdk in order to 222d047e25cSshahar salzmaniterate the spdk lists and build iterable representations of the list objects. 223d047e25cSshahar salzmanThis will result in errors if these are not available which is very possible if 224d047e25cSshahar salzmangdb is used for reasons other than debugging spdk core dumps. 225d047e25cSshahar salzman 2263f912cf0SMichal BergerIn the example below, I attempted to load the macros when the globals are not 227d047e25cSshahar salzmanavailable causing gdb to fail loading the gdb_macros: 228d047e25cSshahar salzman 229d047e25cSshahar salzman~~~{.sh} 230d047e25cSshahar salzman(gdb) spdk_load_macros 231d047e25cSshahar salzmanTraceback (most recent call last): 232d047e25cSshahar salzman File "/opt/km/install/tools/gdb_macros/gdb_macros.py", line 257, in invoke 233d047e25cSshahar salzman spdk_print_threads() 234d047e25cSshahar salzman File "/opt/km/install/tools/gdb_macros/gdb_macros.py", line 241, in __init__ 235d047e25cSshahar salzman threads = SpdkThreads() 236d047e25cSshahar salzman File "/opt/km/install/tools/gdb_macros/gdb_macros.py", line 234, in __init__ 237d047e25cSshahar salzman super(SpdkThreads, self).__init__('g_threads', SpdkThread) 238d047e25cSshahar salzman File "/opt/km/install/tools/gdb_macros/gdb_macros.py", line 25, in __init__ 239d047e25cSshahar salzman ['tailq']) 240d047e25cSshahar salzman File "/opt/km/install/tools/gdb_macros/gdb_macros.py", line 10, in __init__ 241d047e25cSshahar salzman self.list = gdb.parse_and_eval(self.list_pointer) 242d047e25cSshahar salzmanRuntimeError: No symbol table is loaded. Use the "file" command. 243d047e25cSshahar salzmanError occurred in Python command: No symbol table is loaded. Use the "file" 244d047e25cSshahar salzmancommand. 245d047e25cSshahar salzman~~~ 246d047e25cSshahar salzman 2471e1fd9acSwawryk## Macros available 248d047e25cSshahar salzman 249d047e25cSshahar salzman- spdk_load_macros: load the macros (use --reload in order to reload them) 250d047e25cSshahar salzman- spdk_print_bdevs: information about bdevs 251d047e25cSshahar salzman- spdk_find_bdev: find a bdev (substring search) 252d047e25cSshahar salzman- spdk_print_io_devices: information about io devices 253d047e25cSshahar salzman- spdk_print_nvmf_subsystems: information about nvmf subsystems 254d047e25cSshahar salzman- spdk_print_threads: information about threads 255d047e25cSshahar salzman 2561e1fd9acSwawryk## Adding New Macros 257d047e25cSshahar salzman 258d047e25cSshahar salzmanThe list iteration macros are usually built from 3 layers: 259d047e25cSshahar salzman 260d047e25cSshahar salzman- SpdkPrintCommand: inherits from gdb.Command and invokes the list iteration 261d047e25cSshahar salzman- SpdkTailqList: Performs the iteration of a tailq list according to the tailq 262d047e25cSshahar salzman member implementation 263d047e25cSshahar salzman- SpdkObject: Provides the __str__ function so that the list iteration can print 264d047e25cSshahar salzman the object 265d047e25cSshahar salzman 266d047e25cSshahar salzmanOther useful objects: 267d047e25cSshahar salzman 268d047e25cSshahar salzman- SpdkNormalTailqList: represents a list which has 'tailq' as the tailq object 269d047e25cSshahar salzman- SpdkArr: Iteration over an array (instead of a linked list) 270