diff options
| -rw-r--r-- | lldb/test/lldbtest.py | 16 | ||||
| -rw-r--r-- | lldb/test/stop-hook/Makefile | 5 | ||||
| -rw-r--r-- | lldb/test/stop-hook/TestStopHook.py | 88 | ||||
| -rw-r--r-- | lldb/test/stop-hook/main.cpp | 54 |
4 files changed, 163 insertions, 0 deletions
diff --git a/lldb/test/lldbtest.py b/lldb/test/lldbtest.py index dab27177470..cba495b2afc 100644 --- a/lldb/test/lldbtest.py +++ b/lldb/test/lldbtest.py @@ -523,6 +523,10 @@ class TestBase(unittest2.TestCase): # We want our debugger to be synchronous. self.dbg.SetAsync(False) + # This is for the case of directly spawning 'lldb' and interacting with it + # using pexpect. + self.child = None + # There is no process associated with the debugger as yet. # See also self.tearDown() where it checks whether self.process has a # valid reference and calls self.process.Kill() to kill the process. @@ -658,6 +662,12 @@ class TestBase(unittest2.TestCase): print >> sbuf, "Executing tearDown hook:", getsource_if_available(hook) hook() + # This is for the case of directly spawning 'lldb' and interacting with it + # using pexpect. + if self.child and self.child.isalive(): + self.child.sendline('quit') + self.child.close() + # Terminate the current process being debugged, if any. if self.runStarted: self.runCmd("process kill", PROCESS_KILLED, check=False) @@ -916,3 +926,9 @@ class TestBase(unittest2.TestCase): err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n') err.write('\t' + "Location -> " + val.GetLocation(frame) + '\n') + def DebugPExpect(self, child): + """Debug the spwaned pexpect object.""" + if not traceAlways: + return + + print child diff --git a/lldb/test/stop-hook/Makefile b/lldb/test/stop-hook/Makefile new file mode 100644 index 00000000000..d4bc9c68904 --- /dev/null +++ b/lldb/test/stop-hook/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/stop-hook/TestStopHook.py b/lldb/test/stop-hook/TestStopHook.py new file mode 100644 index 00000000000..6123c6cdc33 --- /dev/null +++ b/lldb/test/stop-hook/TestStopHook.py @@ -0,0 +1,88 @@ +""" +Test lldb target stop-hook command. +""" + +import os +import unittest2 +import lldb +import pexpect +from lldbtest import * + +class StopHookTestCase(TestBase): + + mydir = "stop-hook" + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym(self): + """Test a sequence of target add-hook commands.""" + self.buildDsym() + self.stop_hook_command_sequence() + + def test_with_dwarf(self): + """Test a sequence of target add-hook commands.""" + self.buildDwarf() + self.stop_hook_command_sequence() + + 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.') + + def stop_hook_command_sequence(self): + """Test a sequence of target stop-hook commands.""" + exe = os.path.join(os.getcwd(), "a.out") + prompt = "\r\n\(lldb\) " + add_prompt = "Enter your stop hook command\(s\). Type 'DONE' to end.\r\n> " + add_prompt1 = "\r\n> " + + child = pexpect.spawn('%s %s' % (self.lldbExec, exe)) + # Turn on logging for what the child sends back. + if traceAlways: + child.logfile_read = sys.stdout + + # Set the breakpoint, followed by the target stop-hook commands. + child.expect(prompt) + child.sendline('breakpoint set -f main.cpp -l %d' % self.begl) + child.expect(prompt) + child.sendline('breakpoint set -f main.cpp -l %d' % self.line) + child.expect(prompt) + child.sendline('target stop-hook add -f main.cpp -l %d -e %d' % (self.begl, self.endl)) + child.expect(add_prompt) + child.sendline('expr ptr') + child.expect(add_prompt1) + child.sendline('DONE') + child.expect(prompt) + child.sendline('target stop-hook list') + + # Now run the program, expect to stop at the the first breakpoint which is within the stop-hook range. + child.expect(prompt) + child.sendline('run') + child.expect(prompt) + self.DebugPExpect(child) + child.sendline('thread step-over') + child.expect(prompt) + self.DebugPExpect(child) + # Verify that the 'Stop Hooks' mechanism is fired off. + self.expect(child.before, exe=False, + substrs = ['Stop Hooks']) + + # Now continue the inferior, we'll stop at another breakpoint which is outside the stop-hook range. + child.sendline('process continue') + child.expect(prompt) + self.DebugPExpect(child) + child.sendline('thread step-over') + child.expect(prompt) + self.DebugPExpect(child) + # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off. + self.expect(child.before, exe=False, matching=False, + substrs = ['Stop Hooks']) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/stop-hook/main.cpp b/lldb/test/stop-hook/main.cpp new file mode 100644 index 00000000000..095a37a1a45 --- /dev/null +++ b/lldb/test/stop-hook/main.cpp @@ -0,0 +1,54 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#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); + 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 B2 = b(2); // Another breakpoint which is outside of the stop-hook range. + printf("b(2) returns %d\n", B2); + + int A3 = a(3); + printf("a(3) returns %d\n", A3); + + return 0; +} |

