xref: /spdk/doc/gdb_macros.md (revision adc2ca50e945f297dd669e8d21ca5fc33ea257d5)
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