2 from lldbsuite.test.lldbtest import *
3 from lldbsuite.test.decorators import *
4 from gdbclientutils import *
7 class TestRecognizeBreakpoint(GDBRemoteTestBase):
8 """ This tests the case where the gdb-remote server doesn't support any
9 of the thread-info packets, and just tells which thread got the stop
12 There was a bug in lldb that we would set the stop reason from this
13 packet too early - before we had updated the thread list. So when we
14 later updated the thread list, we would throw away this info. Normally
15 we would be able to reconstruct it from the thread info, but not if the
16 stub doesn't support it """
18 @skipIfXmlSupportMissing
20 class MyResponder(MockGDBServerResponder):
22 MockGDBServerResponder.__init__(self)
23 self.thread_info_count = 0
24 self.after_cont = False
25 self.current_thread = 0
28 # Simulate process stopping due to a breakpoint:
29 self.after_cont = True
30 return "T05thread:01;"
32 def vCont(self, packet):
33 self.after_cont = True
34 return "T05thread:01;"
37 return "T02thread:01;"
39 def threadStopInfo(self, num):
42 def QThreadSuffixSupported(self):
45 def QListThreadsInStopReply(self):
48 def setBreakpoint(self, packet):
51 def qfThreadInfo(self):
54 def qsThreadInfo(self):
55 if (self.thread_info_count % 2) == 0:
59 self.thread_info_count += 1
62 def readRegisters(self):
63 if self.after_cont and self.current_thread == 1:
64 return "c01e990080ffffff"
66 return "badcfe10325476980"
68 def readRegister(self, regno):
71 def qXferRead(self, obj, annex, offset, length):
72 if annex == "target.xml":
73 return """<?xml version="1.0"?>
74 <target version="1.0">
75 <architecture>i386:x86-64</architecture>
76 <feature name="org.gnu.gdb.i386.core">
77 <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
83 def selectThread(self, op, thread):
87 self.current_thread = thread
90 def other (self, packet):
91 if packet == "vCont?":
92 return "vCont;c;C;s;S"
95 python_os_plugin_path = os.path.join(self.getSourceDir(),
96 'operating_system_2.py')
97 command ="settings set target.process.python-os-plugin-path '{}'".format(
98 python_os_plugin_path)
101 self.server.responder = MyResponder()
102 target = self.dbg.CreateTarget("")
103 process = self.connect(target)
105 bkpt = target.BreakpointCreateByAddress(0xffffff8000991ec0)
106 self.assertEqual(bkpt.GetNumLocations(), 1, "Fake breakpoint was resolved.")
108 # Get the initial stop, and we should have two threads.
109 num_threads = len(process.threads)
110 self.assertEqual(num_threads, 2, "Got two threads")
112 thread_0 = process.threads[0]
113 self.assertEqual(thread_0.GetStopReason(), 1, "Thread_0 stopped for no reason")
114 self.assertEqual(thread_0.GetName(), "one", "Thread_0 is called one")
116 thread_1 = process.threads[1]
117 self.assertEqual(thread_1.GetStopReason(), 5, "Thread_0 stopped for SIGSTOP")
118 self.assertEqual(thread_1.GetName(), "two", "Thread_0 is called two")
120 # Now continue and we will fake hitting a breakpoint.
123 self.assertEqual(process.GetState(),lldb.eStateStopped, "Process is stopped")
124 num_threads = len(process.threads)
126 num_threads = len(process.threads)
127 self.assertEqual(num_threads, 2, "Got two threads")
129 thread_0 = process.threads[0]
130 self.assertEqual(thread_0.GetStopReason(), 1, "Thread_0 stopped for no reason")
131 self.assertEqual(thread_0.GetName(), "one", "Thread_0 is called one")
133 thread_1 = process.threads[1]
134 self.assertEqual(thread_1.GetStopReason(), 3, "Thread_0 stopped for SIGTRAP")
135 self.assertEqual(thread_1.GetName(), "three", "Thread_0 is called three")
137 self.assertTrue(thread_1.IsValid(), "Thread_1 is valid")
138 self.assertEqual(thread_1.GetStopReason(), lldb.eStopReasonBreakpoint, "Stopped at breakpoint")