teak-llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py
Jason Molenda 2d5d71c061 Revert this patch; I was emailing with Eugene and they have some other changes going
in today and don't want the two changes to confuse the situation with the build bots.
I'll commit tomorrow once they're known good.

llvm-svn: 313934
2017-09-21 23:02:56 +00:00

504 lines
21 KiB
Python

"""
Test lldb-mi -exec-xxx commands.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiExecTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@expectedFailureAll(
oslist=["linux"],
bugnumber="llvm.org/pr25000: lldb-mi does not receive broadcasted notification from Core/Process about process stopped")
def test_lldbmi_exec_run(self):
"""Test that 'lldb-mi --interpreter' can stop at entry."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Test that program is stopped at entry
self.runCmd("-exec-run --start")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",.*?thread-id=\"1\",stopped-threads=\"all\"")
# Test that lldb-mi is ready to execute next commands
self.expect(self.child_prompt, exactly=True)
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_abort(self):
"""Test that 'lldb-mi --interpreter' works for -exec-abort."""
self.spawnLldbMi(args=None)
# Test that -exec-abort fails on invalid process
self.runCmd("-exec-abort")
self.expect(
"\^error,msg=\"Command 'exec-abort'\. Invalid process during debug session\"")
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set arguments
self.runCmd("-exec-arguments arg1")
self.expect("\^done")
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that arguments were passed
self.runCmd("-data-evaluate-expression argc")
self.expect("\^done,value=\"2\"")
# Test that program may be aborted
self.runCmd("-exec-abort")
self.expect("\^done")
self.expect("\*stopped,reason=\"exited-normally\"")
# Test that program can be run again
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that arguments were passed again
self.runCmd("-data-evaluate-expression argc")
self.expect("\^done,value=\"2\"")
# Test that program may be aborted again
self.runCmd("-exec-abort")
self.expect("\^done")
self.expect("\*stopped,reason=\"exited-normally\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_arguments_set(self):
"""Test that 'lldb-mi --interpreter' can pass args using -exec-arguments."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set arguments
self.runCmd(
"-exec-arguments --arg1 \"2nd arg\" third_arg fourth=\"4th arg\"")
self.expect("\^done")
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Check argc and argv to see if arg passed
# Note that exactly=True is needed to avoid extra escaping for re
self.runCmd("-data-evaluate-expression argc")
self.expect("\^done,value=\"5\"")
#self.runCmd("-data-evaluate-expression argv[1]")
# self.expect("\^done,value=\"--arg1\"")
self.runCmd("-interpreter-exec command \"print argv[1]\"")
self.expect("\\\"--arg1\\\"", exactly=True)
#self.runCmd("-data-evaluate-expression argv[2]")
#self.expect("\^done,value=\"2nd arg\"")
self.runCmd("-interpreter-exec command \"print argv[2]\"")
self.expect("\\\"2nd arg\\\"", exactly=True)
#self.runCmd("-data-evaluate-expression argv[3]")
# self.expect("\^done,value=\"third_arg\"")
self.runCmd("-interpreter-exec command \"print argv[3]\"")
self.expect("\\\"third_arg\\\"", exactly=True)
#self.runCmd("-data-evaluate-expression argv[4]")
#self.expect("\^done,value=\"fourth=\\\\\\\"4th arg\\\\\\\"\"")
self.runCmd("-interpreter-exec command \"print argv[4]\"")
self.expect("\\\"fourth=\\\\\\\"4th arg\\\\\\\"\\\"", exactly=True)
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_arguments_reset(self):
"""Test that 'lldb-mi --interpreter' can reset previously set args using -exec-arguments."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set arguments
self.runCmd("-exec-arguments arg1")
self.expect("\^done")
self.runCmd("-exec-arguments")
self.expect("\^done")
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Check argc to see if arg passed
self.runCmd("-data-evaluate-expression argc")
self.expect("\^done,value=\"1\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_next(self):
"""Test that 'lldb-mi --interpreter' works for stepping."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Warning: the following is sensitive to the lines in the source
# Test -exec-next
self.runCmd("-exec-next --thread 1 --frame 0")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\"")
# Test that --thread is optional
self.runCmd("-exec-next --frame 0")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"")
# Test that --frame is optional
self.runCmd("-exec-next --thread 1")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"31\"")
# Test that both --thread and --frame are optional
self.runCmd("-exec-next")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"32\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-next --thread 0")
self.expect("\^error,message=\"error: Thread index 0 is out of range")
self.runCmd("-exec-next --thread 10")
self.expect("\^error,message=\"error: Thread index 10 is out of range")
# Test that an invalid --frame is handled
# FIXME: no error is returned
self.runCmd("-exec-next --frame 10")
#self.expect("\^error: Frame index 10 is out of range")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_next_instruction(self):
"""Test that 'lldb-mi --interpreter' works for instruction stepping."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Warning: the following is sensitive to the lines in the
# source and optimizations
# Test -exec-next-instruction
self.runCmd("-exec-next-instruction --thread 1 --frame 0")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"28\"")
# Test that --thread is optional
self.runCmd("-exec-next-instruction --frame 0")
self.expect("\^running")
# Depending on compiler, it can stop at different line
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(28|29)\"")
# Test that --frame is optional
self.runCmd("-exec-next-instruction --thread 1")
self.expect("\^running")
# Depending on compiler, it can stop at different line
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(28|29|30)\"")
# Test that both --thread and --frame are optional
self.runCmd("-exec-next-instruction")
self.expect("\^running")
# Depending on compiler, it can stop at different line
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(28|29|30|31)\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-next-instruction --thread 0")
self.expect("\^error,message=\"error: Thread index 0 is out of range")
self.runCmd("-exec-next-instruction --thread 10")
self.expect("\^error,message=\"error: Thread index 10 is out of range")
# Test that an invalid --frame is handled
# FIXME: no error is returned
self.runCmd("-exec-next-instruction --frame 10")
#self.expect("\^error: Frame index 10 is out of range")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_step(self):
"""Test that 'lldb-mi --interpreter' works for stepping into."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Warning: the following is sensitive to the lines in the source
# Test that -exec-step steps into (or not) printf depending on debug info
# Note that message is different in Darwin and Linux:
# Darwin: "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x[0-9a-f]+\",func=\"main\",args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value="0x[0-9a-f]+\"}],file=\"main.cpp\",fullname=\".+main.cpp\",line=\"\d\"},thread-id=\"1\",stopped-threads=\"all\"
# Linux:
# "*stopped,reason=\"end-stepping-range\",frame={addr="0x[0-9a-f]+\",func=\"__printf\",args=[{name=\"format\",value=\"0x[0-9a-f]+\"}],file=\"printf.c\",fullname=\".+printf.c\",line="\d+"},thread-id=\"1\",stopped-threads=\"all\"
self.runCmd("-exec-step --thread 1 --frame 0")
self.expect("\^running")
it = self.expect(["\*stopped,reason=\"end-stepping-range\".+?func=\"main\"",
"\*stopped,reason=\"end-stepping-range\".+?func=\"(?!main).+?\""])
# Exit from printf if needed
if it == 1:
self.runCmd("-exec-finish")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"main\"")
# Test that -exec-step steps into g_MyFunction and back out
# (and that --thread is optional)
self.runCmd("-exec-step --frame 0")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"")
# Use -exec-finish here to make sure that control reaches the caller.
# -exec-step can keep us in the g_MyFunction for gcc
self.runCmd("-exec-finish --frame 0")
self.expect("\^running")
it = self.expect(["\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"",
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\""])
if it == 1:
# Call to s_MyFunction may not follow immediately after g_MyFunction.
# There might be some instructions in between to restore caller-saved registers.
# We need to get past these instructions with a next to reach call to s_MyFunction.
self.runCmd("-exec-next --thread 1")
self.expect("\^running")
self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"")
# Test that -exec-step steps into s_MyFunction
# (and that --frame is optional)
self.runCmd("-exec-step --thread 1")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\".*?s_MyFunction.*?\"")
# Test that -exec-step steps into g_MyFunction from inside
# s_MyFunction (and that both --thread and --frame are optional)
self.runCmd("-exec-step")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-step --thread 0")
self.expect("\^error,message=\"error: Thread index 0 is out of range")
self.runCmd("-exec-step --thread 10")
self.expect("\^error,message=\"error: Thread index 10 is out of range")
# Test that an invalid --frame is handled
# FIXME: no error is returned
self.runCmd("-exec-step --frame 10")
#self.expect("\^error: Frame index 10 is out of range")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_step_instruction(self):
"""Test that 'lldb-mi --interpreter' works for instruction stepping into."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Warning: the following is sensitive to the lines in the
# source and optimizations
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that -exec-next steps over printf
self.runCmd("-exec-next --thread 1 --frame 0")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\"")
# Test that -exec-step-instruction steps over non branching
# instruction
self.runCmd("-exec-step-instruction --thread 1 --frame 0")
self.expect("\^running")
self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\"")
# Test that -exec-step-instruction steps into g_MyFunction
# instruction (and that --thread is optional)
# In case of MIPS, there might be more than one instruction
# before actual call instruction (like load, move and call instructions).
# The -exec-step-instruction would step one assembly instruction.
# Thus we may not enter into g_MyFunction function. The -exec-step would definitely
# step into the function.
if self.isMIPS():
self.runCmd("-exec-step --frame 0")
else:
self.runCmd("-exec-step-instruction --frame 0")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"")
# Test that -exec-step-instruction steps over non branching
# (and that --frame is optional)
self.runCmd("-exec-step-instruction --thread 1")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"")
# Test that -exec-step-instruction steps into g_MyFunction
# (and that both --thread and --frame are optional)
self.runCmd("-exec-step-instruction")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-step-instruction --thread 0")
self.expect("\^error,message=\"error: Thread index 0 is out of range")
self.runCmd("-exec-step-instruction --thread 10")
self.expect("\^error,message=\"error: Thread index 10 is out of range")
# Test that an invalid --frame is handled
# FIXME: no error is returned
self.runCmd("-exec-step-instruction --frame 10")
#self.expect("\^error: Frame index 10 is out of range")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_exec_finish(self):
"""Test that 'lldb-mi --interpreter' works for -exec-finish."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set BP at g_MyFunction and run to BP
self.runCmd("-break-insert -f g_MyFunction")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that -exec-finish returns from g_MyFunction
self.runCmd("-exec-finish --thread 1 --frame 0")
self.expect("\^running")
self.expect("\*stopped,reason=\"end-stepping-range\".+?func=\"main\"")
# Run to BP inside s_MyFunction call
self.runCmd("-break-insert s_MyFunction")
self.expect("\^done,bkpt={number=\"2\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that -exec-finish hits BP at g_MyFunction call inside
# s_MyFunction (and that --thread is optional)
self.runCmd("-exec-finish --frame 0")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that -exec-finish returns from g_MyFunction call inside
# s_MyFunction (and that --frame is optional)
self.runCmd("-exec-finish --thread 1")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\".*?s_MyFunction.*?\"")
# Test that -exec-finish returns from s_MyFunction
# (and that both --thread and --frame are optional)
self.runCmd("-exec-finish")
self.expect("\^running")
self.expect("\*stopped,reason=\"end-stepping-range\".+?func=\"main\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-finish --thread 0")
self.expect("\^error,message=\"error: Thread index 0 is out of range")
self.runCmd("-exec-finish --thread 10")
self.expect("\^error,message=\"error: Thread index 10 is out of range")
# Test that an invalid --frame is handled
# FIXME: no error is returned
#self.runCmd("-exec-finish --frame 10")
#self.expect("\^error: Frame index 10 is out of range")
# Set BP at printf and run to BP
self.runCmd("-break-insert -f printf")
self.expect("\^done,bkpt={number=\"3\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that -exec-finish returns from printf
self.runCmd("-exec-finish --thread 1 --frame 0")
self.expect("\^running")
self.expect("\*stopped,reason=\"end-stepping-range\".+?func=\"main\"")