]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
Vendor import of lldb release_39 branch r287912:
[FreeBSD/FreeBSD.git] / packages / Python / lldbsuite / test / functionalities / postmortem / linux-core / TestLinuxCore.py
1 """
2 Test basics of linux core file debugging.
3 """
4
5 from __future__ import print_function
6
7 import shutil
8 import struct
9
10 import lldb
11 from lldbsuite.test.decorators import *
12 from lldbsuite.test.lldbtest import *
13 from lldbsuite.test import lldbutil
14
15 class LinuxCoreTestCase(TestBase):
16     NO_DEBUG_INFO_TESTCASE = True
17
18     mydir = TestBase.compute_mydir(__file__)
19
20     _i386_pid   = 32306
21     _x86_64_pid = 32259
22     _s390x_pid  = 1045
23
24     _i386_regions   = 4
25     _x86_64_regions = 5
26     _s390x_regions  = 2
27
28     @skipIf(bugnumber="llvm.org/pr26947")
29     def test_i386(self):
30         """Test that lldb can read the process information from an i386 linux core file."""
31         self.do_test("i386", self._i386_pid, self._i386_regions)
32
33     def test_x86_64(self):
34         """Test that lldb can read the process information from an x86_64 linux core file."""
35         self.do_test("x86_64", self._x86_64_pid, self._x86_64_regions)
36
37     # This seems to hang on non-s390x platforms for some reason.  Disabling for now.
38     @skipIf(archs=no_match(['s390x'])) 
39     def test_s390x(self):
40         """Test that lldb can read the process information from an s390x linux core file."""
41         self.do_test("s390x", self._s390x_pid, self._s390x_regions)
42
43     def test_same_pid_running(self):
44         """Test that we read the information from the core correctly even if we have a running
45         process with the same PID around"""
46         try:
47             shutil.copyfile("x86_64.out",  "x86_64-pid.out")
48             shutil.copyfile("x86_64.core", "x86_64-pid.core")
49             with open("x86_64-pid.core", "r+b") as f:
50                 # These are offsets into the NT_PRSTATUS and NT_PRPSINFO structures in the note
51                 # segment of the core file. If you update the file, these offsets may need updating
52                 # as well. (Notes can be viewed with readelf --notes.)
53                 for pid_offset in [0x1c4, 0x320]:
54                     f.seek(pid_offset)
55                     self.assertEqual(struct.unpack("<I", f.read(4))[0], self._x86_64_pid)
56
57                     # We insert our own pid, and make sure the test still works.
58                     f.seek(pid_offset)
59                     f.write(struct.pack("<I", os.getpid()))
60             self.do_test("x86_64-pid", os.getpid(), self._x86_64_regions)
61         finally:
62             self.RemoveTempFile("x86_64-pid.out")
63             self.RemoveTempFile("x86_64-pid.core")
64
65     def test_two_cores_same_pid(self):
66         """Test that we handle the situation if we have two core files with the same PID
67         around"""
68         alttarget = self.dbg.CreateTarget("altmain.out")
69         altprocess = alttarget.LoadCore("altmain.core")
70         self.assertTrue(altprocess, PROCESS_IS_VALID)
71         self.assertEqual(altprocess.GetNumThreads(), 1)
72         self.assertEqual(altprocess.GetProcessID(), self._x86_64_pid)
73
74         altframe = altprocess.GetSelectedThread().GetFrameAtIndex(0)
75         self.assertEqual(altframe.GetFunctionName(), "_start")
76         self.assertEqual(altframe.GetLineEntry().GetLine(), line_number("altmain.c", "Frame _start"))
77
78         error = lldb.SBError()
79         F = altprocess.ReadCStringFromMemory(altframe.FindVariable("F").GetValueAsUnsigned(), 256, error)
80         self.assertTrue(error.Success())
81         self.assertEqual(F, "_start")
82
83         # without destroying this process, run the test which opens another core file with the
84         # same pid
85         self.do_test("x86_64", self._x86_64_pid, self._x86_64_regions)
86
87     def check_memory_regions(self, process, region_count):
88         region_list = process.GetMemoryRegions()
89         self.assertEqual(region_list.GetSize(), region_count)
90
91         region = lldb.SBMemoryRegionInfo()
92
93         # Check we have the right number of regions.
94         self.assertEqual(region_list.GetSize(), region_count);
95
96         # Check that getting a region beyond the last in the list fails.
97         self.assertFalse(region_list.GetMemoryRegionAtIndex(region_count, region));
98
99         # Check each region is valid.
100         for i in range(region_list.GetSize()):
101             # Check we can actually get this region.
102             self.assertTrue(region_list.GetMemoryRegionAtIndex(i, region))
103
104             #Every region in the list should be mapped.
105             self.assertTrue(region.IsMapped())
106
107             # Test the address at the start of a region returns it's enclosing region.
108             begin_address = region.GetRegionBase()
109             region_at_begin = lldb.SBMemoryRegionInfo()
110             error = process.GetMemoryRegionInfo(begin_address, region_at_begin)
111             self.assertEqual(region, region_at_begin)
112
113             # Test an address in the middle of a region returns it's enclosing region.
114             middle_address = (region.GetRegionBase() + region.GetRegionEnd()) / 2l
115             region_at_middle = lldb.SBMemoryRegionInfo()
116             error = process.GetMemoryRegionInfo(middle_address, region_at_middle)
117             self.assertEqual(region, region_at_middle)
118
119             # Test the address at the end of a region returns it's enclosing region.
120             end_address = region.GetRegionEnd() - 1l
121             region_at_end = lldb.SBMemoryRegionInfo()
122             error = process.GetMemoryRegionInfo(end_address, region_at_end)
123             self.assertEqual(region, region_at_end)
124
125             # Check that quering the end address does not return this region but
126             # the next one.
127             next_region = lldb.SBMemoryRegionInfo()
128             error = process.GetMemoryRegionInfo(region.GetRegionEnd(), next_region)
129             self.assertNotEqual(region, next_region)
130             self.assertEqual(region.GetRegionEnd(), next_region.GetRegionBase())
131
132         # Check that query beyond the last region returns an unmapped region
133         # that ends at LLDB_INVALID_ADDRESS
134         last_region = lldb.SBMemoryRegionInfo()
135         region_list.GetMemoryRegionAtIndex(region_count - 1, last_region)
136         end_region = lldb.SBMemoryRegionInfo()
137         error = process.GetMemoryRegionInfo(last_region.GetRegionEnd(), end_region)
138         self.assertFalse(end_region.IsMapped())
139         self.assertEqual(last_region.GetRegionEnd(), end_region.GetRegionBase())
140         self.assertEqual(end_region.GetRegionEnd(), lldb.LLDB_INVALID_ADDRESS)
141
142     def do_test(self, filename, pid, region_count):
143         target = self.dbg.CreateTarget(filename + ".out")
144         process = target.LoadCore(filename + ".core")
145         self.assertTrue(process, PROCESS_IS_VALID)
146         self.assertEqual(process.GetNumThreads(), 1)
147         self.assertEqual(process.GetProcessID(), pid)
148
149         thread = process.GetSelectedThread()
150         self.assertTrue(thread)
151         self.assertEqual(thread.GetThreadID(), pid)
152         backtrace = ["bar", "foo", "_start"]
153         self.assertEqual(thread.GetNumFrames(), len(backtrace))
154         for i in range(len(backtrace)):
155             frame = thread.GetFrameAtIndex(i)
156             self.assertTrue(frame)
157             self.assertEqual(frame.GetFunctionName(), backtrace[i])
158             self.assertEqual(frame.GetLineEntry().GetLine(),
159                     line_number("main.c", "Frame " + backtrace[i]))
160             self.assertEqual(frame.FindVariable("F").GetValueAsUnsigned(), ord(backtrace[i][0]))
161
162         self.check_memory_regions(process, region_count)
163
164         self.dbg.DeleteTarget(target)