labath updated this revision to Diff 37340.
labath added a comment.

The new functionality gets picked up by the client and automatically used 
everywhere, so I'm not
really worried about testing it. A more important issue would be making sure 
that the legacy read
packet does not rot as it is now unused. I have added a test which makes sure 
both packets return
the same value (modulo hex-encoding), which should prevent that.


http://reviews.llvm.org/D13695

Files:
  examples/python/read_test.py
  source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Utility/StringExtractorGDBRemote.cpp
  source/Utility/StringExtractorGDBRemote.h
  test/functionalities/archives/a.dwo
  test/functionalities/archives/b.dwo
  test/lang/cpp/incomplete-types/length_limit.dwo
  test/lang/cpp/incomplete-types/length_nolimit.dwo
  test/lang/go/goroutines/a.out
  test/lang/go/types/a.out
  test/tools/lldb-server/TestGDBRemoteMemoryRead.py
  test/types/recursive_type_1.d
  test/types/recursive_type_1.dwo
  test/types/recursive_type_1.o

Index: test/types/recursive_type_1.d
===================================================================
--- /dev/null
+++ test/types/recursive_type_1.d
@@ -0,0 +1,2 @@
+recursive_type_1.o recursive_type_1.d : recursive_type_1.cpp \
+  /usr/local/google/home/labath/ll/lldb/test/make/test_common.h
Index: test/tools/lldb-server/TestGDBRemoteMemoryRead.py
===================================================================
--- /dev/null
+++ test/tools/lldb-server/TestGDBRemoteMemoryRead.py
@@ -0,0 +1,45 @@
+"""
+Tests the binary ($x) and hex ($m) memory read packets of the remote stub
+"""
+
+import os
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+import binascii
+
+
+class MemoryReadTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessPlatform(getDarwinOSTriples()+["linux"])
+    def test_memory_read(self):
+        self.build()
+        exe = os.path.join (os.getcwd(), "a.out")
+
+        target = self.dbg.CreateTarget(exe)
+        lldbutil.run_break_set_by_symbol(self, "main")
+
+        process = target.LaunchSimple (None, None, self.get_process_working_directory())
+        self.assertTrue(process, PROCESS_IS_VALID)
+        self.assertEqual(process.GetState(), lldb.eStateStopped, "Process is stopped")
+
+        pc = process.GetSelectedThread().GetSelectedFrame().GetPC()
+        for size in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]:
+            error = lldb.SBError()
+            memory = process.ReadMemory(pc, size, error)
+            self.assertTrue(error.Success())
+            self.match("process plugin packet send x%x,%x" % (pc, size), ["response:", memory])
+            self.match("process plugin packet send m%x,%x" % (pc, size), ["response:", binascii.hexlify(memory)])
+
+        process.Continue()
+        self.assertEqual(process.GetState(), lldb.eStateExited, "Process exited")
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()
Index: source/Utility/StringExtractorGDBRemote.h
===================================================================
--- source/Utility/StringExtractorGDBRemote.h
+++ source/Utility/StringExtractorGDBRemote.h
@@ -145,6 +145,8 @@
         eServerPacketType_s,
         eServerPacketType_S,
         eServerPacketType_T,
+        eServerPacketType_x,
+        eServerPacketType_X,
         eServerPacketType_Z,
         eServerPacketType_z,
 
Index: source/Utility/StringExtractorGDBRemote.cpp
===================================================================
--- source/Utility/StringExtractorGDBRemote.cpp
+++ source/Utility/StringExtractorGDBRemote.cpp
@@ -310,6 +310,12 @@
       case 'S':
         return eServerPacketType_S;
 
+      case 'x':
+        return eServerPacketType_x;
+
+      case 'X':
+        return eServerPacketType_X;
+
       case 'T':
         return eServerPacketType_T;
 
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -3043,14 +3043,8 @@
     char packet[64];
     int packet_len;
     bool binary_memory_read = m_gdb_comm.GetxPacketSupported();
-    if (binary_memory_read)
-    {
-        packet_len = ::snprintf (packet, sizeof(packet), "x0x%" PRIx64 ",0x%" PRIx64, (uint64_t)addr, (uint64_t)size);
-    }
-    else
-    {
-        packet_len = ::snprintf (packet, sizeof(packet), "m%" PRIx64 ",%" PRIx64, (uint64_t)addr, (uint64_t)size);
-    }
+    packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,
+                            binary_memory_read ? 'x' : 'm', (uint64_t)addr, (uint64_t)size);
     assert (packet_len + 1 < (int)sizeof(packet));
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true) == GDBRemoteCommunication::PacketResult::Success)
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -202,8 +202,9 @@
     PacketResult
     Handle_interrupt (StringExtractorGDBRemote &packet);
 
+    // Handles $m and $x packets.
     PacketResult
-    Handle_m (StringExtractorGDBRemote &packet);
+    Handle_memory_read (StringExtractorGDBRemote &packet);
 
     PacketResult
     Handle_M (StringExtractorGDBRemote &packet);
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -113,7 +113,7 @@
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
                                   &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_m,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_m);
+                                  &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
                                   &GDBRemoteCommunicationServerLLGS::Handle_M);
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
@@ -164,6 +164,8 @@
                                   &GDBRemoteCommunicationServerLLGS::Handle_vCont);
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont_actions,
                                   &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
+    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_x,
+                                  &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
                                   &GDBRemoteCommunicationServerLLGS::Handle_Z);
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
@@ -1975,7 +1977,7 @@
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_m (StringExtractorGDBRemote &packet)
+GDBRemoteCommunicationServerLLGS::Handle_memory_read(StringExtractorGDBRemote &packet)
 {
     Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
@@ -2008,7 +2010,7 @@
     {
         if (log)
             log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to read: zero-length packet", __FUNCTION__);
-        return PacketResult::Success;
+        return SendOKResponse();
     }
 
     // Allocate the response buffer.
@@ -2035,8 +2037,16 @@
     }
 
     StreamGDBRemote response;
-    for (size_t i = 0; i < bytes_read; ++i)
-        response.PutHex8(buf[i]);
+    packet.SetFilePos(0);
+    char kind = packet.GetChar('?');
+    if (kind == 'x')
+        response.PutEscapedBytes(buf.data(), byte_count);
+    else
+    {
+        assert(kind == 'm');
+        for (size_t i = 0; i < bytes_read; ++i)
+            response.PutHex8(buf[i]);
+    }
 
     return SendPacketNoLock(response.GetData(), response.GetSize());
 }
Index: examples/python/read_test.py
===================================================================
--- /dev/null
+++ examples/python/read_test.py
@@ -0,0 +1,72 @@
+#!/usr/bin/python
+
+#----------------------------------------------------------------------
+# Be sure to add the python path that points to the LLDB shared library.
+#
+# # To use this in the embedded python interpreter using "lldb" just
+# import it with the full path using the "command script import" 
+# command
+#   (lldb) command script import /path/to/cmdtemplate.py
+#----------------------------------------------------------------------
+
+import commands
+import platform
+import os
+import re
+import sys
+
+try: 
+    # Just try for LLDB in case PYTHONPATH is already correctly setup
+    import lldb
+except ImportError:
+    lldb_python_dirs = list()
+    # lldb is not in the PYTHONPATH, try some defaults for the current platform
+    platform_system = platform.system()
+    if platform_system == 'Darwin':
+        # On Darwin, try the currently selected Xcode directory
+        xcode_dir = commands.getoutput("xcode-select --print-path")
+        if xcode_dir:
+            lldb_python_dirs.append(os.path.realpath(xcode_dir + '/../SharedFrameworks/LLDB.framework/Resources/Python'))
+            lldb_python_dirs.append(xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
+        lldb_python_dirs.append('/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
+    success = False
+    for lldb_python_dir in lldb_python_dirs:
+        if os.path.exists(lldb_python_dir):
+            if not (sys.path.__contains__(lldb_python_dir)):
+                sys.path.append(lldb_python_dir)
+                try: 
+                    import lldb
+                except ImportError:
+                    pass
+                else:
+                    print 'imported lldb from: "%s"' % (lldb_python_dir)
+                    success = True
+                    break
+    if not success:
+        print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
+        sys.exit(1)
+
+import commands
+import optparse
+import shlex
+import string
+import struct
+import time
+
+    
+def test (debugger, command, result, dict):
+    target = debugger.GetSelectedTarget()
+    for size in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 3072, 3584, 4096]:
+        start = time.clock()
+        for i in range(0,100):
+            debugger.HandleCommand('process plugin packet send xb6fef000,%x'%size)
+        elapsed = time.clock()-start
+        print >>result, "Size %5d: %g ms per packet" % (size, elapsed*1000/100)
+        
+
+if __name__ == '__main__':
+    print 'error: this script is designed to be used within the embedded script interpreter in LLDB'
+elif getattr(lldb, 'debugger', None):
+    test.__doc__ = 'XXXX'
+    lldb.debugger.HandleCommand('command script add -f memory.test memfind')
+    print '"memfind" command installed, use the "--help" option for detailed help'
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to