[Lldb-commits] [lldb] r210116 - Added gdb-remote memory read ($m) test.

Todd Fiala todd.fiala at gmail.com
Tue Jun 3 11:09:56 PDT 2014


Author: tfiala
Date: Tue Jun  3 13:09:56 2014
New Revision: 210116

URL: http://llvm.org/viewvc/llvm-project?rev=210116&view=rev
Log:
Added gdb-remote memory read ($m) test.

Added set-memory:{content} and get-memory-address-hex: commands
to the test exe for gdb-remote.  Added a test that sets the content
via the inferior command line, then reads it back via gdb-remote
with $m.

Passing on debugserver.  Marked as fail on llgs.  Implementing
in the llgs branch next.

Modified:
    lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py
    lldb/trunk/test/tools/lldb-gdbserver/main.cpp

Modified: lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py?rev=210116&r1=210115&r2=210116&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py (original)
+++ lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py Tue Jun  3 13:09:56 2014
@@ -49,9 +49,8 @@ class LldbGdbServerTestCase(TestBase):
         self.set_inferior_startup_launch()
 
         # Uncomment this code to force only a single test to run (by name).
-        # if self._testMethodName != "test_Hc_then_Csignal_signals_correct_thread_launch_debugserver_dsym":
-        #   # print "skipping test {}".format(self._testMethodName)
-        #   self.skipTest("focusing on one test")
+        # if not re.search(r"m_packet_reads_memory", self._testMethodName):
+        #     self.skipTest("focusing on one test")
 
     def reset_test_sequence(self):
         self.test_sequence = GdbRemoteTestSequence(self.logger)
@@ -1223,6 +1222,68 @@ class LldbGdbServerTestCase(TestBase):
         self.set_inferior_startup_launch()
         self.Hc_then_Csignal_signals_correct_thread()
 
+    def m_packet_reads_memory(self):
+        # This is the memory we will write into the inferior and then ensure we can read back with $m.
+        MEMORY_CONTENTS = "Test contents 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"
+
+        # Start up the inferior.
+        procs = self.prep_debug_monitor_and_inferior(
+            inferior_args=["set-message:%s" % MEMORY_CONTENTS, "get-message-address-hex:", "sleep:5"])
+
+        # Run the process
+        self.test_sequence.add_log_lines(
+            [
+             # Start running after initial stop.
+             "read packet: $c#00",
+             # Match output line that prints the memory address of the message buffer within the inferior. 
+             # Note we require launch-only testing so we can get inferior otuput.
+             { "type":"output_match", "regex":r"^message address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"message_address"} },
+             # Now stop the inferior.
+             "read packet: {}".format(chr(03)),
+             # And wait for the stop notification.
+             {"direction":"send", "regex":r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture":{1:"stop_signo", 2:"stop_thread_id"} }],
+            True)
+
+        # Run the packet stream.
+        context = self.expect_gdbremote_sequence()
+        self.assertIsNotNone(context)
+
+        # Grab the message address.
+        self.assertIsNotNone(context.get("message_address"))
+        message_address = int(context.get("message_address"), 16)
+
+        # Grab contents from the inferior.
+        self.reset_test_sequence()
+        self.test_sequence.add_log_lines(
+            ["read packet: $m{0:x},{1:x}#00".format(message_address, len(MEMORY_CONTENTS)),
+             {"direction":"send", "regex":r"^\$(.+)#[0-9a-fA-F]{2}$", "capture":{1:"read_contents"} }],
+            True)
+
+        # Run the packet stream.
+        context = self.expect_gdbremote_sequence()
+        self.assertIsNotNone(context)
+
+        # Ensure what we read from inferior memory is what we wrote.
+        self.assertIsNotNone(context.get("read_contents"))
+        read_contents = context.get("read_contents").decode("hex")
+        self.assertEquals(read_contents, MEMORY_CONTENTS)
+        
+    @debugserver_test
+    @dsym_test
+    def test_m_packet_reads_memory_debugserver_dsym(self):
+        self.init_debugserver_test()
+        self.buildDsym()
+        self.set_inferior_startup_launch()
+        self.m_packet_reads_memory()
+
+    @llgs_test
+    @dwarf_test
+    @unittest2.expectedFailure()
+    def test_m_packet_reads_memory_llgs_dwarf(self):
+        self.init_llgs_test()
+        self.buildDwarf()
+        self.set_inferior_startup_launch()
+        self.m_packet_reads_memory()
 
 if __name__ == '__main__':
     unittest2.main()

Modified: lldb/trunk/test/tools/lldb-gdbserver/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-gdbserver/main.cpp?rev=210116&r1=210115&r2=210116&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-gdbserver/main.cpp (original)
+++ lldb/trunk/test/tools/lldb-gdbserver/main.cpp Tue Jun  3 13:09:56 2014
@@ -7,6 +7,8 @@
 #include <signal.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
+#include <time.h>
 #include <unistd.h>
 #include <vector>
 
@@ -20,6 +22,8 @@ int pthread_threadid_np(pthread_t,__uint
 static const char *const RETVAL_PREFIX = "retval:";
 static const char *const SLEEP_PREFIX  = "sleep:";
 static const char *const STDERR_PREFIX = "stderr:";
+static const char *const SET_MESSAGE_PREFIX = "set-message:";
+static const char *const GET_MESSAGE_ADDRESS_COMMAND = "get-message-address-hex:";
 
 static const char *const THREAD_PREFIX = "thread:";
 static const char *const THREAD_COMMAND_NEW = "new"; 
@@ -34,6 +38,8 @@ static pthread_mutex_t g_jump_buffer_mut
 static jmp_buf g_jump_buffer;
 static bool g_is_segfaulting = false;
 
+static char g_message[256];
+
 static void
 print_thread_id ()
 {
@@ -220,6 +226,22 @@ int main (int argc, char **argv)
 				// std::cout << "sleep result (call " << i << "): " << sleep_seconds_remaining << std::endl;
 			}
         }
+		else if (std::strstr (argv[i], SET_MESSAGE_PREFIX))
+		{
+			// Copy the contents after "set-message:" to the g_message buffer.
+			// Used for reading inferior memory and verifying contents match expectations.
+            strncpy (g_message, argv[i] + strlen (SET_MESSAGE_PREFIX), sizeof (g_message));
+
+			// Ensure we're null terminated.
+			g_message[sizeof (g_message) - 1] = '\0';
+			
+		}
+        else if (std::strstr (argv[i], GET_MESSAGE_ADDRESS_COMMAND))
+        {
+			pthread_mutex_lock (&g_print_mutex);
+            printf ("message address: %p\n", &g_message[0]);
+			pthread_mutex_unlock (&g_print_mutex);
+        }
 		else if (std::strstr (argv[i], THREAD_PREFIX))
 		{
 			// Check if we're creating a new thread.





More information about the lldb-commits mailing list