1import lldb 2from lldbsuite.test.lldbtest import * 3from lldbsuite.test.decorators import * 4from lldbsuite.test.gdbclientutils import * 5from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 6 7 8class TestRecognizeBreakpoint(GDBRemoteTestBase): 9 10 mydir = TestBase.compute_mydir(__file__) 11 12 """ This tests the case where the gdb-remote server doesn't support any 13 of the thread-info packets, and just tells which thread got the stop 14 signal with: 15 T05thread:01; 16 There was a bug in lldb that we would set the stop reason from this 17 packet too early - before we had updated the thread list. So when we 18 later updated the thread list, we would throw away this info. Normally 19 we would be able to reconstruct it from the thread info, but not if the 20 stub doesn't support it """ 21 22 @skipIfXmlSupportMissing 23 def test(self): 24 class MyResponder(MockGDBServerResponder): 25 def __init__(self): 26 MockGDBServerResponder.__init__(self) 27 self.thread_info_count = 0 28 self.after_cont = False 29 self.current_thread = 0 30 31 def cont(self): 32 # Simulate process stopping due to a breakpoint: 33 self.after_cont = True 34 return "T05thread:01;" 35 36 def vCont(self, packet): 37 self.after_cont = True 38 return "T05thread:01;" 39 40 def haltReason(self): 41 return "T02thread:01;" 42 43 def threadStopInfo(self, num): 44 return "" 45 46 def QThreadSuffixSupported(self): 47 return "" 48 49 def QListThreadsInStopReply(self): 50 return "" 51 52 def setBreakpoint(self, packet): 53 return "OK" 54 55 def qfThreadInfo(self): 56 return "m1" 57 58 def qsThreadInfo(self): 59 if (self.thread_info_count % 2) == 0: 60 str = "m2" 61 else: 62 str = "l" 63 self.thread_info_count += 1 64 return str 65 66 def readRegisters(self): 67 if self.after_cont and self.current_thread == 1: 68 return "c01e990080ffffff" 69 else: 70 return "badcfe10325476980" 71 72 def readRegister(self, regno): 73 return "" 74 75 def qXferRead(self, obj, annex, offset, length): 76 if annex == "target.xml": 77 return """<?xml version="1.0"?> 78 <target version="1.0"> 79 <architecture>i386:x86-64</architecture> 80 <feature name="org.gnu.gdb.i386.core"> 81 <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/> 82 </feature> 83 </target>""", False 84 else: 85 return None, False 86 87 def selectThread(self, op, thread): 88 if op != 'g': 89 return '' 90 91 self.current_thread = thread 92 return "OK" 93 94 def other (self, packet): 95 if packet == "vCont?": 96 return "vCont;c;C;s;S" 97 return '' 98 99 python_os_plugin_path = os.path.join(self.getSourceDir(), 100 'operating_system_2.py') 101 command ="settings set target.process.python-os-plugin-path '{}'".format( 102 python_os_plugin_path) 103 self.runCmd(command) 104 105 self.server.responder = MyResponder() 106 target = self.dbg.CreateTarget("") 107 process = self.connect(target) 108 109 bkpt = target.BreakpointCreateByAddress(0xffffff8000991ec0) 110 self.assertEqual(bkpt.GetNumLocations(), 1, "Fake breakpoint was resolved.") 111 112 # Get the initial stop, and we should have two threads. 113 num_threads = len(process.threads) 114 self.assertEqual(num_threads, 2, "Got two threads") 115 116 thread_0 = process.threads[0] 117 self.assertEqual(thread_0.GetStopReason(), 1, "Thread_0 stopped for no reason") 118 self.assertEqual(thread_0.GetName(), "one", "Thread_0 is called one") 119 120 thread_1 = process.threads[1] 121 self.assertEqual(thread_1.GetStopReason(), 5, "Thread_0 stopped for SIGSTOP") 122 self.assertEqual(thread_1.GetName(), "two", "Thread_0 is called two") 123 124 # Now continue and we will fake hitting a breakpoint. 125 process.Continue() 126 127 self.assertEqual(process.GetState(),lldb.eStateStopped, "Process is stopped") 128 num_threads = len(process.threads) 129 130 num_threads = len(process.threads) 131 self.assertEqual(num_threads, 2, "Got two threads") 132 133 thread_0 = process.threads[0] 134 self.assertEqual(thread_0.GetStopReason(), 1, "Thread_0 stopped for no reason") 135 self.assertEqual(thread_0.GetName(), "one", "Thread_0 is called one") 136 137 thread_1 = process.threads[1] 138 self.assertEqual(thread_1.GetStopReason(), 3, "Thread_0 stopped for SIGTRAP") 139 self.assertEqual(thread_1.GetName(), "three", "Thread_0 is called three") 140 141 self.assertTrue(thread_1.IsValid(), "Thread_1 is valid") 142 self.assertEqual(thread_1.GetStopReason(), lldb.eStopReasonBreakpoint, "Stopped at breakpoint") 143 144