[Lldb-commits] [lldb] caedbc3 - [lldb] [test/Register] Add read/write tests for multithreaded process

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 14 02:08:46 PDT 2020


Author: Michał Górny
Date: 2020-10-14T11:08:36+02:00
New Revision: caedbc317a5a4f046c345c136387e3ca199d8503

URL: https://github.com/llvm/llvm-project/commit/caedbc317a5a4f046c345c136387e3ca199d8503
DIFF: https://github.com/llvm/llvm-project/commit/caedbc317a5a4f046c345c136387e3ca199d8503.diff

LOG: [lldb] [test/Register] Add read/write tests for multithreaded process

Add a test to verify that 'register read' and 'register write' commands
work correctly in a multithreaded program, in particular that they read
or write registers for the correct thread.  The tests use locking
to ensure that events are serialized and the test can execute reliably.

Differential Revision: https://reviews.llvm.org/D89248

Added: 
    lldb/test/Shell/Register/Inputs/x86-multithread-read.cpp
    lldb/test/Shell/Register/Inputs/x86-multithread-write.cpp
    lldb/test/Shell/Register/x86-multithread-read.test
    lldb/test/Shell/Register/x86-multithread-write.test

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/lldb/test/Shell/Register/Inputs/x86-multithread-read.cpp b/lldb/test/Shell/Register/Inputs/x86-multithread-read.cpp
new file mode 100644
index 000000000000..c5f571fc1d2c
--- /dev/null
+++ b/lldb/test/Shell/Register/Inputs/x86-multithread-read.cpp
@@ -0,0 +1,61 @@
+#include <cstdint>
+#include <mutex>
+#include <thread>
+
+std::mutex t1_mutex, t2_mutex;
+
+struct test_data {
+  uint32_t eax;
+  uint32_t ebx;
+
+  struct alignas(16) {
+    uint64_t mantissa;
+    uint16_t sign_exp;
+  } st0;
+};
+
+void t_func(std::mutex &t_mutex, const test_data &t_data) {
+  std::lock_guard<std::mutex> t_lock(t_mutex);
+
+  asm volatile(
+    "finit\t\n"
+    "fldt %2\t\n"
+    "int3\n\t"
+    :
+    : "a"(t_data.eax), "b"(t_data.ebx), "m"(t_data.st0)
+    : "st"
+  );
+}
+
+int main() {
+  test_data t1_data = {
+    .eax = 0x05060708,
+    .ebx = 0x15161718,
+    .st0 = {0x8070605040302010, 0x4000},
+  };
+  test_data t2_data = {
+    .eax = 0x25262728,
+    .ebx = 0x35363738,
+    .st0 = {0x8171615141312111, 0xc000},
+  };
+
+  // block both threads from proceeding
+  std::unique_lock<std::mutex> m1_lock(t1_mutex);
+  std::unique_lock<std::mutex> m2_lock(t2_mutex);
+
+  // start both threads
+  std::thread t1(t_func, std::ref(t1_mutex), std::ref(t1_data));
+  std::thread t2(t_func, std::ref(t2_mutex), std::ref(t2_data));
+
+  // release lock on thread 1 to make it interrupt the program
+  m1_lock.unlock();
+  // wait for thread 1 to finish
+  t1.join();
+
+  // release lock on thread 2
+  m2_lock.unlock();
+  // wait for thread 2 to finish
+  t2.join();
+
+  return 0;
+}

diff  --git a/lldb/test/Shell/Register/Inputs/x86-multithread-write.cpp b/lldb/test/Shell/Register/Inputs/x86-multithread-write.cpp
new file mode 100644
index 000000000000..320f9e938e5b
--- /dev/null
+++ b/lldb/test/Shell/Register/Inputs/x86-multithread-write.cpp
@@ -0,0 +1,66 @@
+#include <cinttypes>
+#include <cstdint>
+#include <cstdio>
+#include <mutex>
+#include <thread>
+
+std::mutex t1_mutex, t2_mutex;
+
+struct test_data {
+  uint32_t eax;
+  uint32_t ebx;
+
+  struct alignas(16) {
+    uint8_t data[10];
+  } st0;
+};
+
+constexpr test_data filler = {
+  .eax = 0xffffffff,
+  .ebx = 0xffffffff,
+  .st0 = {{0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, 0x8f, 0x80, 0x40}},
+};
+
+void t_func(std::mutex &t_mutex) {
+  std::lock_guard<std::mutex> t_lock(t_mutex);
+  test_data out = filler;
+
+  asm volatile(
+    "finit\t\n"
+    "fldt %2\t\n"
+    "int3\n\t"
+    "fstpt %2\t\n"
+    : "+a"(out.eax), "+b"(out.ebx)
+    : "m"(out.st0)
+    : "memory", "st"
+  );
+
+  printf("eax = 0x%08" PRIx32 "\n", out.eax);
+  printf("ebx = 0x%08" PRIx32 "\n", out.ebx);
+  printf("st0 = { ");
+  for (int i = 0; i < sizeof(out.st0.data); ++i)
+    printf("0x%02" PRIx8 " ", out.st0.data[i]);
+  printf("}\n");
+}
+
+int main() {
+  // block both threads from proceeding
+  std::unique_lock<std::mutex> m1_lock(t1_mutex);
+  std::unique_lock<std::mutex> m2_lock(t2_mutex);
+
+  // start both threads
+  std::thread t1(t_func, std::ref(t1_mutex));
+  std::thread t2(t_func, std::ref(t2_mutex));
+
+  // release lock on thread 1 to make it interrupt the program
+  m1_lock.unlock();
+  // wait for thread 1 to finish
+  t1.join();
+
+  // release lock on thread 2
+  m2_lock.unlock();
+  // wait for thread 2 to finish
+  t2.join();
+
+  return 0;
+}

diff  --git a/lldb/test/Shell/Register/x86-multithread-read.test b/lldb/test/Shell/Register/x86-multithread-read.test
new file mode 100644
index 000000000000..6bff2b155758
--- /dev/null
+++ b/lldb/test/Shell/Register/x86-multithread-read.test
@@ -0,0 +1,23 @@
+# XFAIL: system-windows
+# REQUIRES: native && (target-x86 || target-x86_64)
+# RUN: %clangxx_host %p/Inputs/x86-multithread-read.cpp -o %t -pthread
+# RUN: %lldb -b -s %s %t | FileCheck %s
+
+process launch
+# CHECK: Process {{[0-9]+}} stopped
+
+register read --all
+# CHECK-DAG: eax = 0x05060708
+# CHECK-DAG: ebx = 0x15161718
+# CHECK-DAG: st{{(mm)?}}0 = {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x00 0x40}
+
+process continue
+# CHECK: Process {{[0-9]+}} stopped
+
+register read --all
+# CHECK-DAG: eax = 0x25262728
+# CHECK-DAG: ebx = 0x35363738
+# CHECK-DAG: st{{(mm)?}}0 = {0x11 0x21 0x31 0x41 0x51 0x61 0x71 0x81 0x00 0xc0}
+
+process continue
+# CHECK: Process {{[0-9]+}} exited with status = 0

diff  --git a/lldb/test/Shell/Register/x86-multithread-write.test b/lldb/test/Shell/Register/x86-multithread-write.test
new file mode 100644
index 000000000000..bf0cd33c44e0
--- /dev/null
+++ b/lldb/test/Shell/Register/x86-multithread-write.test
@@ -0,0 +1,31 @@
+# XFAIL: system-windows
+# XFAIL: system-darwin
+# REQUIRES: native && (target-x86 || target-x86_64)
+# RUN: %clangxx_host %p/Inputs/x86-multithread-write.cpp -o %t -pthread
+# RUN: %lldb -b -s %s %t | FileCheck %s
+
+process launch
+# CHECK: Process {{[0-9]+}} stopped
+
+register write eax 0x05060708
+register write ebx 0x15161718
+# TODO: the need to call 'read' is probably a bug in the Linux plugin
+register read st0
+register write st0 "{0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x00 0x40}"
+
+process continue
+# CHECK-DAG: eax = 0x05060708
+# CHECK-DAG: ebx = 0x15161718
+# CHECK-DAG: st0 = { 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x00 0x40 }
+# CHECK: Process {{[0-9]+}} stopped
+
+register write eax 0x25262728
+register write ebx 0x35363738
+register read st0
+register write st0 "{0x11 0x21 0x31 0x41 0x51 0x61 0x71 0x81 0x00 0xc0}"
+
+process continue
+# CHECK-DAG: eax = 0x25262728
+# CHECK-DAG: ebx = 0x35363738
+# CHECK-DAG: st0 = { 0x11 0x21 0x31 0x41 0x51 0x61 0x71 0x81 0x00 0xc0 }
+# CHECK: Process {{[0-9]+}} exited with status = 0


        


More information about the lldb-commits mailing list