import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
from gdbclientutils import *


class TestRecognizeBreakpoint(GDBRemoteTestBase):
    """ This tests the case where the gdb-remote server doesn't support any
        of the thread-info packets, and just tells which thread got the stop
        signal with:
              T05thread:01;
        There was a bug in lldb that we would set the stop reason from this 
        packet too early - before we had updated the thread list.  So when we
        later updated the thread list, we would throw away this info.  Normally
        we would be able to reconstruct it from the thread info, but not if the
        stub doesn't support it """
             
    @skipIfXmlSupportMissing
    def test(self):
        class MyResponder(MockGDBServerResponder):
            def __init__(self):
                MockGDBServerResponder.__init__(self)
                self.thread_info_count = 0
                self.after_cont = False
                self.current_thread = 0
                
            def cont(self):
                # Simulate process stopping due to a breakpoint:
                self.after_cont = True
                return "T05thread:01;"

            def vCont(self, packet):
                self.after_cont = True
                return "T05thread:01;"
            
            def haltReason(self):
                return "T02thread:01;"

            def threadStopInfo(self, num):
                return ""

            def QThreadSuffixSupported(self):
                return ""

            def QListThreadsInStopReply(self):
                return ""

            def setBreakpoint(self, packet):
                return "OK"
            
            def qfThreadInfo(self):
                return "m1"

            def qsThreadInfo(self):
                if (self.thread_info_count % 2) == 0:
                    str = "m2"
                else:
                    str = "l"
                self.thread_info_count += 1
                return str

            def readRegisters(self):
                if self.after_cont and self.current_thread == 1:
                    return "c01e990080ffffff"
                else:
                    return "badcfe10325476980"
            
            def readRegister(self, regno):
                return ""
            
            def qXferRead(self, obj, annex, offset, length):
                if annex == "target.xml":
                    return """<?xml version="1.0"?>
                        <target version="1.0">
                          <architecture>i386:x86-64</architecture>
                          <feature name="org.gnu.gdb.i386.core">
                            <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
                          </feature>
                        </target>""", False
                else:
                    return None, False

            def selectThread(self, op, thread):
                if op != 'g':
                    return ''
                
                self.current_thread = thread
                return "OK"
            
            def other (self, packet):
                if packet == "vCont?":
                    return "vCont;c;C;s;S"
                return ''
                
        python_os_plugin_path = os.path.join(self.getSourceDir(),
                                             'operating_system_2.py')
        command ="settings set target.process.python-os-plugin-path '{}'".format(
            python_os_plugin_path)
        self.runCmd(command)

        self.server.responder = MyResponder()
        target = self.dbg.CreateTarget("")
        process = self.connect(target)

        bkpt = target.BreakpointCreateByAddress(0xffffff8000991ec0)
        self.assertEqual(bkpt.GetNumLocations(), 1, "Fake breakpoint was resolved.")

        # Get the initial stop, and we should have two threads.
        num_threads = len(process.threads)
        self.assertEqual(num_threads, 2, "Got two threads")

        thread_0 = process.threads[0]
        self.assertEqual(thread_0.GetStopReason(), 1, "Thread_0 stopped for no reason")
        self.assertEqual(thread_0.GetName(), "one", "Thread_0 is called one")
        
        thread_1 = process.threads[1]
        self.assertEqual(thread_1.GetStopReason(), 5, "Thread_0 stopped for SIGSTOP")
        self.assertEqual(thread_1.GetName(), "two", "Thread_0 is called two")
        
        # Now continue and we will fake hitting a breakpoint.
        process.Continue()

        self.assertEqual(process.GetState(),lldb.eStateStopped, "Process is stopped")
        num_threads = len(process.threads)

        num_threads = len(process.threads)
        self.assertEqual(num_threads, 2, "Got two threads")

        thread_0 = process.threads[0]
        self.assertEqual(thread_0.GetStopReason(), 1, "Thread_0 stopped for no reason")
        self.assertEqual(thread_0.GetName(), "one", "Thread_0 is called one")
        
        thread_1 = process.threads[1]
        self.assertEqual(thread_1.GetStopReason(), 3, "Thread_0 stopped for SIGTRAP")
        self.assertEqual(thread_1.GetName(), "three", "Thread_0 is called three")

        self.assertTrue(thread_1.IsValid(), "Thread_1 is valid")
        self.assertEqual(thread_1.GetStopReason(), lldb.eStopReasonBreakpoint, "Stopped at breakpoint")
        
