diff options
Diffstat (limited to 'lldb/test/Shell/ExecControl/StopHook')
9 files changed, 260 insertions, 0 deletions
diff --git a/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-1.lldbinit b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-1.lldbinit new file mode 100644 index 00000000000..4ab5d56f036 --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-1.lldbinit @@ -0,0 +1 @@ +target stop-hook add -n b -o "expr ptr" diff --git a/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-2.lldbinit b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-2.lldbinit new file mode 100644 index 00000000000..31817bdaaa5 --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-2.lldbinit @@ -0,0 +1 @@ +target stop-hook add -f stop-hook.c -l 29 -e 34 -o "expr ptr" diff --git a/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-3.lldbinit b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-3.lldbinit new file mode 100644 index 00000000000..36e144deecc --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-3.lldbinit @@ -0,0 +1,3 @@ +target stop-hook add -f stop-hook.c -l 29 -e 34 +expr ptr +DONE diff --git a/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads-1.lldbinit b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads-1.lldbinit new file mode 100644 index 00000000000..004bd34abfb --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads-1.lldbinit @@ -0,0 +1,7 @@ +break set -f stop-hook-threads.cpp -p "Break here to set up the stop hook" +break set -f stop-hook-threads.cpp -p "Break here to test that the stop-hook" +run +target stop-hook add -G true +expr lldb_val += 1 +thread list +DONE diff --git a/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads-2.lldbinit b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads-2.lldbinit new file mode 100644 index 00000000000..3b7d23953c3 --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads-2.lldbinit @@ -0,0 +1,5 @@ +break set -f stop-hook-threads.cpp -p "Break here to set up the stop hook" +break set -f stop-hook-threads.cpp -p "Break here to test that the stop-hook" +run +target stop-hook add -x 2 -o "expr lldb_val += 1" -o "thread list" +target stop-hook add -G true -o "script print('Hit stop hook') diff --git a/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads.cpp b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads.cpp new file mode 100644 index 00000000000..46aae8346be --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads.cpp @@ -0,0 +1,79 @@ +//===-- stop-hook-threads.cpp -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <chrono> +#include <cstdio> +#include <mutex> +#include <random> +#include <thread> + +std::default_random_engine g_random_engine{std::random_device{}()}; +std::uniform_int_distribution<> g_distribution{0, 3000}; + +uint32_t g_val = 0; +uint32_t lldb_val = 0; + +uint32_t +access_pool (bool flag = false) +{ + static std::mutex g_access_mutex; + if (!flag) + g_access_mutex.lock(); + + uint32_t old_val = g_val; + if (flag) + g_val = old_val + 1; + + if (!flag) + g_access_mutex.unlock(); + return g_val; +} + +void +thread_func (uint32_t thread_index) +{ + // Break here to test that the stop-hook mechanism works for multiple threads. + printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index); + + uint32_t count = 0; + uint32_t val; + while (count++ < 4) + { + // random micro second sleep from zero to .3 seconds + int usec = g_distribution(g_random_engine); + printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec); + std::this_thread::sleep_for(std::chrono::microseconds{usec}); // Set break point at this line + + if (count < 2) + val = access_pool (); + else + val = access_pool (true); + + printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count); + } + printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index); +} + + +int main (int argc, char const *argv[]) +{ + std::thread threads[3]; + // Break here to set up the stop hook + printf("Stop hooks engaged.\n"); + // Create 3 threads + for (auto &thread : threads) + thread = std::thread{thread_func, std::distance(threads, &thread)}; + + // Join all of our threads + for (auto &thread : threads) + thread.join(); + + // print lldb_val so we can check it here. + printf ("lldb_val was set to: %d.\n", lldb_val); + return 0; +} diff --git a/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook.c b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook.c new file mode 100644 index 00000000000..e1b2579526d --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook.c @@ -0,0 +1,53 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <stdlib.h> + +int a(int); +int b(int); +int c(int); + +int a(int val) +{ + if (val <= 1) + return b(val); + else if (val >= 3) + return c(val); + + return val; +} + +int b(int val) +{ + int rc = c(val); + void *ptr = malloc(1024); + if (!ptr) // Set breakpoint here to test target stop-hook. + return -1; + else + printf("ptr=%p\n", ptr); // We should stop here after stepping. + return rc; // End of the line range for which stop-hook is to be run. +} + +int c(int val) +{ + return val + 3; +} + +int main (int argc, char const *argv[]) +{ + int A1 = a(1); + printf("a(1) returns %d\n", A1); + + int C2 = c(2); // Another breakpoint which is outside of the stop-hook range. + printf("c(2) returns %d\n", C2); + + int A3 = a(3); + printf("a(3) returns %d\n", A3); + + return 0; +} diff --git a/lldb/test/Shell/ExecControl/StopHook/stop-hook-threads.test b/lldb/test/Shell/ExecControl/StopHook/stop-hook-threads.test new file mode 100644 index 00000000000..edb95ffc25e --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/stop-hook-threads.test @@ -0,0 +1,35 @@ +# RUN: %clangxx -std=c++11 %p/Inputs/stop-hook-threads.cpp -g -o %t +# RUN: %lldb -b -s %p/Inputs/stop-hook-threads-1.lldbinit -s %s -f %t \ +# RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-NO-FILTER %s +# RUN: %lldb -b -s %p/Inputs/stop-hook-threads-2.lldbinit -s %s -f %t \ +# RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-FILTER %s +# XFAIL: system-netbsd +# UNSUPPORTED: system-windows +# This test is flakey and hangs on windows periodically: llvm.org/pr38373 +# UNSUPPORTED: system-linux, system-darwin + +thread list +break set -f stop-hook-threads.cpp -p "Set break point at this line" +target stop-hook list + +# CHECK: Hook: 1 +# CHECK-NEXT: State: enabled +# CHECK-NO-FILTER-NEXT: AutoContinue on +# CHECK-FILTER-NEXT: Thread +# CHECK-FILTER-NEXT: index: 2 +# CHECK-NEXT: Commands: +# CHECK-NEXT: expr lldb_val += 1 +# CHECK-NEXT: thread list + +# CHECK-FILTER: Hook: 2 +# CHECK-FILTER-NEXT: State: enabled +# CHECK-FILTER-NEXT: AutoContinue on +# CHECK-FILTER-NEXT: Commands: +# CHECK-FILTER-NEXT: script print('Hit stop hook') + +# Get the threads going +continue + +# Now make sure we hit the command the right number of times: +# CHECK-NO-FILTER: lldb_val was set to: 15. +# CHECK-FILTER: lldb_val was set to: 5. diff --git a/lldb/test/Shell/ExecControl/StopHook/stop-hook.test b/lldb/test/Shell/ExecControl/StopHook/stop-hook.test new file mode 100644 index 00000000000..ca6495ef14a --- /dev/null +++ b/lldb/test/Shell/ExecControl/StopHook/stop-hook.test @@ -0,0 +1,76 @@ +# RUN: %clang %p/Inputs/stop-hook.c -g -o %t +# Test setting stop-hook per-function +# RUN: %lldb -b -s %p/Inputs/stop-hook-1.lldbinit -s %s -f %t \ +# RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-FUNC %s +# Test setting stop-hook per-line range +# RUN: %lldb -b -s %p/Inputs/stop-hook-2.lldbinit -s %s -f %t | FileCheck %s +# Test setting stop-hook with multi-line expression +# RUN: %lldb -b -s %p/Inputs/stop-hook-3.lldbinit -s %s -f %t | FileCheck %s +# This test is not "unsupported" on Windows, but it fails because "expr ptr" +# does not evaluate correctly. However, the error message contains the expected +# string, so the test "passes" despite the fact that the commands failed +# llvm.org/pr40119 +# UNSUPPORTED: system-windows + +break set -f stop-hook.c -p "// Set breakpoint here to test target stop-hook" +break set -f stop-hook.c -p "// Another breakpoint which is outside of the stop-hook range" +target stop-hook list + +# CHECK: Hook: 1 +# CHECK-NEXT: State: enabled +# CHECK-NEXT: Specifier: +# CHECK-FUNC-NEXT: Function: b. +# CHECK-NEXT: Commands: +# CHECK-NEXT: expr ptr + +target stop-hook disable + +target stop-hook list +# CHECK: Hook: 1 +# CHECK-NEXT: State: disabled +# CHECK-NEXT: Specifier: +# CHECK-FUNC-NEXT: Function: b. +# CHECK-NEXT: Commands: +# CHECK-NEXT: expr ptr + +target stop-hook enable + +target stop-hook list +# CHECK: Hook: 1 +# CHECK-NEXT: State: enabled +# CHECK-NEXT: Specifier: +# CHECK-FUNC-NEXT: Function: b. +# CHECK-NEXT: Commands: +# CHECK-NEXT: expr ptr + +run +# Stopping inside of the stop hook range +# CHECK: (lldb) run +# CHECK-NEXT: (void *) $0 = 0x + +thread step-over +# Stepping inside of the stop hook range +# CHECK: (lldb) thread step-over +# CHECK-NEXT: (void *) $1 = 0x +# CHECK: ->{{.*}} // We should stop here after stepping. + +process continue +# Stopping outside of the stop hook range +# CHECK: (lldb) process continue +# CHECK-NOT: (void *) +# CHECK: ->{{.*}} // Another breakpoint which is outside of the stop-hook range. + +thread step-over +# Stepping inside of the stop hook range +# CHECK: (lldb) thread step-over +# CHECK-NOT: (void *) + +settings set auto-confirm true +target stop-hook delete + +target stop-hook list +# CHECK: (lldb) target stop-hook list +# CHECK-NOT: Hook: 1 +# CHECK: No stop hooks +# CHECK-NOT: Hook: 1 + |