1import bz2
2import shutil
3import struct
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11@skipIfFBSDVMCoreSupportMissing
12class FreeBSDKernelVMCoreTestCase(TestBase):
13    NO_DEBUG_INFO_TESTCASE = True
14    maxDiff = None
15
16    def make_target(self, src_filename):
17        src = self.getSourcePath(src_filename)
18        dest = self.getBuildArtifact("kernel")
19        self.yaml2obj(src, dest, max_size=30*1024*1024)
20        return self.dbg.CreateTarget(dest)
21
22    def make_vmcore(self, src_filename):
23        src = self.getSourcePath(src_filename)
24        dest = self.getBuildArtifact("vmcore")
25        with bz2.open(src, "rb") as inf:
26            with open(dest, "wb") as outf:
27                shutil.copyfileobj(inf, outf)
28        return dest
29
30    def do_test(self, kernel_yaml, vmcore_bz2, numthread, threads={}, hz=100):
31        target = self.make_target(kernel_yaml)
32        vmcore_file = self.make_vmcore(vmcore_bz2)
33        process = target.LoadCore(vmcore_file)
34
35        self.assertTrue(process, PROCESS_IS_VALID)
36        self.assertEqual(process.GetNumThreads(), numthread)
37        self.assertEqual(process.GetProcessID(), 0)
38
39        # test memory reading
40        self.expect("expr -- *(int *) &hz",
41                    substrs=["(int) $0 = %d" % hz])
42
43        main_mod = target.GetModuleAtIndex(0)
44        hz_addr = (main_mod.FindSymbols("hz")[0].symbol.addr
45                   .GetLoadAddress(target))
46        error = lldb.SBError()
47        self.assertEqual(process.ReadMemory(hz_addr, 4, error),
48                         struct.pack("<I", hz))
49
50        for thread_index, thread_data in threads.items():
51            bt_expected = thread_data["bt"]
52            regs_expected = thread_data["regs"]
53            thread = process.GetThreadAtIndex(thread_index)
54            self.assertEqual(thread.GetName(), thread_data["name"])
55
56            # test backtrace
57            self.assertEqual(
58                [frame.addr.GetLoadAddress(target) for frame in thread],
59                bt_expected)
60
61            # test registers
62            regs = thread.GetFrameAtIndex(0).GetRegisters()
63            reg_values = {}
64            for regset in regs:
65                for reg in regset:
66                    if reg.value is None:
67                        continue
68                    reg_values[reg.name] = reg.value
69            self.assertEqual(reg_values, regs_expected)
70
71        self.dbg.DeleteTarget(target)
72
73    def test_amd64_full_vmcore(self):
74        self.do_test("kernel-amd64.yaml", "vmcore-amd64-full.bz2",
75                numthread=13,
76                threads={
77                    0: {"name": "(pid 806) sysctl (crashed)",
78                        "bt": [0xffffffff80c09ade, 0xffffffff80c09916,
79                               0xffffffff80c09d90, 0xffffffff80c09b93,
80                               0xffffffff80c57d91, 0xffffffff80c19e71,
81                               0xffffffff80c192bc, 0xffffffff80c19933,
82                               0xffffffff80c1977f, 0xffffffff8108ba8c,
83                               0xffffffff810620ce,
84                               ],
85                        "regs": {"rbx": "0x0000000000000000",
86                                 "rbp": "0xfffffe0085cb2760",
87                                 "rsp": "0xfffffe0085cb2748",
88                                 "r12": "0xfffffe0045a6c300",
89                                 "r13": "0xfffff800033693a8",
90                                 "r14": "0x0000000000000000",
91                                 "r15": "0xfffff80003369380",
92                                 "rip": "0xffffffff80c09ade",
93                                 },
94                        },
95                    1: {"name": "(pid 11) idle/idle: cpu0 (on CPU 0)",
96                        "bt": [0xffffffff81057988, 0xffffffff81057949,
97                               0xffffffff8108a5ff, 0xffffffff81062537,
98                               0xffffffff80c1aa38, 0xffffffff80b9d587,
99                               0xffffffff810575b1, 0xffffffff81063b33,
100                               0xffffffff804e3edb, 0xffffffff8104dc6e,
101                               0xffffffff8104dd1f, 0xffffffff80c3f0b4,
102                               0xffffffff80bc7c5e,
103                               ],
104                        "regs": {"rbx": "0xffffffff81d43950",
105                                 "rbp": "0xffffffff81d43820",
106                                 "rsp": "0xffffffff81d43808",
107                                 "r12": "0xfffff80003374000",
108                                 "r13": "0x00000000027be000",
109                                 "r14": "0x0000000000000000",
110                                 "r15": "0xfffffe00009f7300",
111                                 "rip": "0xffffffff81057988",
112                                 },
113                        },
114                    10: {"name": "(pid 11) idle/idle: cpu9",
115                         "bt": [0xffffffff80c3c8c8, 0xffffffff80c16521,
116                                0xffffffff80c3f0b4, 0xffffffff80bc7c5e,
117                                ],
118                         "regs": {"rbx": "0x000000007fff29f4",
119                                  "rbp": "0xfffffe00007a4ad0",
120                                  "rsp": "0xfffffe00007a4a08",
121                                  "r12": "0xfffffe00009fd300",
122                                  "r13": "0x0000000000000608",
123                                  "r14": "0xfffffe00009250c0",
124                                  "r15": "0xfffffe0045a6c300",
125                                  "rip": "0xffffffff80c3c8c8",
126                                  },
127                         },
128                    })
129
130    def test_amd64_minidump(self):
131        self.do_test("kernel-amd64.yaml", "vmcore-amd64-minidump.bz2",
132                     numthread=16,
133                     threads={
134                         0: {"name": "(pid 800) sysctl (crashed)",
135                             "bt": [0xffffffff80c09ade, 0xffffffff80c09916,
136                                    0xffffffff80c09d90, 0xffffffff80c09b93,
137                                    0xffffffff80c57d91, 0xffffffff80c19e71,
138                                    0xffffffff80c192bc, 0xffffffff80c19933,
139                                    0xffffffff80c1977f, 0xffffffff8108ba8c,
140                                    0xffffffff810620ce,
141                                    ],
142                             "regs": {"rbx": "0x0000000000000000",
143                                      "rbp": "0xfffffe00798c4760",
144                                      "rsp": "0xfffffe00798c4748",
145                                      "r12": "0xfffffe0045b11c00",
146                                      "r13": "0xfffff800033693a8",
147                                      "r14": "0x0000000000000000",
148                                      "r15": "0xfffff80003369380",
149                                      "rip": "0xffffffff80c09ade",
150                                      },
151                             },
152                         1: {"name": "(pid 28) pagedaemon/dom0 (on CPU 4)",
153                             "bt": [0xffffffff81057988, 0xffffffff81057949,
154                                    0xffffffff8108a5ff, 0xffffffff81062537,
155                                    0xffffffff8107171e, 0xffffffff81075f9c,
156                                    0xffffffff80f4359e, 0xffffffff80f494b4,
157                                    0xffffffff80f47430, 0xffffffff80f46eee,
158                                    0xffffffff80bc7c5e,
159                                    ],
160                             "regs": {"rbx": "0xfffffe00008e2f30",
161                                      "rbp": "0xfffffe00008e2e00",
162                                      "rsp": "0xfffffe00008e2de8",
163                                      "r12": "0xfffff80003845000",
164                                      "r13": "0x00000000027be000",
165                                      "r14": "0x0000000000000004",
166                                      "r15": "0xfffffe00458c2700",
167                                      "rip": "0xffffffff81057988",
168                                      },
169                             },
170                         2: {"name": "(pid 28) pagedaemon/laundry: dom0",
171                             "bt": [0xffffffff80c3c8c8, 0xffffffff80c16521,
172                                    0xffffffff80c15c3b, 0xffffffff80f48dfc,
173                                    0xffffffff80bc7c5e,
174                                    ],
175                             "regs": {"rbx": "0x000000007fff25f1",
176                                      "rbp": "0xfffffe00527dd890",
177                                      "rsp": "0xfffffe00527dd7c8",
178                                      "r12": "0xfffffe0045b13100",
179                                      "r13": "0x0000000000000104",
180                                      "r14": "0xfffffe00008d70c0",
181                                      "r15": "0xfffffe00009f5e00",
182                                      "rip": "0xffffffff80c3c8c8",
183                                      },
184                             },
185                         })
186
187    def test_arm64_minidump(self):
188        self.do_test("kernel-arm64.yaml", "vmcore-arm64-minidump.bz2",
189                     hz=1000,
190                     numthread=10,
191                     threads={
192                         0: {"name": "(pid 939) sysctl (crashed)",
193                             # TODO: fix unwinding
194                             "bt": [0xffff0000004b6e78,
195                                    ],
196                             "regs": {"x0": "0x0000000000000000",
197                                      "x1": "0x0000000000000000",
198                                      "x2": "0x0000000000000000",
199                                      "x3": "0x0000000000000000",
200                                      "x4": "0x0000000000000000",
201                                      "x5": "0x0000000000000000",
202                                      "x6": "0x0000000000000000",
203                                      "x7": "0x0000000000000000",
204                                      "x8": "0xffffa00001548700",
205                                      "x9": "0x0000000000000000",
206                                      "x10": "0xffffa00000e04580",
207                                      "x11": "0x0000000000000000",
208                                      "x12": "0x000000000008950a",
209                                      "x13": "0x0000000000089500",
210                                      "x14": "0x0000000000000039",
211                                      "x15": "0x0000000000000000",
212                                      "x16": "0x00000000ffffffd8",
213                                      "x17": "0x0000000000000000",
214                                      "x18": "0xffff000000e6d380",
215                                      "x19": "0xffff000000af9000",
216                                      "x20": "0xffff000000b82000",
217                                      "x21": "0xffffa00000319da8",
218                                      "x22": "0xffff000000b84000",
219                                      "x23": "0xffff000000b84000",
220                                      "x24": "0xffff000000b55000",
221                                      "x25": "0x0000000000000000",
222                                      "x26": "0x0000000000040800",
223                                      "x27": "0x0000000000000000",
224                                      "x28": "0x00000000002019ca",
225                                      "fp": "0xffff0000d58f23b0",
226                                      "sp": "0xffff0000d58f23b0",
227                                      "pc": "0xffff0000004b6e78",
228                                      },
229                             },
230                         1: {"name": "(pid 21) syncer (on CPU 6)",
231                             # TODO: fix unwinding
232                             "bt": [0xffff000000811370,
233                                    ],
234                             "regs": {"x0": "0x0000000000000000",
235                                      "x1": "0x0000000000000000",
236                                      "x2": "0x0000000000000000",
237                                      "x3": "0x0000000000000000",
238                                      "x4": "0x0000000000000000",
239                                      "x5": "0x0000000000000000",
240                                      "x6": "0x0000000000000000",
241                                      "x7": "0x0000000000000000",
242                                      "x8": "0x0000000000000006",
243                                      "x9": "0x0000000000000560",
244                                      "x10": "0xffff000000e8f640",
245                                      "x11": "0x0000000000000001",
246                                      "x12": "0x0000000056000000",
247                                      "x13": "0x0000000000002af8",
248                                      "x14": "0x0000000000002710",
249                                      "x15": "0x0000000000000002",
250                                      "x16": "0x00000000ffffffff",
251                                      "x17": "0x0000000000000002",
252                                      "x18": "0xffff000000e6db80",
253                                      "x19": "0x0000000000000006",
254                                      "x20": "0xffff0000853a3670",
255                                      "x21": "0xffff0000009279c1",
256                                      "x22": "0x0000000000000804",
257                                      "x23": "0x0000000000000004",
258                                      "x24": "0xffff000082a93000",
259                                      "x25": "0xffffa0000053f080",
260                                      "x26": "0xffff000000e6391c",
261                                      "x27": "0xffff000000e63000",
262                                      "x28": "0x0000000000000004",
263                                      "fp": "0xffff0000853a35c0",
264                                      "sp": "0xffff0000853a35c0",
265                                      "pc": "0xffff000000811370",
266                                      },
267                             },
268                         4: {"name": "(pid 11) idle/idle: cpu2",
269                             # TODO: fix unwinding
270                             "bt": [0xffff0000004ee99c,
271                                    ],
272                             "regs": {"x0": "0x0000000000000000",
273                                      "x1": "0x0000000000000000",
274                                      "x2": "0x0000000000000000",
275                                      "x3": "0x0000000000000000",
276                                      "x4": "0x0000000000000000",
277                                      "x5": "0x0000000000000000",
278                                      "x6": "0x0000000000000000",
279                                      "x7": "0x0000000000000000",
280                                      "x8": "0x00000000ffffffff",
281                                      "x9": "0x0000000000000001",
282                                      "x10": "0x0000000000002710",
283                                      "x11": "0x000000007ff7e333",
284                                      "x12": "0x000000007ff7ba9c",
285                                      "x13": "0x0000000000002af8",
286                                      "x14": "0x0000000000002897",
287                                      "x15": "0x0000000000002af8",
288                                      "x16": "0x00000000000028e1",
289                                      "x17": "0x00000000ffffffff",
290                                      "x18": "0xffff000000e6d380",
291                                      "x19": "0xffffa0000032e580",
292                                      "x20": "0xffff000000b82000",
293                                      "x21": "0xffff000040517100",
294                                      "x22": "0xffffa00000e04580",
295                                      "x23": "0xffff000000b84000",
296                                      "x24": "0x0000000000000001",
297                                      "x25": "0xffff000000dd1000",
298                                      "x26": "0xffff000082783898",
299                                      "x27": "0xffff000000e26000",
300                                      "x28": "0xffff000000b82000",
301                                      "fp": "0xffff0000827835f0",
302                                      "sp": "0xffff000082783570",
303                                      "pc": "0xffff0000004ee99c",
304                                      },
305                             },
306                         })
307
308    def test_i386_minidump(self):
309        self.do_test("kernel-i386.yaml", "vmcore-i386-minidump.bz2",
310                     numthread=13,
311                     threads={
312                         0: {"name": "(pid 806) sysctl (crashed)",
313                             "bt": [0x010025c5, 0x01002410,
314                                    0x010027d5, 0x01002644,
315                                    0x01049a2f, 0x01011077,
316                                    0x01010780, 0x01010c7a,
317                                    0x01010ab2, 0x013e9e2d,
318                                    0xffc033f9,
319                                    ],
320                             "regs": {"ebp": "0x151968e4",
321                                      "esp": "0x151968d8",
322                                      "esi": "0x0c77aa80",
323                                      "edi": "0x03f0dc80",
324                                      "eip": "0x010025c5",
325                                      },
326                             },
327                         1: {"name": "(pid 11) idle/idle: cpu0 (on CPU 0)",
328                             "bt": [0x013a91f6, 0x013a91c0,
329                                    0x013e8ce4, 0xffc0319f,
330                                    0x00000028,
331                                    ],
332                             "regs": {"ebp": "0x03d979bc",
333                                      "esp": "0x03d979a0",
334                                      "esi": "0x000007f7",
335                                      "edi": "0x00000000",
336                                      "eip": "0x013a91f6",
337                                      },
338                             },
339                         12: {"name": "(pid 11) idle/idle: cpu11",
340                             "bt": [0x0103012c, 0x0100de0e,
341                                    0x0100b770, 0x010323be,
342                                    0x00fc50b6,
343                                    ],
344                             "regs": {"ebp": "0x03dc4af0",
345                                      "esp": "0x03dc4aa4",
346                                      "esi": "0x03f97e00",
347                                      "edi": "0x000003e8",
348                                      "eip": "0x0103012c",
349                                      },
350                             },
351                         })
352