Rewrite stop-hook tests as a couple of FileCheck tests

Those tests were using pexpect and being flaky on some of ours bots.
This patch reimplmeents the tests usinf FileCheck, and it also
extends the test coverage to a few more stop-hook options.

llvm-svn: 347109
This commit is contained in:
Frederic Riss 2018-11-16 23:07:28 +00:00
parent 4fd065a4ac
commit d146e337ed
9 changed files with 120 additions and 322 deletions

View File

@ -14,7 +14,7 @@
#include <thread>
std::default_random_engine g_random_engine{std::random_device{}()};
std::uniform_int_distribution<> g_distribution{0, 3000000};
std::uniform_int_distribution<> g_distribution{0, 3000};
uint32_t g_val = 0;
@ -42,14 +42,14 @@ thread_func (uint32_t thread_index)
uint32_t count = 0;
uint32_t val;
while (count++ < 15)
while (count++ < 4)
{
// random micro second sleep from zero to 3 seconds
// 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});
std::this_thread::sleep_for(std::chrono::microseconds{usec}); // Set break point at this line
if (count < 7)
if (count < 2)
val = access_pool ();
else
val = access_pool (true);
@ -64,7 +64,6 @@ int main (int argc, char const *argv[])
{
std::thread threads[3];
printf ("Before turning all three threads loose...\n"); // Set break point at this line, and add a stop-hook.
// Create 3 threads
for (auto &thread : threads)
thread = std::thread{thread_func, std::distance(threads, &thread)};

View File

@ -0,0 +1,44 @@
# RUN: %cxx %p/Inputs/stop-hook-threads.cpp -g -o %t
# RUN: %lldb -b -s %s -O 'target create %t' \
# RUN: -O 'break set -f stop-hook-threads.cpp -p "Break here to test that the stop-hook"' \
# RUN: -O run \
# RUN: -O 'target stop-hook add' \
# RUN: -O "frame variable --show-globals g_val" \
# RUN: -O "thread list" \
# RUN: -O continue \
# RUN: -O DONE \
# RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-NO-FILTER %s
# RUN: %lldb -b -s %s \
# RUN: -O 'target create %t' \
# RUN: -O 'break set -f stop-hook-threads.cpp -p "Break here to test that the stop-hook"' \
# RUN: -O run \
# RUN: -O 'target stop-hook add -x 2 -o "frame variable thread_index"' \
# RUN: -O 'target stop-hook add -o continue' \
# RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-FILTER %s
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-FILTER-NEXT: Thread
# CHECK-FILTER-NEXT: index: 2
# CHECK-NEXT: Commands:
# CHECK-NEXT: frame variable
# CHECK-FILTER: Hook: 2
# CHECK-FILTER-NEXT: State: enabled
# CHECK-FILTER-NEXT: Commands:
# CHECK-FILTER-NEXT: continue
# Get the threads going
continue
# When we filter per thread, we expect exactly 4 identical "frame var" results
# CHECK-FILTER: (uint32_t) thread_index = [[THREAD_INDEX:[0-9]*]]
# CHECK-FILTER-COUNT-3: (uint32_t) thread_index = [[THREAD_INDEX]]
# CHECK-FILTER-NOT: thread_index
# When we don't filter, we expect to count 12 stopped threads in the thread list output
# CHECK-NO-FILTER-COUNT-12: at stop-hook-threads.cpp{{.*}} stop reason = breakpoint

View File

@ -0,0 +1,71 @@
# RUN: %cc %p/Inputs/stop-hook.c -g -o %t
# Test setting stop-hook per-function
# RUN: %lldb -b -s %s -O 'target create %t' -O 'target stop-hook add -n b -o "expr ptr"' \
# RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-FUNC %s
# Test setting stop-hook per-line range
# RUN: %lldb -b -s %s -O 'target create %t' -O 'target stop-hook add -f stop-hook.c -l 30 -e 34 -o "expr ptr"' | FileCheck %s
# Test setting stop-hook with multi-line expression
# RUN: %lldb -b -s %s -O 'target create %t' -O 'target stop-hook add -f stop-hook.c -l 30 -e 34' -O 'expr ptr' -O DONE | FileCheck %s
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

View File

@ -1,5 +0,0 @@
LEVEL = ../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -1,77 +0,0 @@
"""
Test lldb target stop-hook command.
"""
from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class StopHookCmdTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line numbers inside main.cpp.
self.begl = line_number(
'main.cpp',
'// Set breakpoint here to test target stop-hook.')
self.endl = line_number(
'main.cpp',
'// End of the line range for which stop-hook is to be run.')
self.line = line_number(
'main.cpp',
'// Another breakpoint which is outside of the stop-hook range.')
@no_debug_info_test
def test_not_crashing_if_no_target(self):
"""target stop-hook list should not crash if no target has been set."""
self.runCmd("target stop-hook list", check=False)
def test(self):
"""Test a sequence of target stop-hook commands."""
self.build()
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
lldbutil.run_break_set_by_file_and_line(
self, "main.cpp", self.begl, num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd(
"target stop-hook add -f main.cpp -l %d -e %d -o 'expr ptr'" %
(self.begl, self.endl))
self.expect('target stop-hook list', 'Stop Hook added successfully',
substrs=['State: enabled',
'expr ptr'])
self.runCmd('target stop-hook disable')
self.expect('target stop-hook list', 'Stop Hook disabled successfully',
substrs=['State: disabled',
'expr ptr'])
self.runCmd('target stop-hook enable')
self.expect('target stop-hook list', 'Stop Hook enabled successfully',
substrs=['State: enabled',
'expr ptr'])
self.runCmd("settings set auto-confirm true")
self.addTearDownHook(
lambda: self.runCmd("settings clear auto-confirm"))
self.runCmd('target stop-hook delete')
self.expect('target stop-hook list', 'Stop Hook deleted successfully',
substrs=['No stop hooks.'])

View File

@ -1,128 +0,0 @@
"""
Test lldb target stop-hook mechanism to see whether it fires off correctly .
"""
from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import configuration
from lldbsuite.test import lldbutil
class StopHookMechanismTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line numbers inside main.cpp.
self.begl = line_number(
'main.cpp',
'// Set breakpoint here to test target stop-hook.')
self.endl = line_number(
'main.cpp',
'// End of the line range for which stop-hook is to be run.')
self.correct_step_line = line_number(
'main.cpp', '// We should stop here after stepping.')
self.line = line_number(
'main.cpp',
'// Another breakpoint which is outside of the stop-hook range.')
@skipIfFreeBSD # llvm.org/pr15037
# stop-hooks sometimes fail to fire on Linux
@expectedFlakeyLinux('llvm.org/pr15037')
@expectedFailureAll(
hostoslist=["windows"],
bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIf(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k']) # <rdar://problem/34582291> problem with armv7 and step-over and stop-hook firing on ios etc systems
def test(self):
"""Test the stop-hook mechanism."""
self.build()
import pexpect
exe = self.getBuildArtifact("a.out")
prompt = "(lldb) "
add_prompt = "Enter your stop hook command(s). Type 'DONE' to end."
add_prompt1 = "> "
# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s %s' %
(lldbtest_config.lldbExec, self.lldbOption))
child = self.child
# Turn on logging for what the child sends back.
if self.TraceOn():
child.logfile_read = sys.stdout
if lldb.remote_platform:
child.expect_exact(prompt)
child.sendline(
'platform select %s' %
lldb.remote_platform.GetName())
child.expect_exact(prompt)
child.sendline(
'platform connect %s' %
configuration.lldb_platform_url)
child.expect_exact(prompt)
child.sendline(
'platform settings -w %s' %
configuration.lldb_platform_working_dir)
child.expect_exact(prompt)
child.sendline('target create %s' % exe)
# Set the breakpoint, followed by the target stop-hook commands.
child.expect_exact(prompt)
child.sendline('breakpoint set -f main.cpp -l %d' % self.begl)
child.expect_exact(prompt)
child.sendline('breakpoint set -f main.cpp -l %d' % self.line)
child.expect_exact(prompt)
child.sendline(
'target stop-hook add -f main.cpp -l %d -e %d' %
(self.begl, self.endl))
child.expect_exact(add_prompt)
child.expect_exact(add_prompt1)
child.sendline('expr ptr')
child.expect_exact(add_prompt1)
child.sendline('DONE')
child.expect_exact(prompt)
child.sendline('target stop-hook list')
# Now run the program, expect to stop at the first breakpoint which is
# within the stop-hook range.
child.expect_exact(prompt)
child.sendline('run')
# Make sure we see the stop hook text from the stop of the process from
# the run hitting the first breakpoint
child.expect_exact('(void *) $')
child.expect_exact(prompt)
child.sendline('thread step-over')
# Expecting to find the output emitted by the firing of our stop hook.
child.expect_exact('(void *) $')
# This is orthogonal to the main stop hook test, but this example shows a bug in
# CLANG where the line table entry for the "return -1" actually includes some code
# from the other branch of the if/else, so we incorrectly stop at the "return -1" line.
# I fixed that in lldb and I'm sticking in a test here because I don't want to have to
# make up a whole nother test case for it.
child.sendline('frame info')
at_line = 'at main.cpp:%d' % (self.correct_step_line)
print('expecting "%s"' % at_line)
child.expect_exact(at_line)
# Now continue the inferior, we'll stop at another breakpoint which is
# outside the stop-hook range.
child.sendline('process continue')
child.expect_exact(
'// Another breakpoint which is outside of the stop-hook range.')
# self.DebugPExpect(child)
child.sendline('thread step-over')
child.expect_exact(
'// Another breakpoint which is outside of the stop-hook range.')
# self.DebugPExpect(child)
# Verify that the 'Stop Hooks' mechanism is NOT BEING fired off.
self.expect(child.before, exe=False, matching=False,
substrs=['(void *) $'])

View File

@ -1,6 +0,0 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
include $(LEVEL)/Makefile.rules

View File

@ -1,100 +0,0 @@
"""
Test that lldb stop-hook works for multiple threads.
"""
from __future__ import print_function
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import configuration
from lldbsuite.test import lldbutil
class StopHookForMultipleThreadsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Our simple source filename.
self.source = 'main.cpp'
# Find the line number to break inside main().
self.first_stop = line_number(
self.source, '// Set break point at this line, and add a stop-hook.')
self.thread_function = line_number(
self.source,
'// Break here to test that the stop-hook mechanism works for multiple threads.')
# Build dictionary to have unique executable names for each test
# method.
self.exe_name = self.testMethodName
self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
@expectedFlakeyFreeBSD("llvm.org/pr15037")
# stop hooks sometimes fail to fire on Linux
@expectedFlakeyLinux("llvm.org/pr15037")
@expectedFailureAll(
hostoslist=["windows"],
bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_stop_hook_multiple_threads(self):
"""Test that lldb stop-hook works for multiple threads."""
self.build(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
import pexpect
exe = self.getBuildArtifact(self.exe_name)
prompt = "(lldb) "
# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s %s' %
(lldbtest_config.lldbExec, self.lldbOption))
child = self.child
# Turn on logging for what the child sends back.
if self.TraceOn():
child.logfile_read = sys.stdout
if lldb.remote_platform:
child.expect_exact(prompt)
child.sendline(
'platform select %s' %
lldb.remote_platform.GetName())
child.expect_exact(prompt)
child.sendline(
'platform connect %s' %
configuration.lldb_platform_url)
child.expect_exact(prompt)
child.sendline(
'platform settings -w %s' %
configuration.lldb_platform_working_dir)
child.expect_exact(prompt)
child.sendline('target create %s' % exe)
# Set the breakpoint, followed by the target stop-hook commands.
child.expect_exact(prompt)
child.sendline('breakpoint set -f main.cpp -l %d' % self.first_stop)
child.expect_exact(prompt)
child.sendline(
'breakpoint set -f main.cpp -l %d' %
self.thread_function)
child.expect_exact(prompt)
# Now run the program, expect to stop at the first breakpoint which is
# within the stop-hook range.
child.sendline('run')
# 'Process 2415 launched', 'Process 2415 stopped'
child.expect_exact("Process")
child.expect_exact(prompt)
child.sendline(
'target stop-hook add -o "frame variable --show-globals g_val"')
child.expect_exact("Stop hook") # 'Stop hook #1 added.'
child.expect_exact(prompt)
# Continue and expect to find the output emitted by the firing of our
# stop hook.
child.sendline('continue')
child.expect_exact('(uint32_t) ::g_val = ')