[lldb][NFC] Cleanup mentions and code related to lldb-mi

Summary: lldb-mi has been removed, but there are still a bunch of references in the code base. This patch removes all of them.

Reviewers: JDevlieghere, jfb

Reviewed By: JDevlieghere

Subscribers: dexonsmith, ki.stfu, mgorny, abidh, jfb, lldb-commits

Tags: #lldb

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

llvm-svn: 366590
This commit is contained in:
Raphael Isemann 2019-07-19 15:55:23 +00:00
parent 0054230181
commit b45853f173
117 changed files with 1 additions and 15114 deletions

View File

@ -106,10 +106,6 @@ if(LLDB_INCLUDE_TESTS)
list(APPEND LLDB_TEST_DEPS lldb-server) list(APPEND LLDB_TEST_DEPS lldb-server)
endif() endif()
if(TARGET lldb-mi)
list(APPEND LLDB_TEST_DEPS lldb-mi)
endif()
if(TARGET lldb-vscode) if(TARGET lldb-vscode)
list(APPEND LLDB_TEST_DEPS lldb-vscode) list(APPEND LLDB_TEST_DEPS lldb-vscode)
endif() endif()

View File

@ -21,10 +21,6 @@ D: Watchpoints, Trampolines, Target, Command Interpreter, C++ / Objective-C Lang
D: Expression evaluator, IR interpreter, Clang integration D: Expression evaluator, IR interpreter, Clang integration
D: Data Formatters D: Data Formatters
N: Ilia K
E: ki.stfu@gmail.com
D: lldb-mi
N: Ed Maste N: Ed Maste
E: emaste@freebsd.org E: emaste@freebsd.org
D: FreeBSD D: FreeBSD
@ -34,10 +30,6 @@ E: jmolenda@apple.com
D: ABI, Disassembler, Unwinding, iOS, debugserver, Platform, ObjectFile, SymbolFile, D: ABI, Disassembler, Unwinding, iOS, debugserver, Platform, ObjectFile, SymbolFile,
D: SymbolVendor, DWARF, gdb-remote D: SymbolVendor, DWARF, gdb-remote
N: Hafiz Abid Qadeer
E: abidh.haq@gmail.com
D: lldb-mi
N: Kamil Rytarowski N: Kamil Rytarowski
E: kamil@netbsd.org E: kamil@netbsd.org
D: NetBSD D: NetBSD

View File

@ -16,11 +16,6 @@ def use_lldb_substitutions(config):
dsname = 'debugserver' if platform.system() in ['Darwin'] else 'lldb-server' dsname = 'debugserver' if platform.system() in ['Darwin'] else 'lldb-server'
dsargs = [] if platform.system() in ['Darwin'] else ['gdbserver'] dsargs = [] if platform.system() in ['Darwin'] else ['gdbserver']
lldbmi = ToolSubst('%lldbmi',
command=FindTool('lldb-mi'),
extra_args=['--synchronous'],
unresolved='ignore')
build_script = os.path.dirname(__file__) build_script = os.path.dirname(__file__)
build_script = os.path.join(build_script, 'build.py') build_script = os.path.join(build_script, 'build.py')
@ -43,7 +38,6 @@ def use_lldb_substitutions(config):
ToolSubst('%lldb-init', ToolSubst('%lldb-init',
command=FindTool('lldb'), command=FindTool('lldb'),
extra_args=['-S', lldb_init]), extra_args=['-S', lldb_init]),
lldbmi,
ToolSubst('%debugserver', ToolSubst('%debugserver',
command=FindTool(dsname), command=FindTool(dsname),
extra_args=dsargs, extra_args=dsargs,
@ -61,9 +55,6 @@ def use_lldb_substitutions(config):
llvm_config.add_tool_substitutions(primary_tools, llvm_config.add_tool_substitutions(primary_tools,
[config.lldb_tools_dir]) [config.lldb_tools_dir])
# lldb-mi always fails without Python support
if lldbmi.was_resolved and not config.lldb_disable_python:
config.available_features.add('lldb-mi')
def _use_msvc_substitutions(config): def _use_msvc_substitutions(config):
# If running from a Visual Studio Command prompt (e.g. vcvars), this will # If running from a Visual Studio Command prompt (e.g. vcvars), this will

View File

@ -693,16 +693,11 @@ def setupSysPath():
os.environ["LLDB_SRC"] = lldbsuite.lldb_root os.environ["LLDB_SRC"] = lldbsuite.lldb_root
pluginPath = os.path.join(scriptPath, 'plugins') pluginPath = os.path.join(scriptPath, 'plugins')
toolsLLDBMIPath = os.path.join(scriptPath, 'tools', 'lldb-mi')
toolsLLDBVSCode = os.path.join(scriptPath, 'tools', 'lldb-vscode') toolsLLDBVSCode = os.path.join(scriptPath, 'tools', 'lldb-vscode')
toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server') toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server')
# Insert script dir, plugin dir, lldb-mi dir and lldb-server dir to the # Insert script dir, plugin dir and lldb-server dir to the sys.path.
# sys.path.
sys.path.insert(0, pluginPath) sys.path.insert(0, pluginPath)
# Adding test/tools/lldb-mi to the path makes it easy
sys.path.insert(0, toolsLLDBMIPath)
# to "import lldbmi_testcase" from the MI tests
# Adding test/tools/lldb-vscode to the path makes it easy to # Adding test/tools/lldb-vscode to the path makes it easy to
# "import lldb_vscode_testcase" from the VSCode tests # "import lldb_vscode_testcase" from the VSCode tests
sys.path.insert(0, toolsLLDBVSCode) sys.path.insert(0, toolsLLDBVSCode)
@ -761,19 +756,7 @@ def setupSysPath():
print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"]) print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"])
os.system('%s -v' % lldbtest_config.lldbExec) os.system('%s -v' % lldbtest_config.lldbExec)
# Assume lldb-mi is in same place as lldb
# If not found, disable the lldb-mi tests
# TODO: Append .exe on Windows
# - this will be in a separate commit in case the mi tests fail horribly
lldbDir = os.path.dirname(lldbtest_config.lldbExec) lldbDir = os.path.dirname(lldbtest_config.lldbExec)
lldbMiExec = os.path.join(lldbDir, "lldb-mi")
if is_exe(lldbMiExec):
os.environ["LLDBMI_EXEC"] = lldbMiExec
else:
if not configuration.shouldSkipBecauseOfCategories(["lldb-mi"]):
print(
"The 'lldb-mi' executable cannot be located. The lldb-mi tests can not be run as a result.")
configuration.skipCategories.append("lldb-mi")
lldbVSCodeExec = os.path.join(lldbDir, "lldb-vscode") lldbVSCodeExec = os.path.join(lldbDir, "lldb-vscode")
if is_exe(lldbVSCodeExec): if is_exe(lldbVSCodeExec):

View File

@ -711,11 +711,6 @@ class Base(unittest2.TestCase):
else: else:
self.libcxxPath = None self.libcxxPath = None
if "LLDBMI_EXEC" in os.environ:
self.lldbMiExec = os.environ["LLDBMI_EXEC"]
else:
self.lldbMiExec = None
if "LLDBVSCODE_EXEC" in os.environ: if "LLDBVSCODE_EXEC" in os.environ:
self.lldbVSCodeExec = os.environ["LLDBVSCODE_EXEC"] self.lldbVSCodeExec = os.environ["LLDBVSCODE_EXEC"]
else: else:

View File

@ -34,7 +34,6 @@ all_categories = {
'dyntype': 'Tests related to dynamic type support', 'dyntype': 'Tests related to dynamic type support',
'stresstest': 'Tests related to stressing lldb limits', 'stresstest': 'Tests related to stressing lldb limits',
'flakey': 'Flakey test cases, i.e. tests that do not reliably pass at each execution', 'flakey': 'Flakey test cases, i.e. tests that do not reliably pass at each execution',
'lldb-mi': 'lldb-mi tests',
'darwin-log': 'Darwin log tests', 'darwin-log': 'Darwin log tests',
'watchpoint': 'Watchpoint-related tests', 'watchpoint': 'Watchpoint-related tests',
} }

View File

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

View File

@ -1,38 +0,0 @@
"""
Test lldb-mi -environment-cd command.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiEnvironmentCdTestCase(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
@skipIfDarwin # Disabled while I investigate the failure on buildbot.
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_environment_cd(self):
"""Test that 'lldb-mi --interpreter' changes working directory for inferior."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# cd to a different directory
self.runCmd("-environment-cd /tmp")
self.expect("\^done")
# Run to the end
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("@\"cwd: /tmp\\r\\n\"", exactly=True)

View File

@ -1,60 +0,0 @@
"""
Test lldb-mi =library-loaded notifications.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiLibraryLoadedTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_library_loaded(self):
"""Test that 'lldb-mi --interpreter' shows the =library-loaded notifications."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Test =library-loaded
import os
path = self.getBuildArtifact(self.myexe)
symbols_path = os.path.join(
path + ".dSYM",
"Contents",
"Resources",
"DWARF",
"a.out")
def add_slashes(x): return x.replace(
"\\",
"\\\\").replace(
"\"",
"\\\"").replace(
"\'",
"\\\'").replace(
"\0",
"\\\0")
self.expect(
[
"=library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded=\"1\",symbols-path=\"%s\",loaded_addr=\"-\",size=\"[0-9]+\"" %
(add_slashes(path),
add_slashes(path),
add_slashes(path),
add_slashes(symbols_path)),
"=library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded=\"0\",loaded_addr=\"-\",size=\"[0-9]+\"" %
(add_slashes(path),
add_slashes(path),
add_slashes(path))])

View File

@ -1,58 +0,0 @@
"""
Test that the lldb-mi driver prints prompt properly.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiPromptTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_prompt(self):
"""Test that 'lldb-mi --interpreter' echos '(gdb)' after commands and events."""
self.spawnLldbMi(args=None)
# Test that lldb-mi is ready after unknown command
self.runCmd("-unknown-command")
self.expect(
"\^error,msg=\"Driver\. Received command '-unknown-command'\. It was not handled\. Command 'unknown-command' not in Command Factory\"")
self.expect(self.child_prompt, exactly=True)
# Test that lldb-mi is ready after -file-exec-and-symbols
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
self.expect(self.child_prompt, exactly=True)
# Test that lldb-mi is ready after -break-insert
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.expect(self.child_prompt, exactly=True)
# Test that lldb-mi is ready after -exec-run
self.runCmd("-exec-run")
self.expect("\*running")
self.expect(self.child_prompt, exactly=True)
# Test that lldb-mi is ready after BP hit
self.expect("\*stopped,reason=\"breakpoint-hit\"")
self.expect(self.child_prompt, exactly=True)
# Test that lldb-mi is ready after -exec-continue
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect(self.child_prompt, exactly=True)
# Test that lldb-mi is ready after program exited
self.expect("\*stopped,reason=\"exited-normally\"")
self.expect(self.child_prompt, exactly=True)

View File

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

View File

@ -1,361 +0,0 @@
"""
Test lldb-mi -break-xxx commands.
"""
from __future__ import print_function
import unittest2
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiBreakTestCase(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
@skipIfLinux # llvm.org/pr24717
@expectedFailureNetBSD
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_break_insert_function_pending(self):
"""Test that 'lldb-mi --interpreter' works for pending function breakpoints."""
self.spawnLldbMi(args=None)
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
self.runCmd("-break-insert -f printf")
# FIXME function name is unknown on Darwin, fullname should be ??, line is -1
# self.expect("\^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0xffffffffffffffff\",func=\"printf\",file=\"\?\?\",fullname=\"\?\?\",line=\"-1\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}")
self.expect(
"\^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0xffffffffffffffff\",func=\"\?\?\",file=\"\?\?\",fullname=\"\?\?/\?\?\",line=\"0\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}")
# FIXME function name is unknown on Darwin, fullname should be ??, line -1
# self.expect("=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0xffffffffffffffff\",func=\"printf\",file=\"\?\?\",fullname=\"\?\?\",line=\"-1\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}")
self.expect(
"=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0xffffffffffffffff\",func=\"\?\?\",file=\"\?\?\",fullname=\"\?\?/\?\?\",line=\"0\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect(
"=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@expectedFailureNetBSD
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_break_insert_function(self):
"""Test that 'lldb-mi --interpreter' works for function breakpoints."""
self.spawnLldbMi(args=None)
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
self.runCmd("-break-insert -f main")
self.expect(
"\^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",pending=\[\"main\"\],times=\"0\",original-location=\"main\"}")
self.expect(
"=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",pending=\[\"main\"\],times=\"0\",original-location=\"main\"}")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect(
"=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",pending=\[\"main\"\],times=\"0\",original-location=\"main\"}")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that -break-insert can set non-pending BP
self.runCmd("-break-insert printf")
# FIXME function name is unknown on Darwin
# self.expect("\^done,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"printf\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",times=\"0\",original-location=\"printf\"}")
self.expect(
"\^done,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",times=\"0\",original-location=\"printf\"}")
# FIXME function name is unknown on Darwin
# self.expect("=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"printf\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",times=\"0\",original-location=\"printf\"}")
self.expect(
"=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",times=\"0\",original-location=\"printf\"}")
# FIXME function name is unknown on Darwin
# self.expect("=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"printf\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",times=\"0\",original-location=\"printf\"}")
self.expect(
"=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",times=\"0\",original-location=\"printf\"}")
# Test that -break-insert fails if non-pending BP can't be resolved
self.runCmd("-break-insert unknown_func")
self.expect(
"\^error,msg=\"Command 'break-insert'. Breakpoint location 'unknown_func' not found\"")
# Test that non-pending BP was set correctly
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\".*bkptno=\"2\"")
# Test that we can set a BP using the file:func syntax
self.runCmd("-break-insert main.cpp:main")
self.expect("\^done,bkpt={number=\"4\"")
self.runCmd("-break-insert main.cpp:ns::foo1")
self.expect("\^done,bkpt={number=\"5\"")
# FIXME: quotes on filenames aren't handled correctly in lldb-mi.
#self.runCmd("-break-insert \"main.cpp\":main")
# self.expect("\^done,bkpt={number=\"6\"")
# We should hit BP #5 on 'main.cpp:ns::foo1'
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\".*bkptno=\"5\"")
# FIXME: this test is disabled due to lldb bug llvm.org/pr24271.
# Test that we can set a BP using the global namespace token
#self.runCmd("-break-insert ::main")
# self.expect("\^done,bkpt={number=\"7\"")
#self.runCmd("-break-insert main.cpp:::main")
# self.expect("\^done,bkpt={number=\"8\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_break_insert_file_line_pending(self):
"""Test that 'lldb-mi --interpreter' works for pending file:line breakpoints."""
self.spawnLldbMi(args=None)
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Find the line number to break inside main() and set
# pending BP
line = line_number('main.cpp', '// BP_return')
self.runCmd("-break-insert -f main.cpp:%d" % line)
self.expect(
"\^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"%d\",pending=\[\"main.cpp:%d\"\],times=\"0\",original-location=\"main.cpp:%d\"}" %
(line,
line,
line))
self.expect(
"=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"%d\",pending=\[\"main.cpp:%d\"\],times=\"0\",original-location=\"main.cpp:%d\"}" %
(line,
line,
line))
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_break_insert_file_line(self):
"""Test that 'lldb-mi --interpreter' works for file:line breakpoints."""
self.spawnLldbMi(args=None)
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
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 -break-insert can set non-pending BP
line = line_number('main.cpp', '// BP_return')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect(
"\^done,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"%d\",times=\"0\",original-location=\"main.cpp:%d\"}" %
(line, line))
self.expect(
"=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"%d\",times=\"0\",original-location=\"main.cpp:%d\"}" %
(line, line))
# Test that -break-insert fails if non-pending BP can't be resolved
self.runCmd("-break-insert unknown_file:1")
self.expect(
"\^error,msg=\"Command 'break-insert'. Breakpoint location 'unknown_file:1' not found\"")
# Test that non-pending BP was set correctly
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_break_insert_file_line_absolute_path(self):
"""Test that 'lldb-mi --interpreter' works for file:line breakpoints."""
self.spawnLldbMi(args=None)
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
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\"")
import os
path = os.path.join(self.getSourceDir(), "main.cpp")
line = line_number('main.cpp', '// BP_return')
self.runCmd("-break-insert %s:%d" % (path, line))
self.expect("\^done,bkpt={number=\"2\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_break_insert_settings(self):
"""Test that 'lldb-mi --interpreter' can set breakpoints accoridng to global options."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set target.move-to-nearest-code=off and try to set BP #1 that
# shouldn't be hit
self.runCmd(
"-interpreter-exec console \"settings set target.move-to-nearest-code off\"")
self.expect("\^done")
line_decl = line_number('main.cpp', '// BP_main_decl')
line_in = line_number('main.cpp', '// BP_in_main')
self.runCmd("-break-insert -f main.cpp:%d" % line_in)
self.expect("\^done,bkpt={number=\"1\"")
# Test that non-pending BP will not be set on non-existing line if target.move-to-nearest-code=off
# Note: this increases the BP number by 1 even though BP #2 is invalid.
self.runCmd("-break-insert main.cpp:%d" % line_in)
self.expect(
"\^error,msg=\"Command 'break-insert'. Breakpoint location 'main.cpp:%d' not found\"" %
line_in)
# Set target.move-to-nearest-code=on and target.skip-prologue=on and
# set BP #3 & #4
self.runCmd(
"-interpreter-exec console \"settings set target.move-to-nearest-code on\"")
self.runCmd(
"-interpreter-exec console \"settings set target.skip-prologue on\"")
self.expect("\^done")
self.runCmd("-break-insert main.cpp:%d" % line_in)
self.expect("\^done,bkpt={number=\"3\"")
self.runCmd("-break-insert main.cpp:%d" % line_decl)
self.expect("\^done,bkpt={number=\"4\"")
# Set target.skip-prologue=off and set BP #5
self.runCmd(
"-interpreter-exec console \"settings set target.skip-prologue off\"")
self.expect("\^done")
self.runCmd("-break-insert main.cpp:%d" % line_decl)
self.expect("\^done,bkpt={number=\"5\"")
# Test that BP #5 is located before BP #4
self.runCmd("-exec-run")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"5\"")
# Test that BP #4 is hit
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"4\"")
# Test that BP #3 is hit
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"3\"")
# Test that the target.language=pascal setting works and that BP #6 is
# NOT set
self.runCmd(
"-interpreter-exec console \"settings set target.language c\"")
self.expect("\^done")
self.runCmd("-break-insert ns.foo1")
self.expect("\^error")
# Test that the target.language=c++ setting works and that BP #7 is hit
self.runCmd(
"-interpreter-exec console \"settings set target.language c++\"")
self.expect("\^done")
self.runCmd("-break-insert ns::foo1")
self.expect("\^done,bkpt={number=\"7\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"7\"")
# Test that BP #1 and #2 weren't set by running to program exit
self.runCmd("-exec-continue")
self.expect("\^running")
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
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfNetBSD
def test_lldbmi_break_enable_disable(self):
"""Test that 'lldb-mi --interpreter' works for enabling / disabling breakpoints."""
self.spawnLldbMi(args=None)
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
self.runCmd("-break-insert main")
self.expect(
"\^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\"")
self.expect(
"=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"main\"}")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect(
"=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"main\"}")
self.expect(
"\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"1\"")
self.runCmd("-break-insert ns::foo1")
self.expect(
"\^done,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo1\(\)\"")
self.expect(
"=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo1\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo1\"}")
self.runCmd("-break-insert ns::foo2")
self.expect(
"\^done,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\"")
self.expect(
"=breakpoint-modified,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo2\"}")
# disable the 2nd breakpoint
self.runCmd("-break-disable 2")
self.expect("\^done")
self.expect(
"=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"n\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo1\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo1\"}")
# disable the 3rd breakpoint and re-enable
self.runCmd("-break-disable 3")
self.expect("\^done")
self.expect(
"=breakpoint-modified,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"n\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo2\"}")
self.runCmd("-break-enable 3")
self.expect("\^done")
self.expect(
"=breakpoint-modified,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo2\"}")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect(
"\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"3\"")

View File

@ -1,29 +0,0 @@
//===-- main.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 <cstdio>
namespace ns
{
int foo1(void) { printf("In foo1\n"); return 1; }
int foo2(void) { printf("In foo2\n"); return 2; }
}
int x;
int main(int argc, char const *argv[]) { // BP_main_decl
printf("Print a formatted string so that GCC does not optimize this printf call: %s\n", argv[0]);
// This is a long comment with no code inside
// This is a long comment with no code inside
// This is a long comment with no code inside
// BP_in_main
// This is a long comment with no code inside
// This is a long comment with no code inside
// This is a long comment with no code inside
x = ns::foo1() + ns::foo2();
return 0; // BP_return
}

View File

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

View File

@ -1,141 +0,0 @@
"""
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__)
@skipIfRemote # We do not currently support remote debugging via the MI.
@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\"")
@skipIfRemote # We do not currently support remote debugging via the MI.
@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)
@skipIfRemote # We do not currently support remote debugging via the MI.
@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\"")

View File

@ -1,32 +0,0 @@
//===-- main.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 <cstdio>
void
g_MyFunction(void)
{
printf("g_MyFunction");
}
static void
s_MyFunction(void)
{
g_MyFunction();
printf("s_MyFunction");
}
int
main(int argc, char const *argv[])
{
printf("start");
g_MyFunction();
s_MyFunction();
printf("exit");
return 0;
}

View File

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

View File

@ -1,365 +0,0 @@
"""
Test lldb-mi -data-xxx commands.
"""
from __future__ import print_function
import unittest2
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiDataTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfDarwin # pexpect is known to be unreliable on Darwin
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_data_disassemble(self):
"""Test that 'lldb-mi --interpreter' works for -data-disassemble."""
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\"")
# Get an address for disassembling: use main
self.runCmd("-data-evaluate-expression main")
self.expect(
"\^done,value=\"0x[0-9a-f]+ \(a.out`main at main.cpp:[0-9]+\)\"")
addr = int(self.child.after.split("\"")[1].split(" ")[0], 16)
# Test -data-disassemble: try to disassemble some address
self.runCmd(
"-data-disassemble -s %#x -e %#x -- 0" %
(addr, addr + 0x10))
self.expect(
"\^done,asm_insns=\[{address=\"0x0*%x\",func-name=\"main\",offset=\"0\",size=\"[1-9]+\",inst=\".+?\"}," %
addr)
# Test -data-disassemble without "--"
self.runCmd("-data-disassemble -s %#x -e %#x 0" % (addr, addr + 0x10))
self.expect(
"\^done,asm_insns=\[{address=\"0x0*%x\",func-name=\"main\",offset=\"0\",size=\"[1-9]+\",inst=\".+?\"}," %
addr)
# Test -data-disassemble with source line information
self.runCmd("-data-disassemble -s %#x -e %#x -- 1" % (addr, addr + 0x10))
self.expect(
'\^done,asm_insns=\[src_and_asm_line={line="\d+",file="main.cpp",'
'line_asm_insn=\[{address="0x0*%x",func-name="main",offset="0",size="[1-9]+",inst=".+?"}\],'
'fullname="%s"}' %
(addr, os.path.abspath("main.cpp")) )
# Run to hello_world
self.runCmd("-break-insert -f hello_world")
self.expect("\^done,bkpt={number=\"2\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Get an address for disassembling: use hello_world
self.runCmd("-data-evaluate-expression hello_world")
self.expect(
"\^done,value=\"0x[0-9a-f]+ \(a.out`hello_world\(\) at main.cpp:[0-9]+\)\"")
addr = int(self.child.after.split("\"")[1].split(" ")[0], 16)
# Test -data-disassemble: try to disassemble some address
self.runCmd(
"-data-disassemble -s %#x -e %#x -- 0" %
(addr, addr + 0x10))
# This matches a line similar to:
# Darwin: {address="0x0000000100000f18",func-name="hello_world()",offset="8",size="7",inst="leaq 0x65(%rip), %rdi; \"Hello, World!\\n\""},
# Linux: {address="0x0000000000400642",func-name="hello_world()",offset="18",size="5",inst="callq 0x4004d0; symbol stub for: printf"}
# To match the escaped characters in the ouptut, we must use four backslashes per matches backslash
# See https://docs.python.org/2/howto/regex.html#the-backslash-plague
# The MIPS and PPC64le disassemblers never print stub name
if self.isMIPS() or self.isPPC64le():
self.expect(["{address=\"0x[0-9a-f]+\",func-name=\"hello_world\(\)\",offset=\"[0-9]+\",size=\"[0-9]+\",inst=\".+?; \\\\\"Hello, World!\\\\\\\\n\\\\\"\"}",
"{address=\"0x[0-9a-f]+\",func-name=\"hello_world\(\)\",offset=\"[0-9]+\",size=\"[0-9]+\",inst=\".+?\"}"])
else:
self.expect(["{address=\"0x[0-9a-f]+\",func-name=\"hello_world\(\)\",offset=\"[0-9]+\",size=\"[0-9]+\",inst=\".+?; \\\\\"Hello, World!\\\\\\\\n\\\\\"\"}",
"{address=\"0x[0-9a-f]+\",func-name=\"hello_world\(\)\",offset=\"[0-9]+\",size=\"[0-9]+\",inst=\".+?; symbol stub for: printf\"}"])
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfDarwin # pexpect is known to be unreliable on Darwin
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_data_read_memory_bytes_global(self):
"""Test that -data-read-memory-bytes can access global buffers."""
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\"")
# Get address of char[] (global)
self.runCmd("-data-evaluate-expression &g_CharArray")
self.expect("\^done,value=\"0x[0-9a-f]+\"")
addr = int(self.child.after.split("\"")[1], 16)
size = 5
# Test that -data-read-memory-bytes works for char[] type (global)
self.runCmd("-data-read-memory-bytes %#x %d" % (addr, size))
self.expect(
"\^done,memory=\[{begin=\"0x0*%x\",offset=\"0x0+\",end=\"0x0*%x\",contents=\"1011121300\"}\]" %
(addr, addr + size))
# Get address of static char[]
self.runCmd("-data-evaluate-expression &s_CharArray")
self.expect("\^done,value=\"0x[0-9a-f]+\"")
addr = int(self.child.after.split("\"")[1], 16)
size = 5
# Test that -data-read-memory-bytes works for static char[] type
self.runCmd("-data-read-memory-bytes %#x %d" % (addr, size))
self.expect(
"\^done,memory=\[{begin=\"0x0*%x\",offset=\"0x0+\",end=\"0x0*%x\",contents=\"2021222300\"}\]" %
(addr, addr + size))
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfDarwin # pexpect is known to be unreliable on Darwin
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_data_read_memory_bytes_local(self):
"""Test that -data-read-memory-bytes can access local buffers."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd('-file-exec-and-symbols %s' % self.myexe)
self.expect(r'\^done')
# Run to BP_local_array_test_inner
line = line_number('main.cpp', '// BP_local_array_test_inner')
self.runCmd('-break-insert main.cpp:%d' % line)
self.expect(r'\^done,bkpt=\{number="1"')
self.runCmd('-exec-run')
self.expect(r'\^running')
self.expect(r'\*stopped,reason="breakpoint-hit"')
# Get address of local char[]
self.runCmd('-data-evaluate-expression "(void *)&array"')
self.expect(r'\^done,value="0x[0-9a-f]+"')
addr = int(self.child.after.split('"')[1], 16)
size = 4
# Test that an unquoted hex literal address works
self.runCmd('-data-read-memory-bytes %#x %d' % (addr, size))
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' %
(addr, addr + size))
# Test that a double-quoted hex literal address works
self.runCmd('-data-read-memory-bytes "%#x" %d' % (addr, size))
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' %
(addr, addr + size))
# Test that unquoted expressions work
self.runCmd('-data-read-memory-bytes &array %d' % size)
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' %
(addr, addr + size))
# This doesn't work, and perhaps that makes sense, but it does work on
# GDB
self.runCmd('-data-read-memory-bytes array 4')
self.expect(r'\^error')
#self.expect(r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' % (addr, addr + size))
self.runCmd('-data-read-memory-bytes &array[2] 2')
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="0304"\}\]' %
(addr + 2, addr + size))
self.runCmd('-data-read-memory-bytes first_element_ptr %d' % size)
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' %
(addr, addr + size))
# Test that double-quoted expressions work
self.runCmd('-data-read-memory-bytes "&array" %d' % size)
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' %
(addr, addr + size))
self.runCmd('-data-read-memory-bytes "&array[0] + 1" 3')
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="020304"\}\]' %
(addr + 1, addr + size))
self.runCmd('-data-read-memory-bytes "first_element_ptr + 1" 3')
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="020304"\}\]' %
(addr + 1, addr + size))
# Test the -o (offset) option
self.runCmd('-data-read-memory-bytes -o 1 &array 3')
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="020304"\}\]' %
(addr + 1, addr + size))
# Test the --thread option
self.runCmd('-data-read-memory-bytes --thread 1 &array 4')
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' %
(addr, addr + size))
# Test the --thread option with an invalid value
self.runCmd('-data-read-memory-bytes --thread 999 &array 4')
self.expect(r'\^error')
# Test the --frame option (current frame)
self.runCmd('-data-read-memory-bytes --frame 0 &array 4')
self.expect(
r'\^done,memory=\[\{begin="0x0*%x",offset="0x0+",end="0x0*%x",contents="01020304"\}\]' %
(addr, addr + size))
# Test the --frame option (outer frame)
self.runCmd('-data-read-memory-bytes --frame 1 &array 4')
self.expect(
r'\^done,memory=\[\{begin="0x[0-9a-f]+",offset="0x0+",end="0x[0-9a-f]+",contents="05060708"\}\]')
# Test the --frame option with an invalid value
self.runCmd('-data-read-memory-bytes --frame 999 &array 4')
self.expect(r'\^error')
# Test all the options at once
self.runCmd(
'-data-read-memory-bytes --thread 1 --frame 1 -o 2 &array 2')
self.expect(
r'\^done,memory=\[\{begin="0x[0-9a-f]+",offset="0x0+",end="0x[0-9a-f]+",contents="0708"\}\]')
# Test that an expression that references undeclared variables doesn't
# work
self.runCmd(
'-data-read-memory-bytes "&undeclared_array1 + undeclared_array2[1]" 2')
self.expect(r'\^error')
# Test that the address argument is required
self.runCmd('-data-read-memory-bytes')
self.expect(r'\^error')
# Test that the count argument is required
self.runCmd('-data-read-memory-bytes &array')
self.expect(r'\^error')
# Test that the address and count arguments are required when other
# options are present
self.runCmd('-data-read-memory-bytes --thread 1')
self.expect(r'\^error')
self.runCmd('-data-read-memory-bytes --thread 1 --frame 0')
self.expect(r'\^error')
# Test that the count argument is required when other options are
# present
self.runCmd('-data-read-memory-bytes --thread 1 &array')
self.expect(r'\^error')
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfDarwin # pexpect is known to be unreliable on Darwin
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_data_list_register_names(self):
"""Test that 'lldb-mi --interpreter' works for -data-list-register-names."""
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\"")
# Test -data-list-register-names: try to get all registers
self.runCmd("-data-list-register-names")
self.expect("\^done,register-names=\[\".+?\",")
# Test -data-list-register-names: try to get specified registers
self.runCmd("-data-list-register-names 0")
self.expect("\^done,register-names=\[\".+?\"\]")
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfDarwin # pexpect is known to be unreliable on Darwin
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_data_list_register_values(self):
"""Test that 'lldb-mi --interpreter' works for -data-list-register-values."""
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\"")
# Test -data-list-register-values: try to get all registers
self.runCmd("-data-list-register-values x")
self.expect(
"\^done,register-values=\[{number=\"0\",value=\"0x[0-9a-f]+\"")
# Test -data-list-register-values: try to get specified registers
self.runCmd("-data-list-register-values x 0")
self.expect(
"\^done,register-values=\[{number=\"0\",value=\"0x[0-9a-f]+\"}\]")
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfDarwin # pexpect is known to be unreliable on Darwin
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_data_evaluate_expression(self):
"""Test that 'lldb-mi --interpreter' works for -data-evaluate-expression."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
line = line_number('main.cpp', '// BP_local_2d_array_test')
self.runCmd('-break-insert main.cpp:%d' % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Check 2d array
self.runCmd("-data-evaluate-expression array2d")
self.expect(
"\^done,value=\"\{\[0\] = \{\[0\] = 1, \[1\] = 2, \[2\] = 3\}, \[1\] = \{\[0\] = 4, \[1\] = 5, \[2\] = 6\}\}\"")

View File

@ -1,60 +0,0 @@
//===-- main.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 <stdio.h>
const char g_CharArray[] = "\x10\x11\x12\x13";
static const char s_CharArray[] = "\x20\x21\x22\x23";
void
local_array_test_inner()
{
char array[] = { 0x01, 0x02, 0x03, 0x04 };
char *first_element_ptr = &array[0];
char g = g_CharArray[0];
char s = s_CharArray[0];
// BP_local_array_test_inner
return;
}
void
local_array_test()
{
char array[] = { 0x05, 0x06, 0x07, 0x08 };
// BP_local_array_test
local_array_test_inner();
return;
}
void
local_2d_array_test()
{
int array2d[2][3];
array2d[0][0] = 1;
array2d[0][1] = 2;
array2d[0][2] = 3;
array2d[1][0] = 4;
array2d[1][1] = 5;
array2d[1][2] = 6;
return; // BP_local_2d_array_test
}
void
hello_world()
{
printf("Hello, World!\n"); // BP_hello_world
}
int
main(int argc, char const *argv[])
{ // FUNC_main
local_array_test();
hello_world();
local_2d_array_test();
return 0;
}

View File

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

View File

@ -1,240 +0,0 @@
"""
Test lldb-mi can interpret CLI commands directly.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiCliSupportTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_target_create(self):
"""Test that 'lldb-mi --interpreter' can create target by 'target create' command."""
self.spawnLldbMi(args=None)
# Test that "target create" loads executable
self.runCmd("target create \"%s\"" % self.myexe)
self.expect("\^done")
# Test that executable was loaded properly
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\"")
@skipIfRemote # We do not currently support remote debugging via the MI.
@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_target_list(self):
"""Test that 'lldb-mi --interpreter' can list targets by 'target list' command."""
self.spawnLldbMi(args=None)
# Test that initially there are no targets.
self.runCmd("target list")
self.expect(r"~\"No targets.\\n\"")
self.expect("\^done")
# Add target.
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
# Test that "target list" lists added target.
self.runCmd("target list")
self.expect(r"~\"Current targets:\\n\* target #0: %s" % self.myexe)
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_breakpoint_set(self):
"""Test that 'lldb-mi --interpreter' can set breakpoint by 'breakpoint set' command."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Test that "breakpoint set" sets a breakpoint
self.runCmd("breakpoint set --name main")
self.expect("\^done")
self.expect("=breakpoint-created,bkpt={number=\"1\"")
# Test that breakpoint was set properly
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("=breakpoint-modified,bkpt={number=\"1\"")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_settings_set_target_run_args_before(self):
"""Test that 'lldb-mi --interpreter' can set target arguments by 'setting set target.run-args' command before than target was created."""
self.spawnLldbMi(args=None)
# Test that "settings set target.run-args" passes arguments to executable
# FIXME: --arg1 causes an error
self.runCmd(
"setting set target.run-args arg1 \"2nd arg\" third_arg fourth=\"4th arg\"")
self.expect("\^done")
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run
self.runCmd("-exec-run")
self.expect("\^running")
# Test that arguments were passed properly
self.expect("@\"argc=5\\\\r\\\\n\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_settings_set_target_run_args_after(self):
"""Test that 'lldb-mi --interpreter' can set target arguments by 'setting set target.run-args' command after than target was created."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Test that "settings set target.run-args" passes arguments to executable
# FIXME: --arg1 causes an error
self.runCmd(
"setting set target.run-args arg1 \"2nd arg\" third_arg fourth=\"4th arg\"")
self.expect("\^done")
# Run
self.runCmd("-exec-run")
self.expect("\^running")
# Test that arguments were passed properly
self.expect("@\"argc=5\\\\r\\\\n\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_process_launch(self):
"""Test that 'lldb-mi --interpreter' can launch process by "process launch" command."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set breakpoint
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
# Test that "process launch" launches executable
self.runCmd("process launch")
self.expect("\^done")
# Test that breakpoint hit
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_thread_step_in(self):
"""Test that 'lldb-mi --interpreter' can step in by "thread step-in" command."""
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\"")
# Test that "thread step-in" 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("thread step-in")
self.expect("\^done")
it = self.expect(["@\"argc=1\\\\r\\\\n\"",
"\*stopped,reason=\"end-stepping-range\".+?func=\"(?!main).+?\""])
if it == 0:
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"main\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_thread_step_over(self):
"""Test that 'lldb-mi --interpreter' can step over by "thread step-over" command."""
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\"")
# Test that "thread step-over" steps over
self.runCmd("thread step-over")
self.expect("\^done")
self.expect("@\"argc=1\\\\r\\\\n\"")
self.expect("\*stopped,reason=\"end-stepping-range\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_thread_continue(self):
"""Test that 'lldb-mi --interpreter' can continue execution by "thread continue" command."""
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\"")
# Test that "thread continue" continues execution
self.runCmd("thread continue")
self.expect("\^done")
self.expect("@\"argc=1\\\\r\\\\n")
self.expect("\*stopped,reason=\"exited-normally\"")

View File

@ -1,227 +0,0 @@
"""
Test lldb-mi -interpreter-exec command.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiInterpreterExecTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_target_create(self):
"""Test that 'lldb-mi --interpreter' can create target by 'target create' command."""
self.spawnLldbMi(args=None)
# Test that "target create" loads executable
self.runCmd(
"-interpreter-exec console \"target create \\\"%s\\\"\"" %
self.myexe)
self.expect("\^done")
# Test that executable was loaded properly
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\"")
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows.
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races.
@skipIfDarwin
def test_lldbmi_target_list(self):
"""Test that 'lldb-mi --interpreter' can list targets by 'target list' command."""
self.spawnLldbMi(args=None)
# Test that initially there are no targets.
self.runCmd("-interpreter-exec console \"target list\"")
self.expect(r"~\"No targets.\\n\"")
# Add target.
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
# Test that "target list" lists added target.
self.runCmd("-interpreter-exec console \"target list\"")
self.expect(r"~\"Current targets:\\n\* target #0: %s" % self.myexe)
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_breakpoint_set(self):
"""Test that 'lldb-mi --interpreter' can set breakpoint by 'breakpoint set' command."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Test that "breakpoint set" sets a breakpoint
self.runCmd("-interpreter-exec console \"breakpoint set --name main\"")
self.expect("\^done")
self.expect("=breakpoint-created,bkpt={number=\"1\"")
# Test that breakpoint was set properly
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("=breakpoint-modified,bkpt={number=\"1\"")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
@skipIfLinux
def test_lldbmi_settings_set_target_run_args_before(self):
"""Test that 'lldb-mi --interpreter' can set target arguments by 'setting set target.run-args' command before than target was created."""
self.spawnLldbMi(args=None)
# Test that "settings set target.run-args" passes arguments to executable
# FIXME: --arg1 causes an error
self.runCmd(
"-interpreter-exec console \"setting set target.run-args arg1 \\\"2nd arg\\\" third_arg fourth=\\\"4th arg\\\"\"")
self.expect("\^done")
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run
self.runCmd("-exec-run")
self.expect("\^running")
# Test that arguments were passed properly
self.expect("@\"argc=5\\\\r\\\\n\"")
self.expect("@\"argv.0.=.*lldb-mi")
self.expect("@\"argv.1.=arg1\\\\r\\\\n\"")
self.expect("@\"argv.2.=2nd arg\\\\r\\\\n\"")
self.expect("@\"argv.3.=third_arg\\\\r\\\\n\"")
self.expect("@\"argv.4.=fourth=4th arg\\\\r\\\\n\"")
# Test that program exited normally
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
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_process_launch(self):
"""Test that 'lldb-mi --interpreter' can launch process by "process launch" command."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set breakpoint
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
# Test that "process launch" launches executable
self.runCmd("-interpreter-exec console \"process launch\"")
self.expect("\^done")
# Test that breakpoint hit
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_thread_step_in(self):
"""Test that 'lldb-mi --interpreter' can step in by "thread step-in" command."""
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\"")
# Test that "thread step-in" 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("-interpreter-exec console \"thread step-in\"")
self.expect("\^done")
it = self.expect(["@\"argc=1\\\\r\\\\n\"",
"\*stopped,reason=\"end-stepping-range\".+?func=\"(?!main).+?\""])
if it == 0:
self.expect(
"\*stopped,reason=\"end-stepping-range\".+?func=\"main\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_thread_step_over(self):
"""Test that 'lldb-mi --interpreter' can step over by "thread step-over" command."""
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\"")
# Test that "thread step-over" steps over
self.runCmd("-interpreter-exec console \"thread step-over\"")
self.expect("\^done")
self.expect("@\"argc=1\\\\r\\\\n\"")
self.expect("\*stopped,reason=\"end-stepping-range\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@expectedFlakeyLinux("llvm.org/pr25470")
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_thread_continue(self):
"""Test that 'lldb-mi --interpreter' can continue execution by "thread continue" command."""
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\"")
# Test that "thread continue" continues execution
self.runCmd("-interpreter-exec console \"thread continue\"")
self.expect("\^done")
self.expect("@\"argc=1\\\\r\\\\n")
self.expect("\*stopped,reason=\"exited-normally\"")

View File

@ -1,18 +0,0 @@
//===-- main.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 <cstdio>
int
main(int argc, char const *argv[])
{
printf("argc=%d\n", argc); // BP_printf
for (int i = 0; i < argc; ++i)
printf("argv[%d]=%s\n", i, argv[i]);
return 0; // BP_return
}

View File

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

View File

@ -1,68 +0,0 @@
"""
Test lldb-mi -stack-list-locals -stack-list-variables and -var-create commands
for variables with the same name in sibling lexical scopes.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiLexicalScopeTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_var_create_in_sibling_scope(self):
"""Test that 'lldb-mi --interpreter' works with sibling lexical scopes."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Breakpoint inside first scope
line = line_number('main.cpp', '// BP_first')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"\d+\"")
# Breakpoint inside second scope
line = line_number('main.cpp', '// BP_second')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"\d+\"")
# Run to the first scope
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Check that only variables a and b exist with expected values
self.runCmd("-stack-list-locals --thread 1 --frame 0 --all-values")
self.expect("\^done,locals=\[{name=\"a\",value=\"1\"},{name=\"b\",value=\"2\"}\]")
# Create variable object for local variable b
self.runCmd("-var-create - * \"b\"")
self.expect(
"\^done,name=\"var\d+\",numchild=\"0\",value=\"2\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
# Run to the second scope
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Check that only variables a and b exist with expected values,
# but variable b is different from previous breakpoint
self.runCmd("-stack-list-variables --thread 1 --frame 0 --all-values")
self.expect("\^done,variables=\[{name=\"a\",value=\"1\"},{name=\"b\",value=\"3\"}\]")
# Create variable object for local variable b
self.runCmd("-var-create - * \"b\"")
self.expect(
"\^done,name=\"var\d+\",numchild=\"0\",value=\"3\",type=\"short\",thread-id=\"1\",has_more=\"0\"")

View File

@ -1,32 +0,0 @@
//===-- main.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
//
//===----------------------------------------------------------------------===//
void
some_func (void)
{
}
void test_sibling_scope (void)
{
int a = 1;
{
int b = 2;
some_func(); // BP_first
}
{
short b = 3;
some_func(); // BP_second
}
}
int
main (int argc, char **argv)
{
test_sibling_scope();
return 0;
}

View File

@ -1,72 +0,0 @@
"""
Base class for lldb-mi test cases.
"""
from __future__ import print_function
from lldbsuite.test.lldbtest import *
class MiTestCaseBase(Base):
mydir = None
myexe = None
mylog = None
NO_DEBUG_INFO_TESTCASE = True
@classmethod
def classCleanup(cls):
if cls.myexe:
TestBase.RemoveTempFile(cls.myexe)
if cls.mylog:
TestBase.RemoveTempFile(cls.mylog)
def setUp(self):
if not self.mydir:
raise("mydir is empty")
Base.setUp(self)
self.buildDefault()
self.child_prompt = "(gdb)"
self.myexe = self.getBuildArtifact("a.out")
def tearDown(self):
if self.TraceOn():
print("\n\nContents of %s:" % self.mylog)
try:
print(open(self.mylog, "r").read())
except IOError:
pass
Base.tearDown(self)
def spawnLldbMi(self, exe=None, args=None, preconfig=True):
import pexpect
import sys
if sys.version_info.major == 3:
self.child = pexpect.spawnu("%s --interpreter %s" % (
self.lldbMiExec, args if args else ""), cwd=self.getBuildDir())
else:
self.child = pexpect.spawn("%s --interpreter %s" % (
self.lldbMiExec, args if args else ""), cwd=self.getBuildDir())
self.child.setecho(True)
self.mylog = self.getBuildArtifact("child.log")
self.child.logfile_read = open(self.mylog, "w")
# wait until lldb-mi has started up and is ready to go
self.expect(self.child_prompt, exactly=True)
if preconfig:
self.runCmd("settings set symbols.enable-external-lookup false")
self.expect("\^done")
self.expect(self.child_prompt, exactly=True)
if exe:
self.runCmd("-file-exec-and-symbols \"%s\"" % exe)
# Testcases expect to be able to match output of this command,
# see test_lldbmi_specialchars.
def runCmd(self, cmd):
self.child.sendline(cmd)
def expect(self, pattern, exactly=False, *args, **kwargs):
if exactly:
return self.child.expect_exact(pattern, *args, **kwargs)
return self.child.expect(pattern, *args, **kwargs)

View File

@ -1,32 +0,0 @@
//===-- main.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 <cstdio>
#ifdef _WIN32
#include <direct.h>
#define getcwd _getcwd // suppress "deprecation" warning
#else
#include <unistd.h>
#endif
int
main(int argc, char const *argv[])
{
int a = 10;
char buf[512];
char *ans = getcwd(buf, sizeof(buf));
if (ans) {
printf("cwd: %s\n", ans);
}
printf("argc=%d\n", argc); // BP_printf
return 0;
}

View File

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

View File

@ -1,236 +0,0 @@
"""
Test that the lldb-mi handles signals properly.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiSignalTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Fails on FreeBSD apparently due to thread race conditions
@expectedFailureNetBSD
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfLinux
def test_lldbmi_stopped_when_interrupt(self):
"""Test that 'lldb-mi --interpreter' interrupt and resume a looping app."""
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\"")
# Set doloop=1 and run (to loop forever)
self.runCmd("-data-evaluate-expression \"do_loop=1\"")
self.expect("\^done,value=\"1\"")
self.runCmd("-exec-continue")
self.expect("\^running")
# Test that -exec-interrupt can interrupt an execution
self.runCmd("-exec-interrupt")
self.expect(
"\*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\",.+?thread-id=\"1\",stopped-threads=\"all\"")
# Continue (to loop forever)
self.runCmd("-exec-continue")
self.expect("\^running")
# There's a chance that lldb didn't resume the process, we send an interruput but
# the process is not running yet. Give it some time to restart. 5 seconds ought to
# be enough for every modern CPU out there.
import time
time.sleep(5)
# Test that Ctrl+C can interrupt an execution
self.child.sendintr() # FIXME: here uses self.child directly
self.expect(
"\*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\",.*thread-id=\"1\",stopped-threads=\"all\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Fails on FreeBSD apparently due to thread race conditions
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@expectedFailureNetBSD
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stopped_when_stopatentry_local(self):
"""Test that 'lldb-mi --interpreter' notifies after it was stopped on entry (local)."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run with stop-at-entry flag
self.runCmd("-interpreter-exec command \"process launch -s\"")
self.expect("\^done")
# Test that *stopped is printed
# Note that message is different in Darwin and Linux:
# Darwin: "*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",frame={level=\"0\",addr=\"0x[0-9a-f]+\",func=\"_dyld_start\",file=\"??\",fullname=\"??\",line=\"-1\"},thread-id=\"1\",stopped-threads=\"all\"
# Linux:
# "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x[0-9a-f]+\",func=\"??\",args=[],file=\"??\",fullname=\"??\",line=\"-1\"},thread-id=\"1\",stopped-threads=\"all\"
self.expect(
[
"\*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",frame=\{level=\"0\",addr=\"0x[0-9a-f]+\",func=\"_dyld_start\",file=\"\?\?\",fullname=\"\?\?\",line=\"-1\"\},thread-id=\"1\",stopped-threads=\"all\"",
"\*stopped,reason=\"end-stepping-range\",frame={addr=\"0x[0-9a-f]+\",func=\"\?\?\",args=\[\],file=\"\?\?\",fullname=\"\?\?\",line=\"-1\"},thread-id=\"1\",stopped-threads=\"all\""])
# Run to main to make sure we have not exited the application
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfDarwin # pexpect is known to be unreliable on Darwin
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stopped_when_stopatentry_remote(self):
"""Test that 'lldb-mi --interpreter' notifies after it was stopped on entry (remote)."""
# Prepare debugserver
import lldbgdbserverutils
debugserver_exe = lldbgdbserverutils.get_debugserver_exe()
if not debugserver_exe:
self.skipTest("debugserver exe not found")
hostname = "localhost"
import random
# the same as GdbRemoteTestCaseBase.get_next_port
port = 12000 + random.randint(0, 3999)
import pexpect
debugserver_child = pexpect.spawn(
"%s %s:%d" %
(debugserver_exe, hostname, port))
self.addTearDownHook(lambda: debugserver_child.terminate(force=True))
self.spawnLldbMi(args=None)
# Connect to debugserver
self.runCmd(
"-interpreter-exec command \"platform select remote-macosx --sysroot /\"")
self.expect("\^done")
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
self.runCmd(
"-interpreter-exec command \"process connect connect://%s:%d\"" %
(hostname, port))
self.expect("\^done")
# Run with stop-at-entry flag
self.runCmd("-interpreter-exec command \"process launch -s\"")
self.expect("\^done")
# Test that *stopped is printed
self.expect(
"\*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",.+?thread-id=\"1\",stopped-threads=\"all\"")
# Exit
self.runCmd("-gdb-exit")
self.expect("\^exit")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@expectedFailureNetBSD
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stopped_when_segfault_local(self):
"""Test that 'lldb-mi --interpreter' notifies after it was stopped when segfault occurred (local)."""
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\"")
# Set do_segfault=1 and run (to cause a segfault error)
self.runCmd("-data-evaluate-expression \"do_segfault=1\"")
self.expect("\^done,value=\"1\"")
self.runCmd("-exec-continue")
self.expect("\^running")
# Test that *stopped is printed
# Note that message is different in Darwin and Linux:
# Darwin: "*stopped,reason=\"exception-received\",exception=\"EXC_BAD_ACCESS (code=1, address=0x0)\",thread-id=\"1\",stopped-threads=\"all\""
# Linux: "*stopped,reason=\"exception-received\",exception=\"invalid
# address (fault address:
# 0x0)\",thread-id=\"1\",stopped-threads=\"all\""
self.expect(["\*stopped,reason=\"exception-received\",exception=\"EXC_BAD_ACCESS \(code=1, address=0x0\)\",thread-id=\"1\",stopped-threads=\"all\"",
"\*stopped,reason=\"exception-received\",exception=\"invalid address \(fault address: 0x0\)\",thread-id=\"1\",stopped-threads=\"all\""])
@skipUnlessDarwin
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stopped_when_segfault_remote(self):
"""Test that 'lldb-mi --interpreter' notifies after it was stopped when segfault occurred (remote)."""
# Prepare debugserver
import lldbgdbserverutils
debugserver_exe = lldbgdbserverutils.get_debugserver_exe()
if not debugserver_exe:
self.skipTest("debugserver exe not found")
hostname = "localhost"
import random
# the same as GdbRemoteTestCaseBase.get_next_port
port = 12000 + random.randint(0, 3999)
import pexpect
debugserver_child = pexpect.spawn(
"%s %s:%d" %
(debugserver_exe, hostname, port))
self.addTearDownHook(lambda: debugserver_child.terminate(force=True))
self.spawnLldbMi(args=None)
# Connect to debugserver
self.runCmd(
"-interpreter-exec command \"platform select remote-macosx --sysroot /\"")
self.expect("\^done")
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
self.runCmd(
"-interpreter-exec command \"process connect connect://%s:%d\"" %
(hostname, port))
self.expect("\^done")
# Run to main
self.runCmd("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
# FIXME -exec-run doesn't work
# FIXME: self.runCmd("-exec-run")
self.runCmd("-interpreter-exec command \"process launch\"")
self.expect("\^done") # FIXME: self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Set do_segfault=1 and run (to cause a segfault error)
self.runCmd("-data-evaluate-expression \"do_segfault=1\"")
self.expect("\^done,value=\"1\"")
self.runCmd("-exec-continue")
self.expect("\^running")
# Test that *stopped is printed
self.expect(
"\*stopped,reason=\"exception-received\",exception=\"EXC_BAD_ACCESS \(code=1, address=0x0\)\",thread-id=\"1\",stopped-threads=\"all\"")
# Exit
self.runCmd("-gdb-exit")
self.expect("\^exit")

View File

@ -1,32 +0,0 @@
//===-- main.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 <cstddef>
#include <unistd.h>
int do_loop;
int do_segfault;
int
main(int argc, char const *argv[])
{
if (do_loop)
{
do
sleep(1);
while (do_loop); // BP_loop_condition
}
if (do_segfault)
{
int *null_ptr = NULL;
return *null_ptr;
}
return 0;
}

View File

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

View File

@ -1,558 +0,0 @@
"""
Test lldb-mi -stack-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 MiStackTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stack_list_arguments(self):
"""Test that 'lldb-mi --interpreter' can shows arguments."""
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\"")
# Test that -stack-list-arguments lists empty stack arguments if range
# is empty
self.runCmd("-stack-list-arguments 0 1 0")
self.expect("\^done,stack-args=\[\]")
# Test that -stack-list-arguments lists stack arguments without values
# (and that low-frame and high-frame are optional)
self.runCmd("-stack-list-arguments 0")
self.expect(
"\^done,stack-args=\[frame={level=\"0\",args=\[name=\"argc\",name=\"argv\"\]}")
self.runCmd("-stack-list-arguments --no-values")
self.expect(
"\^done,stack-args=\[frame={level=\"0\",args=\[name=\"argc\",name=\"argv\"\]}")
# Test that -stack-list-arguments lists stack arguments with all values
self.runCmd("-stack-list-arguments 1 0 0")
self.expect(
"\^done,stack-args=\[frame={level=\"0\",args=\[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\".*\"}\]}\]")
self.runCmd("-stack-list-arguments --all-values 0 0")
self.expect(
"\^done,stack-args=\[frame={level=\"0\",args=\[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\".*\"}\]}\]")
# Test that -stack-list-arguments lists stack arguments with simple
# values
self.runCmd("-stack-list-arguments 2 0 1")
self.expect(
"\^done,stack-args=\[frame={level=\"0\",args=\[{name=\"argc\",type=\"int\",value=\"1\"},{name=\"argv\",type=\"const char \*\*\",value=\".*\"}\]}")
self.runCmd("-stack-list-arguments --simple-values 0 1")
self.expect(
"\^done,stack-args=\[frame={level=\"0\",args=\[{name=\"argc\",type=\"int\",value=\"1\"},{name=\"argv\",type=\"const char \*\*\",value=\".*\"}\]}")
# Test that an invalid low-frame is handled
# FIXME: -1 is treated as unsigned int
self.runCmd("-stack-list-arguments 0 -1 0")
# self.expect("\^error")
self.runCmd("-stack-list-arguments 0 0")
self.expect(
"\^error,msg=\"Command 'stack-list-arguments'\. Thread frame range invalid\"")
# Test that an invalid high-frame is handled
# FIXME: -1 is treated as unsigned int
self.runCmd("-stack-list-arguments 0 0 -1")
# self.expect("\^error")
# Test that a missing low-frame or high-frame is handled
self.runCmd("-stack-list-arguments 0 0")
self.expect(
"\^error,msg=\"Command 'stack-list-arguments'\. Thread frame range invalid\"")
# Test that an invalid low-frame is handled
self.runCmd("-stack-list-arguments 0 0")
self.expect(
"\^error,msg=\"Command 'stack-list-arguments'\. Thread frame range invalid\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stack_list_locals(self):
"""Test that 'lldb-mi --interpreter' can shows local variables."""
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\"")
# Test int local variables:
# Run to BP_local_int_test
line = line_number('main.cpp', '// BP_local_int_test')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"2\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-locals: use 0 or --no-values
self.runCmd("-stack-list-locals 0")
self.expect("\^done,locals=\[name=\"a\",name=\"b\"\]")
self.runCmd("-stack-list-locals --no-values")
self.expect("\^done,locals=\[name=\"a\",name=\"b\"\]")
# Test -stack-list-locals: use 1 or --all-values
self.runCmd("-stack-list-locals 1")
self.expect(
"\^done,locals=\[{name=\"a\",value=\"10\"},{name=\"b\",value=\"20\"}\]")
self.runCmd("-stack-list-locals --all-values")
self.expect(
"\^done,locals=\[{name=\"a\",value=\"10\"},{name=\"b\",value=\"20\"}\]")
# Test -stack-list-locals: use 2 or --simple-values
self.runCmd("-stack-list-locals 2")
self.expect(
"\^done,locals=\[{name=\"a\",type=\"int\",value=\"10\"},{name=\"b\",type=\"int\",value=\"20\"}\]")
self.runCmd("-stack-list-locals --simple-values")
self.expect(
"\^done,locals=\[{name=\"a\",type=\"int\",value=\"10\"},{name=\"b\",type=\"int\",value=\"20\"}\]")
# Test struct local variable:
# Run to BP_local_struct_test
line = line_number('main.cpp', '// BP_local_struct_test')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"3\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-locals: use 0 or --no-values
self.runCmd("-stack-list-locals 0")
self.expect("\^done,locals=\[name=\"var_c\"\]")
self.runCmd("-stack-list-locals --no-values")
self.expect("\^done,locals=\[name=\"var_c\"\]")
# Test -stack-list-locals: use 1 or --all-values
self.runCmd("-stack-list-locals 1")
self.expect(
"\^done,locals=\[{name=\"var_c\",value=\"{var_a = 10, var_b = 97 'a', inner_ = {var_d = 30}}\"}\]")
self.runCmd("-stack-list-locals --all-values")
self.expect(
"\^done,locals=\[{name=\"var_c\",value=\"{var_a = 10, var_b = 97 'a', inner_ = {var_d = 30}}\"}\]")
# Test -stack-list-locals: use 2 or --simple-values
self.runCmd("-stack-list-locals 2")
self.expect("\^done,locals=\[{name=\"var_c\",type=\"my_type\"}\]")
self.runCmd("-stack-list-locals --simple-values")
self.expect("\^done,locals=\[{name=\"var_c\",type=\"my_type\"}\]")
# Test array local variable:
# Run to BP_local_array_test
line = line_number('main.cpp', '// BP_local_array_test')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"4\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-locals: use 0 or --no-values
self.runCmd("-stack-list-locals 0")
self.expect("\^done,locals=\[name=\"array\"\]")
self.runCmd("-stack-list-locals --no-values")
self.expect("\^done,locals=\[name=\"array\"\]")
# Test -stack-list-locals: use 1 or --all-values
self.runCmd("-stack-list-locals 1")
self.expect(
"\^done,locals=\[{name=\"array\",value=\"{\[0\] = 100, \[1\] = 200, \[2\] = 300}\"}\]")
self.runCmd("-stack-list-locals --all-values")
self.expect(
"\^done,locals=\[{name=\"array\",value=\"{\[0\] = 100, \[1\] = 200, \[2\] = 300}\"}\]")
# Test -stack-list-locals: use 2 or --simple-values
self.runCmd("-stack-list-locals 2")
self.expect("\^done,locals=\[{name=\"array\",type=\"int \[3\]\"}\]")
self.runCmd("-stack-list-locals --simple-values")
self.expect("\^done,locals=\[{name=\"array\",type=\"int \[3\]\"}\]")
# Test pointers as local variable:
# Run to BP_local_pointer_test
line = line_number('main.cpp', '// BP_local_pointer_test')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"5\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-locals: use 0 or --no-values
self.runCmd("-stack-list-locals 0")
self.expect(
"\^done,locals=\[name=\"test_str\",name=\"var_e\",name=\"ptr\"\]")
self.runCmd("-stack-list-locals --no-values")
self.expect(
"\^done,locals=\[name=\"test_str\",name=\"var_e\",name=\"ptr\"\]")
# Test -stack-list-locals: use 1 or --all-values
self.runCmd("-stack-list-locals 1")
self.expect(
"\^done,locals=\[{name=\"test_str\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",value=\"24\"},{name=\"ptr\",value=\".*?\"}\]")
self.runCmd("-stack-list-locals --all-values")
self.expect(
"\^done,locals=\[{name=\"test_str\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",value=\"24\"},{name=\"ptr\",value=\".*?\"}\]")
# Test -stack-list-locals: use 2 or --simple-values
self.runCmd("-stack-list-locals 2")
self.expect(
"\^done,locals=\[{name=\"test_str\",type=\"const char \*\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",type=\"int\",value=\"24\"},{name=\"ptr\",type=\"int \*\",value=\".*?\"}\]")
self.runCmd("-stack-list-locals --simple-values")
self.expect(
"\^done,locals=\[{name=\"test_str\",type=\"const char \*\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",type=\"int\",value=\"24\"},{name=\"ptr\",type=\"int \*\",value=\".*?\"}\]")
# Test -stack-list-locals in a function with catch clause,
# having unnamed parameter
# Run to BP_catch_unnamed
line = line_number('main.cpp', '// BP_catch_unnamed')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"6\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-locals: use --no-values
self.runCmd("-stack-list-locals --no-values")
self.expect("\^done,locals=\[name=\"i\",name=\"j\"\]")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stack_list_variables(self):
"""Test that 'lldb-mi --interpreter' can shows local variables and arguments."""
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\"")
# Test int local variables:
# Run to BP_local_int_test
line = line_number('main.cpp', '// BP_local_int_test_with_args')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"2\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-variables: use 0 or --no-values
self.runCmd("-stack-list-variables 0")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"c\"},{arg=\"1\",name=\"d\"},{name=\"a\"},{name=\"b\"}\]")
self.runCmd("-stack-list-variables --no-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"c\"},{arg=\"1\",name=\"d\"},{name=\"a\"},{name=\"b\"}\]")
# Test -stack-list-variables: use 1 or --all-values
self.runCmd("-stack-list-variables 1")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"c\",value=\"30\"},{arg=\"1\",name=\"d\",value=\"40\"},{name=\"a\",value=\"10\"},{name=\"b\",value=\"20\"}\]")
self.runCmd("-stack-list-variables --all-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"c\",value=\"30\"},{arg=\"1\",name=\"d\",value=\"40\"},{name=\"a\",value=\"10\"},{name=\"b\",value=\"20\"}\]")
# Test -stack-list-variables: use 2 or --simple-values
self.runCmd("-stack-list-variables 2")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"c\",type=\"int\",value=\"30\"},{arg=\"1\",name=\"d\",type=\"int\",value=\"40\"},{name=\"a\",type=\"int\",value=\"10\"},{name=\"b\",type=\"int\",value=\"20\"}\]")
self.runCmd("-stack-list-variables --simple-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"c\",type=\"int\",value=\"30\"},{arg=\"1\",name=\"d\",type=\"int\",value=\"40\"},{name=\"a\",type=\"int\",value=\"10\"},{name=\"b\",type=\"int\",value=\"20\"}\]")
# Test struct local variable:
# Run to BP_local_struct_test
line = line_number('main.cpp', '// BP_local_struct_test_with_args')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"3\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-variables: use 0 or --no-values
self.runCmd("-stack-list-variables 0")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"var_e\"},{name=\"var_c\"}\]")
self.runCmd("-stack-list-variables --no-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"var_e\"},{name=\"var_c\"}\]")
# Test -stack-list-variables: use 1 or --all-values
self.runCmd("-stack-list-variables 1")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"var_e\",value=\"{var_a = 20, var_b = 98 'b', inner_ = {var_d = 40}}\"},{name=\"var_c\",value=\"{var_a = 10, var_b = 97 'a', inner_ = {var_d = 30}}\"}\]")
self.runCmd("-stack-list-variables --all-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"var_e\",value=\"{var_a = 20, var_b = 98 'b', inner_ = {var_d = 40}}\"},{name=\"var_c\",value=\"{var_a = 10, var_b = 97 'a', inner_ = {var_d = 30}}\"}\]")
# Test -stack-list-variables: use 2 or --simple-values
self.runCmd("-stack-list-variables 2")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"var_e\",type=\"my_type\"},{name=\"var_c\",type=\"my_type\"}\]")
self.runCmd("-stack-list-variables --simple-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"var_e\",type=\"my_type\"},{name=\"var_c\",type=\"my_type\"}\]")
# Test array local variable:
# Run to BP_local_array_test
line = line_number('main.cpp', '// BP_local_array_test_with_args')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"4\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-variables: use 0 or --no-values
self.runCmd("-stack-list-variables 0")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"other_array\"},{name=\"array\"}\]")
self.runCmd("-stack-list-variables --no-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"other_array\"},{name=\"array\"}\]")
# Test -stack-list-variables: use 1 or --all-values
self.runCmd("-stack-list-variables 1")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"other_array\",value=\".*?\"},{name=\"array\",value=\"{\[0\] = 100, \[1\] = 200, \[2\] = 300}\"}\]")
self.runCmd("-stack-list-variables --all-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"other_array\",value=\".*?\"},{name=\"array\",value=\"{\[0\] = 100, \[1\] = 200, \[2\] = 300}\"}\]")
# Test -stack-list-variables: use 2 or --simple-values
self.runCmd("-stack-list-variables 2")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"other_array\",type=\"int \*\",value=\".*?\"},{name=\"array\",type=\"int \[3\]\"}\]")
self.runCmd("-stack-list-variables --simple-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"other_array\",type=\"int \*\",value=\".*?\"},{name=\"array\",type=\"int \[3\]\"}\]")
# Test pointers as local variable:
# Run to BP_local_pointer_test
line = line_number('main.cpp', '// BP_local_pointer_test_with_args')
self.runCmd("-break-insert --file main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"5\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test -stack-list-variables: use 0 or --no-values
self.runCmd("-stack-list-variables 0")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"arg_str\"},{arg=\"1\",name=\"arg_ptr\"},{name=\"test_str\"},{name=\"var_e\"},{name=\"ptr\"}\]")
self.runCmd("-stack-list-variables --no-values")
self.expect(
"\^done,variables=\[{arg=\"1\",name=\"arg_str\"},{arg=\"1\",name=\"arg_ptr\"},{name=\"test_str\"},{name=\"var_e\"},{name=\"ptr\"}\]")
# Test -stack-list-variables: use 1 or --all-values
self.runCmd("-stack-list-variables 1")
self.expect("\^done,variables=\[{arg=\"1\",name=\"arg_str\",value=\".*?String.*?\"},{arg=\"1\",name=\"arg_ptr\",value=\".*?\"},{name=\"test_str\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",value=\"24\"},{name=\"ptr\",value=\".*?\"}\]")
self.runCmd("-stack-list-variables --all-values")
self.expect("\^done,variables=\[{arg=\"1\",name=\"arg_str\",value=\".*?String.*?\"},{arg=\"1\",name=\"arg_ptr\",value=\".*?\"},{name=\"test_str\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",value=\"24\"},{name=\"ptr\",value=\".*?\"}\]")
# Test -stack-list-variables: use 2 or --simple-values
self.runCmd("-stack-list-variables 2")
self.expect("\^done,variables=\[{arg=\"1\",name=\"arg_str\",type=\"const char \*\",value=\".*?String.*?\"},{arg=\"1\",name=\"arg_ptr\",type=\"int \*\",value=\".*?\"},{name=\"test_str\",type=\"const char \*\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",type=\"int\",value=\"24\"},{name=\"ptr\",type=\"int \*\",value=\".*?\"}\]")
self.runCmd("-stack-list-variables --simple-values")
self.expect("\^done,variables=\[{arg=\"1\",name=\"arg_str\",type=\"const char \*\",value=\".*?String.*?\"},{arg=\"1\",name=\"arg_ptr\",type=\"int \*\",value=\".*?\"},{name=\"test_str\",type=\"const char \*\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",type=\"int\",value=\"24\"},{name=\"ptr\",type=\"int \*\",value=\".*?\"}\]")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stack_info_depth(self):
"""Test that 'lldb-mi --interpreter' can shows depth of the stack."""
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\"")
# Test that -stack-info-depth works
# (and that max-depth is optional)
self.runCmd("-stack-info-depth")
self.expect("\^done,depth=\"[1-9]\"")
# Test that max-depth restricts check of stack depth
# FIXME: max-depth argument is ignored
self.runCmd("-stack-info-depth 1")
# self.expect("\^done,depth=\"1\"")
# Test that invalid max-depth argument is handled
# FIXME: max-depth argument is ignored
self.runCmd("-stack-info-depth -1")
# self.expect("\^error")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipUnlessDarwin
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stack_info_frame(self):
"""Test that 'lldb-mi --interpreter' can show information about current frame."""
self.spawnLldbMi(args=None)
# Test that -stack-info-frame fails when program isn't running
self.runCmd("-stack-info-frame")
self.expect(
"\^error,msg=\"Command 'stack-info-frame'\. Invalid process during debug session\"")
# 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\"")
# Test that -stack-info-frame works when program was stopped on BP
self.runCmd("-stack-info-frame")
self.expect(
"\^done,frame=\{level=\"0\",addr=\"0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\"\}")
# Select frame #1
self.runCmd("-stack-select-frame 1")
self.expect("\^done")
# Test that -stack-info-frame works when specified frame was selected
self.runCmd("-stack-info-frame")
self.expect(
"\^done,frame=\{level=\"1\",addr=\"0x[0-9a-f]+\",func=\".+?\",file=\"\?\?\",fullname=\"\?\?\",line=\"-1\"\}")
# Test that -stack-info-frame fails when an argument is specified
# FIXME: unknown argument is ignored
self.runCmd("-stack-info-frame unknown_arg")
# self.expect("\^error")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stack_list_frames(self):
"""Test that 'lldb-mi --interpreter' can lists the frames on the stack."""
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\"")
# Test stack frame: get frame #0 info
self.runCmd("-stack-list-frames 0 0")
self.expect(
"\^done,stack=\[frame=\{level=\"0\",addr=\"0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\"\}\]")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_stack_select_frame(self):
"""Test that 'lldb-mi --interpreter' can choose current frame."""
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\"")
# Test that -stack-select-frame requires 1 mandatory argument
self.runCmd("-stack-select-frame")
self.expect(
"\^error,msg=\"Command 'stack-select-frame'\. Command Args\. Validation failed. Mandatory args not found: frame_id\"")
# Test that -stack-select-frame fails on invalid frame number
self.runCmd("-stack-select-frame 99")
self.expect(
"\^error,msg=\"Command 'stack-select-frame'\. Frame ID invalid\"")
# Test that current frame is #0
self.runCmd("-stack-info-frame")
self.expect(
"\^done,frame=\{level=\"0\",addr=\"0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\"\}")
# Test that -stack-select-frame can select the selected frame
self.runCmd("-stack-select-frame 0")
self.expect("\^done")
# Test that current frame is still #0
self.runCmd("-stack-info-frame")
self.expect(
"\^done,frame=\{level=\"0\",addr=\"0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\"\}")
# Test that -stack-select-frame can select frame #1 (parent frame)
self.runCmd("-stack-select-frame 1")
self.expect("\^done")
# Test that current frame is #1
# Note that message is different in Darwin and Linux:
# Darwin: "^done,frame={level=\"1\",addr=\"0x[0-9a-f]+\",func=\"start\",file=\"??\",fullname=\"??\",line=\"-1\"}"
# Linux:
# "^done,frame={level=\"1\",addr=\"0x[0-9a-f]+\",func=\".+\",file=\".+\",fullname=\".+\",line=\"\d+\"}"
self.runCmd("-stack-info-frame")
self.expect(
"\^done,frame=\{level=\"1\",addr=\"0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\"\}")
# Test that -stack-select-frame can select frame #0 (child frame)
self.runCmd("-stack-select-frame 0")
self.expect("\^done")
# Test that current frame is #0 and it has the same information
self.runCmd("-stack-info-frame")
self.expect(
"\^done,frame=\{level=\"0\",addr=\"0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\"\}")

View File

@ -1,141 +0,0 @@
//===-- main.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 <exception>
struct inner
{
int var_d;
};
struct my_type
{
int var_a;
char var_b;
struct inner inner_;
};
int
local_int_test(void)
{
int a = 10, b = 20;
return 0; // BP_local_int_test
}
int
local_int_test_with_args(int c, int d)
{
int a = 10, b = 20;
return 0; // BP_local_int_test_with_args
}
int
local_struct_test(void)
{
struct my_type var_c;
var_c.var_a = 10;
var_c.var_b = 'a';
var_c.inner_.var_d = 30;
return 0; // BP_local_struct_test
}
int local_struct_test_with_args(struct my_type var_e)
{
struct my_type var_c;
var_c.var_a = 10;
var_c.var_b = 'a';
var_c.inner_.var_d = 30;
return 0; // BP_local_struct_test_with_args
}
int
local_array_test(void)
{
int array[3];
array[0] = 100;
array[1] = 200;
array[2] = 300;
return 0; // BP_local_array_test
}
int
local_array_test_with_args(int* other_array)
{
int array[3];
array[0] = 100;
array[1] = 200;
array[2] = 300;
return 0; // BP_local_array_test_with_args
}
int
local_pointer_test(void)
{
const char *test_str = "Rakaposhi";
int var_e = 24;
int *ptr = &var_e;
return 0; // BP_local_pointer_test
}
int
local_pointer_test_with_args(const char *arg_str, int *arg_ptr)
{
const char *test_str = "Rakaposhi";
int var_e = 24;
int *ptr = &var_e;
return 0; // BP_local_pointer_test_with_args
}
int do_tests_with_args()
{
local_int_test_with_args(30, 40);
struct my_type var_e;
var_e.var_a = 20;
var_e.var_b = 'b';
var_e.inner_.var_d = 40;
local_struct_test_with_args(var_e);
int array[3];
array[0] = 400;
array[1] = 500;
array[2] = 600;
local_array_test_with_args(array);
const char *test_str = "String";
int var_z = 25;
int *ptr = &var_z;
local_pointer_test_with_args(test_str, ptr);
return 0;
}
void catch_unnamed_test()
{
try
{
int i = 1, j = 2;
throw std::exception(); // BP_catch_unnamed
}
catch(std::exception&)
{
}
}
int
main(int argc, char const *argv[])
{
local_int_test();
local_struct_test();
local_array_test();
local_pointer_test();
catch_unnamed_test();
do_tests_with_args();
return 0;
}

View File

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

View File

@ -1,335 +0,0 @@
"""
Test lldb-mi startup options.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import os
class MiStartupOptionsTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfDarwin
@skipIfLinux
def test_lldbmi_executable_option_file(self):
"""Test that 'lldb-mi --interpreter %s' loads executable file."""
self.spawnLldbMi(exe=self.myexe)
# Test that the executable is loaded when file was specified
self.expect("-file-exec-and-symbols \"%s\"" % self.myexe)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly=True)
# 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\"")
# Continue
self.runCmd("-exec-continue")
self.expect("\^running")
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
@skipIfDarwin
def test_lldbmi_executable_option_unknown_file(self):
"""Test that 'lldb-mi --interpreter %s' fails on unknown executable file."""
# Prepare path to executable
path = "unknown_file"
self.spawnLldbMi(exe=path)
# Test that the executable isn't loaded when unknown file was specified
self.expect("-file-exec-and-symbols \"%s\"" % path)
self.expect(
"\^error,msg=\"Command 'file-exec-and-symbols'. Target binary '%s' is invalid. error: unable to find executable for '%s'\"" %
(path, path))
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly=True)
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfDarwin
@skipIfLinux
def test_lldbmi_executable_option_absolute_path(self):
"""Test that 'lldb-mi --interpreter %s' loads executable which is specified via absolute path."""
# Prepare path to executable
self.spawnLldbMi(exe=self.myexe)
# Test that the executable is loaded when file was specified using
# absolute path
self.expect("-file-exec-and-symbols \"%s\"" % self.myexe)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly=True)
# Run
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfDarwin
@skipIfLinux
def test_lldbmi_executable_option_relative_path(self):
"""Test that 'lldb-mi --interpreter %s' loads executable which is specified via relative path."""
# Prepare path to executable
path = os.path.relpath(self.myexe, self.getBuildDir())
self.spawnLldbMi(exe=path)
# Test that the executable is loaded when file was specified using
# relative path
self.expect("-file-exec-and-symbols \"%s\"" % path)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly=True)
# Run
self.runCmd("-exec-run")
self.expect("\^running")
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
@skipIfDarwin
def test_lldbmi_executable_option_unknown_path(self):
"""Test that 'lldb-mi --interpreter %s' fails on executable file which is specified via unknown path."""
# Prepare path to executable
path = "unknown_dir" + self.myexe
self.spawnLldbMi(exe=path)
# Test that the executable isn't loaded when file was specified using
# unknown path
self.expect("-file-exec-and-symbols \"%s\"" % path)
self.expect(
"\^error,msg=\"Command 'file-exec-and-symbols'. Target binary '%s' is invalid. error: unable to find executable for '%s'\"" %
(path, path))
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly=True)
def copyScript(self, sourceFile):
"""copy the script to builddir and replace a.out with the full path"""
destFile = os.path.join(os.path.dirname(self.myexe),
sourceFile+'.script')
with open(sourceFile, 'r') as src:
with open(destFile, 'w+') as dest:
dest.write(src.read().replace("a.out", self.myexe))
return destFile
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@expectedFailureNetBSD
@skipIfDarwin
def test_lldbmi_source_option_start_script(self):
"""Test that 'lldb-mi --interpreter' can execute user's commands after initial commands were executed."""
# Prepared source file
sourceFile = self.copyScript("start_script")
self.spawnLldbMi(args="--source %s" % sourceFile)
# After '-file-exec-and-symbols a.out'
self.expect("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# After '-break-insert -f main'
self.expect("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
# After '-exec-run'
self.expect("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# After '-break-insert main.cpp:BP_return'
line = line_number('main.cpp', '//BP_return')
self.expect("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"2\"")
# After '-exec-continue'
self.expect("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that lldb-mi is ready after execution of --source start_script
self.expect(self.child_prompt, exactly=True)
# Try to evaluate 'a' expression
self.runCmd("-data-evaluate-expression a")
self.expect("\^done,value=\"10\"")
self.expect(self.child_prompt, exactly=True)
os.unlink(sourceFile)
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@expectedFailureNetBSD
@skipIfDarwin
def test_lldbmi_source_option_start_script_exit(self):
"""Test that 'lldb-mi --interpreter' can execute a prepared file which passed via --source option."""
# Prepared source file
sourceFile = self.copyScript("start_script_exit")
self.spawnLldbMi(args="--source %s" % sourceFile)
# After '-file-exec-and-symbols a.out'
self.expect("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# After '-break-insert -f main'
self.expect("-break-insert -f main")
self.expect("\^done,bkpt={number=\"1\"")
# After '-exec-run'
self.expect("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# After '-break-insert main.cpp:BP_return'
line = line_number('main.cpp', '//BP_return')
self.expect("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"2\"")
# After '-exec-continue'
self.expect("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# After '-data-evaluate-expression a'
self.expect("-data-evaluate-expression a")
self.expect("\^done,value=\"10\"")
# After '-gdb-exit'
self.expect("-gdb-exit")
self.expect("\^exit")
self.expect("\*stopped,reason=\"exited-normally\"")
os.unlink(sourceFile)
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfDarwin
def test_lldbmi_source_option_start_script_error(self):
"""Test that 'lldb-mi --interpreter' stops execution of initial commands in case of error."""
# Prepared source file
sourceFile = self.copyScript("start_script_error")
self.spawnLldbMi(args="--source %s" % sourceFile, preconfig=False)
# After 'settings set symbols.enable-external-lookup false'
self.expect("settings set symbols.enable-external-lookup false")
self.expect("\^done")
# After '-file-exec-and-symbols a.out'
self.expect("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# After '-break-ins -f main'
self.expect("-break-ins -f main")
self.expect("\^error")
# Test that lldb-mi is ready after execution of --source start_script
self.expect(self.child_prompt, exactly=True)
os.unlink(sourceFile)
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfDarwin
@skipIfLinux
def test_lldbmi_log_option(self):
"""Test that 'lldb-mi --log' creates a log file in the current directory."""
logDirectory = self.getBuildDir()
self.spawnLldbMi(exe=self.myexe, args="--log")
# Test that the executable is loaded when file was specified
self.expect("-file-exec-and-symbols \"%s\"" % self.myexe)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly=True)
# Run
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
# Check log file is created
import glob
import os
logFile = glob.glob(logDirectory + "/lldb-mi-*.log")
if not logFile:
self.fail("log file not found")
# Delete log
for f in logFile:
os.remove(f)
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfDarwin
@skipIfLinux
def test_lldbmi_log_directory_option(self):
"""Test that 'lldb-mi --log --log-dir' creates a log file in the directory specified by --log-dir."""
# Create log in temp directory
import tempfile
logDirectory = tempfile.gettempdir()
self.spawnLldbMi(exe=self.myexe,
args="--log --log-dir=%s" % logDirectory)
# Test that the executable is loaded when file was specified
self.expect("-file-exec-and-symbols \"%s\"" % self.myexe)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly=True)
# Run
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
# Check log file is created
import glob
import os
logFile = glob.glob(logDirectory + "/lldb-mi-*.log")
if not logFile:
self.fail("log file not found")
# Delete log
for f in logFile:
os.remove(f)

View File

@ -1,14 +0,0 @@
//===-- main.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
//
//===----------------------------------------------------------------------===//
int
main(int argc, char const *argv[])
{
int a = 10;
return 0; //BP_return
}

View File

@ -1,5 +0,0 @@
-file-exec-and-symbols a.out
-break-insert -f main
-exec-run
-break-insert main.cpp:14
-exec-continue

View File

@ -1,3 +0,0 @@
settings set symbols.enable-external-lookup false
-file-exec-and-symbols a.out
-break-ins -f main

View File

@ -1,7 +0,0 @@
-file-exec-and-symbols a.out
-break-insert -f main
-exec-run
-break-insert main.cpp:14
-exec-continue
-data-evaluate-expression a
-gdb-exit

View File

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

View File

@ -1,174 +0,0 @@
"""
Test that the lldb-mi driver understands MI command syntax.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from functools import reduce
class MiSyntaxTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
@skipIfLinux
def test_lldbmi_tokens(self):
"""Test that 'lldb-mi --interpreter' prints command tokens."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("000-file-exec-and-symbols %s" % self.myexe)
self.expect("000\^done")
# Run to main
self.runCmd("100000001-break-insert -f main")
self.expect("100000001\^done,bkpt={number=\"1\"")
self.runCmd("2-exec-run")
self.expect("2\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Exit
self.runCmd("0000000000000000000003-exec-continue")
self.expect("0000000000000000000003\^running")
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
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_specialchars(self):
"""Test that 'lldb-mi --interpreter' handles complicated strings."""
# Create an alias for myexe
complicated_myexe = self.getBuildArtifact("C--mpl-x file's`s @#$%^&*()_+-={}[]| name")
os.symlink(self.myexe, complicated_myexe)
self.addTearDownHook(lambda: os.unlink(complicated_myexe))
self.spawnLldbMi(exe=complicated_myexe)
# Test that the executable was loaded
self.expect(
"-file-exec-and-symbols \"%s\"" %
complicated_myexe, exactly=True)
self.expect("\^done")
# Check that it was loaded correctly
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\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfDarwin
@expectedFlakeyNetBSD
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_output_grammar(self):
"""Test that 'lldb-mi --interpreter' uses standard output syntax."""
self.spawnLldbMi(args=None)
self.child.setecho(False)
# Run all commands simultaneously
self.runCmd("-unknown-command")
self.runCmd("-interpreter-exec command help")
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.runCmd("-break-insert -f main")
self.runCmd("-gdb-set target-async off")
self.runCmd("-exec-run")
self.runCmd("-gdb-set target-async on")
self.runCmd("-exec-continue")
self.runCmd("-gdb-exit")
# Test that the program's output matches to the following pattern:
# ( async-record | stream-record )* [ result-record ] "(gdb)" nl
async_record = "^[0-9]*(\*|\+|=).+?\n" # 1
stream_record = "^(~|@|&).+?\n" # 2
result_record = "^[0-9]*\^.+?\n" # 3
prompt = "^\(gdb\)\r\n" # 4
command = "^\r\n" # 5 (it looks like empty line for pexpect)
error = "^.+?\n" # 6
import pexpect # 7 (EOF)
all_patterns = [
async_record,
stream_record,
result_record,
prompt,
command,
error,
pexpect.EOF]
# Routines to get a bit-mask for the specified list of patterns
def get_bit(pattern): return all_patterns.index(pattern)
def get_mask(pattern): return 1 << get_bit(pattern)
def or_op(x, y): return x | y
def get_state(*args): return reduce(or_op, map(get_mask, args))
next_state = get_state(command)
while True:
it = self.expect(all_patterns)
matched_pattern = all_patterns[it]
# Check that state is acceptable
if not (next_state & get_mask(matched_pattern)):
self.fail(
"error: inconsistent pattern '%s' for state %#x (matched string: %s)" %
(repr(matched_pattern), next_state, self.child.after))
elif matched_pattern == async_record or matched_pattern == stream_record:
next_state = get_state(
async_record,
stream_record,
result_record,
prompt)
elif matched_pattern == result_record:
# FIXME lldb-mi prints async-records out of turn
# ```
# ^done
# (gdb)
# ^running
# =thread-group-started,id="i1",pid="13875"
# (gdb)
# ```
# Therefore to pass that test I changed the grammar's rule:
# next_state = get_state(prompt)
# to:
next_state = get_state(async_record, prompt)
elif matched_pattern == prompt:
# FIXME lldb-mi prints the prompt out of turn
# ```
# ^done
# (gdb)
# ^running
# (gdb)
# (gdb)
# ```
# Therefore to pass that test I changed the grammar's rule:
# next_state = get_state(async_record, stream_record, result_record, command, pexpect.EOF)
# to:
next_state = get_state(
async_record,
stream_record,
result_record,
prompt,
command,
pexpect.EOF)
elif matched_pattern == command:
next_state = get_state(
async_record,
stream_record,
result_record)
elif matched_pattern == pexpect.EOF:
break
else:
self.fail("error: pexpect returned an unknown state")

View File

@ -1,16 +0,0 @@
//===-- main.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 <cstdio>
int
main(int argc, char const *argv[])
{
printf("'\n` - it's \\n\x12\"\\\"");
return 0;
}

View File

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

View File

@ -1,137 +0,0 @@
"""
Test lldb-mi -target-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 MiTargetTestCase(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
@skipIfLinux # cannot attach to process on linux
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
@expectedFailureNetBSD
def test_lldbmi_target_attach_wait_for(self):
"""Test that 'lldb-mi --interpreter' works for -target-attach -n <name> --waitfor."""
# Build target executable with unique name
exeName = self.testMethodName
d = {'EXE': exeName}
self.buildProgram("test_attach.cpp", exeName)
self.addTearDownCleanup(dictionary=d)
self.spawnLldbMi(args=None)
# Load executable
# FIXME: -file-exec-and-sybmols is not required for target attach, but
# the test will not pass without this
self.runCmd("-file-exec-and-symbols %s" % self.getBuildArtifact(exeName))
self.expect("\^done")
# Set up attach
self.runCmd("-target-attach -n %s --waitfor" % exeName)
time.sleep(4) # Give attach time to setup
# Start target process
self.spawnSubprocess(self.getBuildArtifact(exeName))
self.addTearDownHook(self.cleanupSubprocesses)
self.expect("\^done")
# Set breakpoint on printf
line = line_number('test_attach.cpp', '// BP_i++')
self.runCmd("-break-insert -f test_attach.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
# Continue to breakpoint
self.runCmd("-exec-continue")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Detach
self.runCmd("-target-detach")
self.expect("\^done")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # cannot attach to process on linux
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
@expectedFailureNetBSD
def test_lldbmi_target_attach_name(self):
"""Test that 'lldb-mi --interpreter' works for -target-attach -n <name>."""
# Build target executable with unique name
exeName = self.testMethodName
d = {'EXE': exeName}
self.buildProgram("test_attach.cpp", exeName)
self.addTearDownCleanup(dictionary=d)
# Start target process
targetProcess = self.spawnSubprocess(self.getBuildArtifact(exeName))
self.addTearDownHook(self.cleanupSubprocesses)
self.spawnLldbMi(args=None)
# Set up atatch
self.runCmd("-target-attach -n %s" % exeName)
self.expect("\^done")
# Set breakpoint on printf
line = line_number('test_attach.cpp', '// BP_i++')
self.runCmd("-break-insert -f test_attach.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
# Continue to breakpoint
self.runCmd("-exec-continue")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Detach
self.runCmd("-target-detach")
self.expect("\^done")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # cannot attach to process on linux
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
@expectedFailureNetBSD
def test_lldbmi_target_attach_pid(self):
"""Test that 'lldb-mi --interpreter' works for -target-attach <pid>."""
# Build target executable with unique name
exeName = self.testMethodName
d = {'EXE': exeName}
self.buildProgram("test_attach.cpp", exeName)
self.addTearDownCleanup(dictionary=d)
# Start target process
targetProcess = self.spawnSubprocess(
self.getBuildArtifact(exeName))
self.addTearDownHook(self.cleanupSubprocesses)
self.spawnLldbMi(args=None)
# Set up atatch
self.runCmd("-target-attach %d" % targetProcess.pid)
self.expect("\^done")
# Set breakpoint on printf
line = line_number('test_attach.cpp', '// BP_i++')
self.runCmd("-break-insert -f test_attach.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
# Continue to breakpoint
self.runCmd("-exec-continue")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Detach
self.runCmd("-target-detach")
self.expect("\^done")

View File

@ -1,20 +0,0 @@
//===-- main.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 <cstdio>
int
main(int argc, char const *argv[])
{
int i = 0;
for (;;)
{
i++; // BP_i++
}
return 0;
}

View File

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

View File

@ -1,42 +0,0 @@
"""
Test lldb-mi -thread-info command.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiThreadInfoTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # pthreads not supported on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@expectedFailureNetBSD
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_thread_info(self):
"""Test that -thread-info prints thread info and the current-thread-id"""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
self.runCmd("-break-insert ThreadProc")
self.expect("\^done")
# Run to the breakpoint
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
self.runCmd("-thread-info")
self.expect(
"\^done,threads=\[\{id=\"1\",(.*)\},\{id=\"2\",(.*)\],current-thread-id=\"2\"")
self.runCmd("-gdb-quit")

View File

@ -1,21 +0,0 @@
#include <cstdlib>
#include <iostream>
#include <thread>
using namespace std;
void
ThreadProc()
{
int i = 0;
i++;
}
int
main()
{
thread t(ThreadProc);
t.join();
return 0;
}

View File

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

View File

@ -1,247 +0,0 @@
# coding=utf8
"""
Test lldb-mi -gdb-set and -gdb-show commands for 'print option-name'.
"""
from __future__ import print_function
import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
# evaluates array when char-array-as-string is off
def eval_and_check_array(self, var, typ, length):
self.runCmd("-var-create - * %s" % var)
self.expect(
'\^done,name="var\d+",numchild="%d",value="\[%d\]",type="%s \[%d\]",thread-id="1",has_more="0"' %
(length, length, typ, length))
# evaluates any type which can be represented as string of characters
def eval_and_match_string(self, var, value, typ):
value = value.replace("\\", "\\\\").replace("\"", "\\\"")
self.runCmd("-var-create - * " + var)
self.expect(
'\^done,name="var\d+",numchild="[0-9]+",value="%s",type="%s",thread-id="1",has_more="0"' %
(value, typ))
@skipIfWindows # llvm.org/pr24452: Get lldb-mi working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_gdb_set_show_print_char_array_as_string(self):
"""Test that 'lldb-mi --interpreter' can print array of chars as string."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to BP_gdb_set_show_print_char_array_as_string_test
line = line_number(
'main.cpp',
'// BP_gdb_set_show_print_char_array_as_string_test')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that default print char-array-as-string value is "off"
self.runCmd("-gdb-show print char-array-as-string")
self.expect("\^done,value=\"off\"")
# Test that a char* is expanded to string when print
# char-array-as-string is "off"
self.eval_and_match_string(
"cp",
r'0x[0-9a-f]+ \"\\t\\\"hello\\\"\\n\"',
r'const char \*')
# Test that a char[] isn't expanded to string when print
# char-array-as-string is "off"
self.eval_and_check_array("ca", "const char", 10)
# Test that a char16_t* is expanded to string when print
# char-array-as-string is "off"
self.eval_and_match_string(
"u16p",
r'0x[0-9a-f]+ u\"\\t\\\"hello\\\"\\n\"',
r'const char16_t \*')
# Test that a char16_t[] isn't expanded to string when print
# char-array-as-string is "off"
self.eval_and_check_array("u16a", "const char16_t", 10)
# Test that a char32_t* is expanded to string when print
# char-array-as-string is "off"
self.eval_and_match_string(
"u32p",
r'0x[0-9a-f]+ U\"\\t\\\"hello\\\"\\n\"',
r'const char32_t \*')
# Test that a char32_t[] isn't expanded to string when print
# char-array-as-string is "off"
self.eval_and_check_array("u32a", "const char32_t", 10)
# Test that -gdb-set can set print char-array-as-string flag
self.runCmd("-gdb-set print char-array-as-string on")
self.expect("\^done")
self.runCmd("-gdb-set print char-array-as-string 1")
self.expect("\^done")
self.runCmd("-gdb-show print char-array-as-string")
self.expect("\^done,value=\"on\"")
# Test that a char* with escape chars is expanded to string when print
# char-array-as-string is "on"
self.eval_and_match_string(
"cp",
r'0x[0-9a-f]+ \"\\t\\\"hello\\\"\\n\"',
r'const char \*')
# Test that a char[] with escape chars is expanded to string when print
# char-array-as-string is "on"
self.eval_and_match_string(
"ca",
r'\"\\t\\\"hello\\\"\\n\"',
r'const char \[10\]')
# Test that a char16_t* with escape chars is expanded to string when
# print char-array-as-string is "on"
self.eval_and_match_string(
"u16p",
r'0x[0-9a-f]+ u\"\\t\\\"hello\\\"\\n\"',
r'const char16_t \*')
# Test that a char16_t[] with escape chars is expanded to string when
# print char-array-as-string is "on"
self.eval_and_match_string(
"u16a",
r'u\"\\t\\\"hello\\\"\\n\"',
r'const char16_t \[10\]')
# Test that a char32_t* with escape chars is expanded to string when
# print char-array-as-string is "on"
self.eval_and_match_string(
"u32p",
r'0x[0-9a-f]+ U\"\\t\\\"hello\\\"\\n\"',
r'const char32_t \*')
# Test that a char32_t[] with escape chars is expanded to string when
# print char-array-as-string is "on"
self.eval_and_match_string(
"u32a",
r'U\"\\t\\\"hello\\\"\\n\"',
r'const char32_t \[10\]')
# Test russian unicode strings
self.eval_and_match_string(
"u16p_rus",
r'0x[0-9a-f]+ u\"\\\\Аламо-сквер\"',
r'const char16_t \*')
self.eval_and_match_string(
"u16a_rus",
r'u\"\\\\Бейвью\"',
r'const char16_t \[8\]')
self.eval_and_match_string(
"u32p_rus",
r'0x[0-9a-f]+ U\"\\\\Чайнатаун\"',
r'const char32_t \*')
self.eval_and_match_string(
"u32a_rus",
r'U\"\\\\Догпатч\"',
r'const char32_t \[9\]')
# Test that -gdb-set print char-array-as-string fails if "on"/"off"
# isn't specified
self.runCmd("-gdb-set print char-array-as-string")
self.expect(
"\^error,msg=\"The request ''print' expects option-name and \"on\" or \"off\"' failed.\"")
# Test that -gdb-set print char-array-as-string fails when option is
# unknown
self.runCmd("-gdb-set print char-array-as-string unknown")
self.expect(
"\^error,msg=\"The request ''print' expects option-name and \"on\" or \"off\"' failed.\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi working on Windows
@expectedFailureAll(compiler="gcc", bugnumber="llvm.org/pr23357")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_gdb_set_show_print_aggregate_field_names(self):
"""Test that 'lldb-mi --interpreter' can expand aggregates everywhere."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to BP_gdb_set_show_print_aggregate_field_names
line = line_number(
'main.cpp',
'// BP_gdb_set_show_print_aggregate_field_names')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that default print aggregatep-field-names value is "on"
self.runCmd("-gdb-show print aggregate-field-names")
self.expect("\^done,value=\"on\"")
# Set print expand-aggregates flag to "on"
self.runCmd("-gdb-set print expand-aggregates on")
self.expect("\^done")
# Test that composite type is expanded with field name when print
# aggregate-field-names is "on"
self.runCmd("-var-create var1 * complx")
self.expect(
"\^done,name=\"var1\",numchild=\"3\",value=\"{i = 3, inner = {l = 3}, complex_ptr = 0x[0-9a-f]+}\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"")
# Test that composite type[] is expanded with field name when print
# aggregate-field-names is "on"
self.runCmd("-var-create var2 * complx_array")
self.expect(
"\^done,name=\"var2\",numchild=\"2\",value=\"{\[0\] = {i = 4, inner = {l = 4}, complex_ptr = 0x[0-9a-f]+}, \[1\] = {i = 5, inner = {l = 5}, complex_ptr = 0x[0-9a-f]+}}\",type=\"complex_type \[2\]\",thread-id=\"1\",has_more=\"0\"")
# Test that -gdb-set can set print aggregate-field-names flag
self.runCmd("-gdb-set print aggregate-field-names off")
self.expect("\^done")
self.runCmd("-gdb-set print aggregate-field-names 0")
self.expect("\^done")
self.runCmd("-gdb-show print aggregate-field-names")
self.expect("\^done,value=\"off\"")
# Test that composite type is expanded without field name when print
# aggregate-field-names is "off"
self.runCmd("-var-create var3 * complx")
self.expect(
"\^done,name=\"var3\",numchild=\"3\",value=\"{3,\{3\},0x[0-9a-f]+}\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"")
# Test that composite type[] is expanded without field name when print
# aggregate-field-names is "off"
self.runCmd("-var-create var4 * complx_array")
self.expect(
"\^done,name=\"var4\",numchild=\"2\",value=\"{{4,\{4\},0x[0-9a-f]+},{5,\{5\},0x[0-9a-f]+}}\",type=\"complex_type \[2\]\",thread-id=\"1\",has_more=\"0\"")
# Test that -gdb-set print aggregate-field-names fails if "on"/"off"
# isn't specified
self.runCmd("-gdb-set print aggregate-field-names")
self.expect(
"\^error,msg=\"The request ''print' expects option-name and \"on\" or \"off\"' failed.\"")
# Test that -gdb-set print aggregate-field-names fails when option is
# unknown
self.runCmd("-gdb-set print aggregate-field-names unknown")
self.expect(
"\^error,msg=\"The request ''print' expects option-name and \"on\" or \"off\"' failed.\"")

View File

@ -1,465 +0,0 @@
"""
Test lldb-mi -var-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 MiVarTestCase(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
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_eval(self):
"""Test that 'lldb-mi --interpreter' works for evaluating."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to program return
line = line_number('main.cpp', '// BP_return')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Print non-existant variable
self.runCmd("-var-create var1 * undef")
self.expect(
"\^error,msg=\"error: use of undeclared identifier \'undef\'\\\\n\"")
self.runCmd("-data-evaluate-expression undef")
self.expect(
"\^error,msg=\"error: use of undeclared identifier \'undef\'\\\\n\"")
# Print global "g_MyVar", modify, delete and create again
self.runCmd("-data-evaluate-expression g_MyVar")
self.expect("\^done,value=\"3\"")
self.runCmd("-var-create var2 * g_MyVar")
self.expect(
"\^done,name=\"var2\",numchild=\"0\",value=\"3\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-evaluate-expression var2")
self.expect("\^done,value=\"3\"")
self.runCmd("-var-show-attributes var2")
self.expect("\^done,status=\"editable\"")
self.runCmd("-var-list-children var2")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
# Ensure -var-list-children also works with quotes
self.runCmd("-var-list-children \"var2\"")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
self.runCmd("-data-evaluate-expression \"g_MyVar=30\"")
self.expect("\^done,value=\"30\"")
self.runCmd("-var-update --all-values var2")
# self.expect("\^done,changelist=\[\{name=\"var2\",value=\"30\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]")
# FIXME -var-update doesn't work
self.runCmd("-var-delete var2")
self.expect("\^done")
self.runCmd("-var-create var2 * g_MyVar")
self.expect(
"\^done,name=\"var2\",numchild=\"0\",value=\"30\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
# Print static "s_MyVar", modify, delete and create again
self.runCmd("-data-evaluate-expression s_MyVar")
self.expect("\^done,value=\"30\"")
self.runCmd("-var-create var3 * s_MyVar")
self.expect(
"\^done,name=\"var3\",numchild=\"0\",value=\"30\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-evaluate-expression var3")
self.expect("\^done,value=\"30\"")
self.runCmd("-var-show-attributes var3")
self.expect("\^done,status=\"editable\"")
self.runCmd("-var-list-children var3")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
self.runCmd("-data-evaluate-expression \"s_MyVar=3\"")
self.expect("\^done,value=\"3\"")
self.runCmd("-var-update --all-values var3")
# self.expect("\^done,changelist=\[\{name=\"var3\",value=\"3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]")
# FIXME -var-update doesn't work
self.runCmd("-var-delete var3")
self.expect("\^done")
self.runCmd("-var-create var3 * s_MyVar")
self.expect(
"\^done,name=\"var3\",numchild=\"0\",value=\"3\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
# Print local "b", modify, delete and create again
self.runCmd("-data-evaluate-expression b")
self.expect("\^done,value=\"20\"")
self.runCmd("-var-create var4 * b")
self.expect(
"\^done,name=\"var4\",numchild=\"0\",value=\"20\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-evaluate-expression var4")
self.expect("\^done,value=\"20\"")
self.runCmd("-var-show-attributes var4")
self.expect("\^done,status=\"editable\"")
self.runCmd("-var-list-children var4")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
self.runCmd("-data-evaluate-expression \"b=2\"")
self.expect("\^done,value=\"2\"")
self.runCmd("-var-update --all-values var4")
# self.expect("\^done,changelist=\[\{name=\"var4\",value=\"2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]")
# FIXME -var-update doesn't work
self.runCmd("-var-delete var4")
self.expect("\^done")
self.runCmd("-var-create var4 * b")
self.expect(
"\^done,name=\"var4\",numchild=\"0\",value=\"2\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
# Print temp "a + b"
self.runCmd("-data-evaluate-expression \"a + b\"")
self.expect("\^done,value=\"12\"")
self.runCmd("-var-create var5 * \"a + b\"")
self.expect(
"\^done,name=\"var5\",numchild=\"0\",value=\"12\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-evaluate-expression var5")
self.expect("\^done,value=\"12\"")
self.runCmd("-var-show-attributes var5")
self.expect("\^done,status=\"editable\"") # FIXME editable or not?
self.runCmd("-var-list-children var5")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
# Print argument "argv[0]"
self.runCmd("-data-evaluate-expression \"argv[0]\"")
self.expect(
"\^done,value=\"0x[0-9a-f]+ \\\\\\\".*?%s\\\\\\\"\"" %
self.myexe)
self.runCmd("-var-create var6 * \"argv[0]\"")
self.expect(
"\^done,name=\"var6\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\".*?%s\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"" %
self.myexe)
self.runCmd("-var-evaluate-expression var6")
self.expect(
"\^done,value=\"0x[0-9a-f]+ \\\\\\\".*?%s\\\\\\\"\"" %
self.myexe)
self.runCmd("-var-show-attributes var6")
self.expect("\^done,status=\"editable\"")
self.runCmd("-var-list-children --all-values var6")
# FIXME: The name below is not correct. It should be "var.*argv[0]".
# FIXME -var-list-children shows invalid thread-id
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var6\.\*\$[0-9]+\",exp=\"\*\$[0-9]+\",numchild=\"0\",type=\"const char\",thread-id=\"4294967295\",value=\"47 '/'\",has_more=\"0\"\}\],has_more=\"0\"")
# Print an expression with spaces and optional arguments
self.runCmd("-data-evaluate-expression \"a + b\"")
self.expect("\^done,value=\"12\"")
self.runCmd("-var-create var7 * \"a + b\" --thread 1 --frame 0")
self.expect(
"\^done,name=\"var7\",numchild=\"0\",value=\"12\",type=\"int\",thread-id=\"1\",has_more=\"0\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfDarwin
@skipIfRemote # We do not currently support remote debugging via the MI.
def test_lldbmi_var_update(self):
"""Test that 'lldb-mi --interpreter' works for -var-update."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to BP_var_update_test_init
line = line_number('main.cpp', '// BP_var_update_test_init')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Setup variables
self.runCmd("-var-create var_l * l")
self.expect(
"\^done,name=\"var_l\",numchild=\"0\",value=\"1\",type=\"long\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-create var_complx * complx")
self.expect(
"\^done,name=\"var_complx\",numchild=\"3\",value=\"\{\.\.\.\}\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-create var_complx_array * complx_array")
self.expect(
"\^done,name=\"var_complx_array\",numchild=\"2\",value=\"\[2\]\",type=\"complex_type \[2\]\",thread-id=\"1\",has_more=\"0\"")
# Go to BP_var_update_test_l
line = line_number('main.cpp', '// BP_var_update_test_l')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"2\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that var_l was updated
self.runCmd("-var-update --all-values var_l")
self.expect(
"\^done,changelist=\[\{name=\"var_l\",value=\"0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]")
# Go to BP_var_update_test_complx
line = line_number('main.cpp', '// BP_var_update_test_complx')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"3\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that var_complx was updated
self.runCmd("-var-update --all-values var_complx")
self.expect(
"\^done,changelist=\[\{name=\"var_complx\",value=\"\{\.\.\.\}\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]")
# Go to BP_var_update_test_complx_array
line = line_number('main.cpp', '// BP_var_update_test_complx_array')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"4\"")
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test that var_complex_array was updated
self.runCmd("-var-update --all-values var_complx_array")
self.expect(
"\^done,changelist=\[\{name=\"var_complx_array\",value=\"\[2\]\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_var_create_register(self):
"""Test that 'lldb-mi --interpreter' works for -var-create $regname."""
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\"")
# Find name of register 0
self.runCmd("-data-list-register-names 0")
self.expect("\^done,register-names=\[\".+?\"\]")
register_name = self.child.after.split("\"")[1]
# Create variable for register 0
# Note that message is different in Darwin and Linux:
# Darwin: "^done,name=\"var_reg\",numchild=\"0\",value=\"0x[0-9a-f]+\",type=\"unsigned long\",thread-id=\"1\",has_more=\"0\"
# Linux:
# "^done,name=\"var_reg\",numchild=\"0\",value=\"0x[0-9a-f]+\",type=\"unsigned
# int\",thread-id=\"1\",has_more=\"0\"
self.runCmd("-var-create var_reg * $%s" % register_name)
self.expect(
"\^done,name=\"var_reg\",numchild=\"0\",value=\"0x[0-9a-f]+\",type=\"unsigned (long|int)\",thread-id=\"1\",has_more=\"0\"")
# Assign value to variable
self.runCmd("-var-assign var_reg \"6\"")
# FIXME: the output has different format for 32bit and 64bit values
self.expect("\^done,value=\"0x0*?6\"")
# Assert register 0 updated
self.runCmd("-data-list-register-values d 0")
self.expect("\^done,register-values=\[{number=\"0\",value=\"6\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_var_list_children(self):
"""Test that 'lldb-mi --interpreter' works for -var-list-children."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to BP_var_list_children_test
line = line_number('main.cpp', '// BP_var_list_children_test')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Create variable
self.runCmd("-var-create var_complx * complx")
self.expect(
"\^done,name=\"var_complx\",numchild=\"3\",value=\"\{\.\.\.\}\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-create var_complx_array * complx_array")
self.expect(
"\^done,name=\"var_complx_array\",numchild=\"2\",value=\"\[2\]\",type=\"complex_type \[2\]\",thread-id=\"1\",has_more=\"0\"")
self.runCmd("-var-create var_pcomplx * pcomplx")
self.expect(
"\^done,name=\"var_pcomplx\",numchild=\"2\",value=\"\{\.\.\.\}\",type=\"pcomplex_type\",thread-id=\"1\",has_more=\"0\"")
# Test that -var-evaluate-expression can evaluate the children of
# created varobj
self.runCmd("-var-list-children var_complx")
self.runCmd("-var-evaluate-expression var_complx.i")
self.expect("\^done,value=\"3\"")
self.runCmd("-var-list-children var_complx_array")
self.runCmd("-var-evaluate-expression var_complx_array.[0]")
self.expect("\^done,value=\"\{...\}\"")
self.runCmd("-var-list-children var_pcomplx")
self.runCmd("-var-evaluate-expression var_pcomplx.complex_type")
self.expect("\^done,value=\"\{...\}\"")
# Test that -var-list-children lists empty children if range is empty
# (and that print-values is optional)
self.runCmd("-var-list-children var_complx 0 0")
self.expect("\^done,numchild=\"0\",has_more=\"1\"")
self.runCmd("-var-list-children var_complx 99 0")
self.expect("\^done,numchild=\"0\",has_more=\"1\"")
self.runCmd("-var-list-children var_complx 99 3")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
# Test that -var-list-children lists all children with their values
# (and that from and to are optional)
self.runCmd("-var-list-children --all-values var_complx")
self.expect(
"\^done,numchild=\"3\",children=\[child=\{name=\"var_complx\.i\",exp=\"i\",numchild=\"0\",type=\"int\",thread-id=\"1\",value=\"3\",has_more=\"0\"\},child=\{name=\"var_complx\.inner\",exp=\"inner\",numchild=\"1\",type=\"complex_type::\(anonymous struct\)\",thread-id=\"1\",value=\"\{\.\.\.\}\",has_more=\"0\"\},child=\{name=\"var_complx\.complex_ptr\",exp=\"complex_ptr\",numchild=\"3\",type=\"complex_type \*\",thread-id=\"1\",value=\"0x[0-9a-f]+\",has_more=\"0\"\}\],has_more=\"0\"")
self.runCmd("-var-list-children --simple-values var_complx_array")
self.expect(
"\^done,numchild=\"2\",children=\[child=\{name=\"var_complx_array\.\[0\]\",exp=\"\[0\]\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"\},child=\{name=\"var_complx_array\.\[1\]\",exp=\"\[1\]\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"0\"")
self.runCmd("-var-list-children 0 var_pcomplx")
self.expect(
"\^done,numchild=\"2\",children=\[child=\{name=\"var_pcomplx\.complex_type\",exp=\"complex_type\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"\},child={name=\"var_pcomplx\.complx\",exp=\"complx\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"0\"")
# Test that -var-list-children lists children without values
self.runCmd("-var-list-children 0 var_complx 0 1")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx\.i\",exp=\"i\",numchild=\"0\",type=\"int\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"1\"")
self.runCmd("-var-list-children --no-values var_complx 0 1")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx\.i\",exp=\"i\",numchild=\"0\",type=\"int\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"1\"")
self.runCmd("-var-list-children --no-values var_complx_array 0 1")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx_array\.\[0\]\",exp=\"\[0\]\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"1\"")
self.runCmd("-var-list-children --no-values var_pcomplx 0 1")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_pcomplx\.complex_type\",exp=\"complex_type\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"1\"")
# Test that -var-list-children lists children with all values
self.runCmd("-var-list-children 1 var_complx 1 2")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx\.inner\",exp=\"inner\",numchild=\"1\",type=\"complex_type::\(anonymous struct\)\",thread-id=\"1\",value=\"\{\.\.\.\}\",has_more=\"0\"\}\],has_more=\"1\"")
self.runCmd("-var-list-children --all-values var_complx 1 2")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx\.inner\",exp=\"inner\",numchild=\"1\",type=\"complex_type::\(anonymous struct\)\",thread-id=\"1\",value=\"\{\.\.\.\}\",has_more=\"0\"\}\],has_more=\"1\"")
self.runCmd("-var-list-children --all-values var_complx_array 1 2")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx_array\.\[1\]\",exp=\"\[1\]\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",value=\"\{\.\.\.\}\",has_more=\"0\"\}\],has_more=\"0\"")
self.runCmd("-var-list-children --all-values var_pcomplx 1 2")
self.expect(
"\^done,numchild=\"1\",children=\[child={name=\"var_pcomplx\.complx\",exp=\"complx\",numchild=\"3\",type=\"complex_type\",thread-id=\"1\",value=\"\{\.\.\.\}\",has_more=\"0\"\}\],has_more=\"0\"")
# Test that -var-list-children lists children with simple values
self.runCmd("-var-list-children 2 var_complx 2 4")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx\.complex_ptr\",exp=\"complex_ptr\",numchild=\"3\",type=\"complex_type \*\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"0\"")
self.runCmd("-var-list-children --simple-values var_complx 2 4")
self.expect(
"\^done,numchild=\"1\",children=\[child=\{name=\"var_complx\.complex_ptr\",exp=\"complex_ptr\",numchild=\"3\",type=\"complex_type \*\",thread-id=\"1\",has_more=\"0\"\}\],has_more=\"0\"")
self.runCmd("-var-list-children --simple-values var_complx_array 2 4")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
self.runCmd("-var-list-children --simple-values var_pcomplx 2 4")
self.expect("\^done,numchild=\"0\",has_more=\"0\"")
# Test that an invalid from is handled
# FIXME: -1 is treated as unsigned int
self.runCmd("-var-list-children 0 var_complx -1 0")
#self.expect("\^error,msg=\"Command 'var-list-children'\. Variable children range invalid\"")
# Test that an invalid to is handled
# FIXME: -1 is treated as unsigned int
self.runCmd("-var-list-children 0 var_complx 0 -1")
#self.expect("\^error,msg=\"Command 'var-list-children'\. Variable children range invalid\"")
# Test that a missing low-frame or high-frame is handled
self.runCmd("-var-list-children 0 var_complx 0")
self.expect(
"\^error,msg=\"Command 'var-list-children'. Variable children range invalid\"")
@skipIfWindows # llvm.org/pr24452: Get lldb-mi working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_var_create_for_stl_types(self):
"""Test that 'lldb-mi --interpreter' print summary for STL types."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to BP_gdb_set_show_print_char_array_as_string_test
line = line_number('main.cpp', '// BP_cpp_stl_types_test')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Test for std::string
self.runCmd("-var-create - * std_string")
self.expect(
'\^done,name="var\d+",numchild="[0-9]+",value="\\\\"hello\\\\"",type="std::[\S]*?string",thread-id="1",has_more="0"')
@skipIfWindows # llvm.org/pr24452: Get lldb-mi working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
@skipIfRemote # We do not currently support remote debugging via the MI.
@skipIfDarwin
def test_lldbmi_var_create_for_unnamed_objects(self):
"""Test that 'lldb-mi --interpreter' can expand unnamed structures and unions."""
self.spawnLldbMi(args=None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Run to breakpoint
line = line_number('main.cpp', '// BP_unnamed_objects_test')
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
# Evaluate struct_with_unions type and its children
self.runCmd("-var-create v0 * swu")
self.expect(
'\^done,name="v0",numchild="2",value="\{\.\.\.\}",type="struct_with_unions",thread-id="1",has_more="0"')
self.runCmd("-var-list-children v0")
# inspect the first unnamed union
self.runCmd("-var-list-children v0.$0")
self.runCmd("-var-evaluate-expression v0.$0.u_i")
self.expect('\^done,value="1"')
# inspect the second unnamed union
self.runCmd("-var-list-children v0.$1")
self.runCmd("-var-evaluate-expression v0.$1.u1")
self.expect('\^done,value="-1"')
# inspect unnamed structure
self.runCmd("-var-list-children v0.$1.$1")
self.runCmd("-var-evaluate-expression v0.$1.$1.s1")
self.expect('\^done,value="-1"')

View File

@ -1,151 +0,0 @@
//===-- main.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 <cstdint>
#include <string>
struct complex_type
{
int i;
struct { long l; } inner;
complex_type *complex_ptr;
};
struct pcomplex_type : complex_type
{
pcomplex_type(const complex_type &complx_base, const complex_type &complx_member)
: complex_type(complx_base), complx(complx_member) { }
complex_type complx;
static int si;
};
int pcomplex_type::si;
struct struct_with_unions
{
struct_with_unions(): u_i(1), u1(-1) {}
union
{
int u_i;
int u_j;
};
union
{
int u1;
struct
{
short s1;
short s2;
};
};
};
void
var_update_test(void)
{
long l = 1;
complex_type complx = { 3, { 3L }, &complx };
complex_type complx_array[2] = { { 4, { 4L }, &complx_array[1] }, { 5, { 5 }, &complx_array[0] } };
// BP_var_update_test_init
l = 0;
// BP_var_update_test_l
complx.inner.l = 2;
// BP_var_update_test_complx
complx_array[1].inner.l = 4;
// BP_var_update_test_complx_array
}
void
var_list_children_test(void)
{
complex_type complx = { 3, { 3L }, &complx };
complex_type complx_array[2] = { { 4, { 4L }, &complx_array[1] }, { 5, { 5 }, &complx_array[0] } };
pcomplex_type pcomplx({ 6, { 6L }, &pcomplx}, { 7, { 7L }, &pcomplx});
// BP_var_list_children_test
}
void
gdb_set_show_print_char_array_as_string_test(void)
{
const char *cp = "\t\"hello\"\n";
const char ca[] = "\t\"hello\"\n";
const char16_t *u16p = u"\t\"hello\"\n";
const char16_t u16a[] = u"\t\"hello\"\n";
const char32_t *u32p = U"\t\"hello\"\n";
const char32_t u32a[] = U"\t\"hello\"\n";
const char16_t* u16p_rus = u"\\Аламо-сквер";
const char16_t u16a_rus[] = u"\\Бейвью";
const char32_t* u32p_rus = U"\\Чайнатаун";
const char32_t u32a_rus[] = U"\\Догпатч";
// BP_gdb_set_show_print_char_array_as_string_test
}
void
cpp_stl_types_test(void)
{
std::string std_string = "hello";
// BP_cpp_stl_types_test
}
void
unnamed_objects_test(void)
{
struct_with_unions swu;
// BP_unnamed_objects_test
}
struct not_str
{
not_str(char _c, int _f)
: c(_c), f(_f) { }
char c;
int f;
};
void
gdb_set_show_print_expand_aggregates(void)
{
complex_type complx = { 3, { 3L }, &complx };
complex_type complx_array[2] = { { 4, { 4L }, &complx_array[1] }, { 5, { 5 }, &complx_array[0] } };
not_str nstr('a', 0);
// BP_gdb_set_show_print_expand_aggregates
}
void
gdb_set_show_print_aggregate_field_names(void)
{
complex_type complx = { 3, { 3L }, &complx };
complex_type complx_array[2] = { { 4, { 4L }, &complx_array[1] }, { 5, { 5 }, &complx_array[0] } };
// BP_gdb_set_show_print_aggregate_field_names
}
int g_MyVar = 3;
static int s_MyVar = 4;
int
main(int argc, char const *argv[])
{
int a = 10, b = 20;
s_MyVar = a + b;
var_update_test();
var_list_children_test();
gdb_set_show_print_char_array_as_string_test();
cpp_stl_types_test();
unnamed_objects_test();
gdb_set_show_print_expand_aggregates();
gdb_set_show_print_aggregate_field_names();
return 0; // BP_return
}

View File

@ -1 +0,0 @@
BasedOnStyle: LLVM

View File

@ -1,8 +0,0 @@
LEVEL = ../../make
override CFLAGS_EXTRAS += -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS
ENABLE_THREADS := YES
CXX_SOURCES := main.cpp
MAKE_DSYM :=NO
include $(LEVEL)/Makefile.rules

View File

@ -1,123 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import json
class TestAppleSimulatorOSType(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def check_simulator_ostype(self, sdk, platform, arch='x86_64'):
sim_devices_str = subprocess.check_output(['xcrun', 'simctl', 'list',
'-j', 'devices']).decode("utf-8")
sim_devices = json.loads(sim_devices_str)['devices']
# Find an available simulator for the requested platform
deviceUDID = None
for simulator in sim_devices:
if isinstance(simulator,dict):
runtime = simulator['name']
devices = simulator['devices']
else:
runtime = simulator
devices = sim_devices[simulator]
if not platform in runtime.lower():
continue
for device in devices:
if 'availability' in device and device['availability'] != '(available)':
continue
if 'isAvailable' in device and device['isAvailable'] != True:
continue
deviceUDID = device['udid']
break
if deviceUDID != None:
break
# Launch the process using simctl
self.assertIsNotNone(deviceUDID)
exe_name = 'test_simulator_platform_{}'.format(platform)
sdkroot = subprocess.check_output(['xcrun', '--show-sdk-path', '--sdk',
sdk]).decode("utf-8")
self.build(dictionary={ 'EXE': exe_name, 'SDKROOT': sdkroot.strip(),
'ARCH': arch })
exe_path = self.getBuildArtifact(exe_name)
sim_launcher = subprocess.Popen(['xcrun', 'simctl', 'spawn',
deviceUDID, exe_path,
'print-pid', 'sleep:10'],
stderr=subprocess.PIPE)
# Get the PID from the process output
pid = None
while not pid:
stderr = sim_launcher.stderr.readline().decode("utf-8")
if stderr == '':
continue
m = re.match(r"PID: (.*)", stderr)
self.assertIsNotNone(m)
pid = int(m.group(1))
# Launch debug monitor attaching to the simulated process
self.init_debugserver_test()
server = self.connect_to_debug_monitor(attach_pid=pid)
# Setup packet sequences
self.add_no_ack_remote_stream()
self.add_process_info_collection_packets()
self.test_sequence.add_log_lines(
["read packet: " +
"$jGetLoadedDynamicLibrariesInfos:{\"fetch_all_solibs\" : true}]#ce",
{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
"capture": {1: "dylib_info_raw"}}],
True)
# Run the stream
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info response
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
# Check that ostype is correct
self.assertEquals(process_info['ostype'], platform)
# Now for dylibs
dylib_info_raw = context.get("dylib_info_raw")
dylib_info = json.loads(self.decode_gdbremote_binary(dylib_info_raw))
images = dylib_info['images']
image_info = None
for image in images:
if image['pathname'] != exe_path:
continue
image_info = image
break
self.assertIsNotNone(image_info)
self.assertEquals(image['min_version_os_name'], platform)
@apple_simulator_test('iphone')
@debugserver_test
@skipIfDarwinEmbedded
def test_simulator_ostype_ios(self):
self.check_simulator_ostype(sdk='iphonesimulator',
platform='ios')
@apple_simulator_test('appletv')
@debugserver_test
@skipIfDarwinEmbedded
def test_simulator_ostype_tvos(self):
self.check_simulator_ostype(sdk='appletvsimulator',
platform='tvos')
@apple_simulator_test('watch')
@debugserver_test
@skipIfDarwinEmbedded
def test_simulator_ostype_watchos(self):
self.check_simulator_ostype(sdk='watchsimulator',
platform='watchos', arch='i386')

View File

@ -1,67 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteAttach(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def attach_with_vAttach(self):
# Start the inferior, start the debug monitor, nothing is attached yet.
procs = self.prep_debug_monitor_and_inferior(
inferior_args=["sleep:60"])
self.assertIsNotNone(procs)
# Make sure the target process has been launched.
inferior = procs.get("inferior")
self.assertIsNotNone(inferior)
self.assertTrue(inferior.pid > 0)
self.assertTrue(
lldbgdbserverutils.process_is_running(
inferior.pid, True))
# Add attach packets.
self.test_sequence.add_log_lines([
# Do the attach.
"read packet: $vAttach;{:x}#00".format(inferior.pid),
# Expect a stop notification from the attach.
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
"capture": {1: "stop_signal_hex"}},
], True)
self.add_process_info_collection_packets()
# Run the stream
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info response
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
# Ensure the process id matches what we expected.
pid_text = process_info.get('pid', None)
self.assertIsNotNone(pid_text)
reported_pid = int(pid_text, base=16)
self.assertEqual(reported_pid, inferior.pid)
@debugserver_test
def test_attach_with_vAttach_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_attach_manually()
self.attach_with_vAttach()
@llgs_test
def test_attach_with_vAttach_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_attach_manually()
self.attach_with_vAttach()

View File

@ -1,220 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteAuxvSupport(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
AUXV_SUPPORT_FEATURE_NAME = "qXfer:auxv:read"
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def has_auxv_support(self):
inferior_args = ["message:main entered", "sleep:5"]
procs = self.prep_debug_monitor_and_inferior(
inferior_args=inferior_args)
# Don't do anything until we match the launched inferior main entry output.
# Then immediately interrupt the process.
# This prevents auxv data being asked for before it's ready and leaves
# us in a stopped state.
self.test_sequence.add_log_lines([
# Start the inferior...
"read packet: $c#63",
# ... match output....
{"type": "output_match", "regex": self.maybe_strict_output_regex(
r"message:main entered\r\n")},
], True)
# ... then interrupt.
self.add_interrupt_packets()
self.add_qSupported_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
features = self.parse_qSupported_response(context)
return self.AUXV_SUPPORT_FEATURE_NAME in features and features[
self.AUXV_SUPPORT_FEATURE_NAME] == "+"
def get_raw_auxv_data(self):
# Start up llgs and inferior, and check for auxv support.
if not self.has_auxv_support():
self.skipTest("auxv data not supported")
# Grab pointer size for target. We'll assume that is equivalent to an unsigned long on the target.
# Auxv is specified in terms of pairs of unsigned longs.
self.reset_test_sequence()
self.add_process_info_collection_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
proc_info = self.parse_process_info_response(context)
self.assertIsNotNone(proc_info)
self.assertTrue("ptrsize" in proc_info)
word_size = int(proc_info["ptrsize"])
OFFSET = 0
LENGTH = 0x400
# Grab the auxv data.
self.reset_test_sequence()
self.test_sequence.add_log_lines(
[
"read packet: $qXfer:auxv:read::{:x},{:x}:#00".format(
OFFSET,
LENGTH),
{
"direction": "send",
"regex": re.compile(
r"^\$([^E])(.*)#[0-9a-fA-F]{2}$",
re.MULTILINE | re.DOTALL),
"capture": {
1: "response_type",
2: "content_raw"}}],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Ensure we end up with all auxv data in one packet.
# FIXME don't assume it all comes back in one packet.
self.assertEqual(context.get("response_type"), "l")
# Decode binary data.
content_raw = context.get("content_raw")
self.assertIsNotNone(content_raw)
return (word_size, self.decode_gdbremote_binary(content_raw))
def supports_auxv(self):
# When non-auxv platforms support llgs, skip the test on platforms
# that don't support auxv.
self.assertTrue(self.has_auxv_support())
#
# We skip the "supports_auxv" test on debugserver. The rest of the tests
# appropriately skip the auxv tests if the support flag is not present
# in the qSupported response, so the debugserver test bits are still there
# in case debugserver code one day does have auxv support and thus those
# tests don't get skipped.
#
@llgs_test
def test_supports_auxv_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.supports_auxv()
def auxv_data_is_correct_size(self):
(word_size, auxv_data) = self.get_raw_auxv_data()
self.assertIsNotNone(auxv_data)
# Ensure auxv data is a multiple of 2*word_size (there should be two
# unsigned long fields per auxv entry).
self.assertEqual(len(auxv_data) % (2 * word_size), 0)
# print("auxv contains {} entries".format(len(auxv_data) / (2*word_size)))
@debugserver_test
def test_auxv_data_is_correct_size_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.auxv_data_is_correct_size()
@llgs_test
def test_auxv_data_is_correct_size_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.auxv_data_is_correct_size()
def auxv_keys_look_valid(self):
(word_size, auxv_data) = self.get_raw_auxv_data()
self.assertIsNotNone(auxv_data)
# Grab endian.
self.reset_test_sequence()
self.add_process_info_collection_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
endian = process_info.get("endian")
self.assertIsNotNone(endian)
auxv_dict = self.build_auxv_dict(endian, word_size, auxv_data)
self.assertIsNotNone(auxv_dict)
# Verify keys look reasonable.
for auxv_key in auxv_dict:
self.assertTrue(auxv_key >= 1)
self.assertTrue(auxv_key <= 1000)
# print("auxv dict: {}".format(auxv_dict))
@debugserver_test
def test_auxv_keys_look_valid_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.auxv_keys_look_valid()
@llgs_test
def test_auxv_keys_look_valid_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.auxv_keys_look_valid()
def auxv_chunked_reads_work(self):
# Verify that multiple smaller offset,length reads of auxv data
# return the same data as a single larger read.
# Grab the auxv data with a single large read here.
(word_size, auxv_data) = self.get_raw_auxv_data()
self.assertIsNotNone(auxv_data)
# Grab endian.
self.reset_test_sequence()
self.add_process_info_collection_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
endian = process_info.get("endian")
self.assertIsNotNone(endian)
auxv_dict = self.build_auxv_dict(endian, word_size, auxv_data)
self.assertIsNotNone(auxv_dict)
iterated_auxv_data = self.read_binary_data_in_chunks(
"qXfer:auxv:read::", 2 * word_size)
self.assertIsNotNone(iterated_auxv_data)
auxv_dict_iterated = self.build_auxv_dict(
endian, word_size, iterated_auxv_data)
self.assertIsNotNone(auxv_dict_iterated)
# Verify both types of data collection returned same content.
self.assertEqual(auxv_dict_iterated, auxv_dict)
@debugserver_test
def test_auxv_chunked_reads_work_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.auxv_chunked_reads_work()
@llgs_test
def test_auxv_chunked_reads_work_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.auxv_chunked_reads_work()

View File

@ -1,127 +0,0 @@
from __future__ import print_function
# lldb test suite imports
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import TestBase
# gdb-remote-specific imports
import lldbgdbserverutils
from gdbremote_testcase import GdbRemoteTestCaseBase
class TestGdbRemoteExitCode(GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
FAILED_LAUNCH_CODE = "E08"
def get_launch_fail_reason(self):
self.reset_test_sequence()
self.test_sequence.add_log_lines(
["read packet: $qLaunchSuccess#00"],
True)
self.test_sequence.add_log_lines(
[{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
"capture": {1: "launch_result"}}],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
return context.get("launch_result")[1:]
def start_inferior(self):
launch_args = self.install_and_create_launch_args()
server = self.connect_to_debug_monitor()
self.assertIsNotNone(server)
self.add_no_ack_remote_stream()
self.test_sequence.add_log_lines(
["read packet: %s" % lldbgdbserverutils.build_gdbremote_A_packet(
launch_args)],
True)
self.test_sequence.add_log_lines(
[{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
"capture": {1: "A_result"}}],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
launch_result = context.get("A_result")
self.assertIsNotNone(launch_result)
if launch_result == self.FAILED_LAUNCH_CODE:
fail_reason = self.get_launch_fail_reason()
self.fail("failed to launch inferior: " + fail_reason)
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_start_inferior_debugserver(self):
self.init_debugserver_test()
self.build()
self.start_inferior()
@llgs_test
def test_start_inferior_llgs(self):
self.init_llgs_test()
self.build()
self.start_inferior()
def inferior_exit_0(self):
launch_args = self.install_and_create_launch_args()
server = self.connect_to_debug_monitor()
self.assertIsNotNone(server)
self.add_no_ack_remote_stream()
self.add_verified_launch_packets(launch_args)
self.test_sequence.add_log_lines(
["read packet: $vCont;c#a8",
"send packet: $W00#00"],
True)
self.expect_gdbremote_sequence()
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_inferior_exit_0_debugserver(self):
self.init_debugserver_test()
self.build()
self.inferior_exit_0()
@llgs_test
def test_inferior_exit_0_llgs(self):
self.init_llgs_test()
self.build()
self.inferior_exit_0()
def inferior_exit_42(self):
launch_args = self.install_and_create_launch_args()
server = self.connect_to_debug_monitor()
self.assertIsNotNone(server)
RETVAL = 42
# build launch args
launch_args += ["retval:%d" % RETVAL]
self.add_no_ack_remote_stream()
self.add_verified_launch_packets(launch_args)
self.test_sequence.add_log_lines(
["read packet: $vCont;c#a8",
"send packet: $W{0:02x}#00".format(RETVAL)],
True)
self.expect_gdbremote_sequence()
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_inferior_exit_42_debugserver(self):
self.init_debugserver_test()
self.build()
self.inferior_exit_42()
@llgs_test
def test_inferior_exit_42_llgs(self):
self.init_llgs_test()
self.build()
self.inferior_exit_42()

View File

@ -1,162 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteExpeditedRegisters(
gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def gather_expedited_registers(self):
# Setup the stub and set the gdb remote command stream.
procs = self.prep_debug_monitor_and_inferior(inferior_args=["sleep:2"])
self.test_sequence.add_log_lines([
# Start up the inferior.
"read packet: $c#63",
# Immediately tell it to stop. We want to see what it reports.
"read packet: {}".format(chr(3)),
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]+)([^#]+)#[0-9a-fA-F]{2}$",
"capture": {1: "stop_result",
2: "key_vals_text"}},
], True)
# Run the gdb remote command stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Pull out expedited registers.
key_vals_text = context.get("key_vals_text")
self.assertIsNotNone(key_vals_text)
expedited_registers = self.extract_registers_from_stop_notification(
key_vals_text)
self.assertIsNotNone(expedited_registers)
return expedited_registers
def stop_notification_contains_generic_register(
self, generic_register_name):
# Generate a stop reply, parse out expedited registers from stop
# notification.
expedited_registers = self.gather_expedited_registers()
self.assertIsNotNone(expedited_registers)
self.assertTrue(len(expedited_registers) > 0)
# Gather target register infos.
reg_infos = self.gather_register_infos()
# Find the generic register.
reg_info = self.find_generic_register_with_name(
reg_infos, generic_register_name)
self.assertIsNotNone(reg_info)
# Ensure the expedited registers contained it.
self.assertTrue(reg_info["lldb_register_index"] in expedited_registers)
# print("{} reg_info:{}".format(generic_register_name, reg_info))
def stop_notification_contains_any_registers(self):
# Generate a stop reply, parse out expedited registers from stop
# notification.
expedited_registers = self.gather_expedited_registers()
# Verify we have at least one expedited register.
self.assertTrue(len(expedited_registers) > 0)
@debugserver_test
def test_stop_notification_contains_any_registers_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_any_registers()
@llgs_test
def test_stop_notification_contains_any_registers_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_any_registers()
def stop_notification_contains_no_duplicate_registers(self):
# Generate a stop reply, parse out expedited registers from stop
# notification.
expedited_registers = self.gather_expedited_registers()
# Verify no expedited register was specified multiple times.
for (reg_num, value) in list(expedited_registers.items()):
if (isinstance(value, list)) and (len(value) > 0):
self.fail(
"expedited register number {} specified more than once ({} times)".format(
reg_num, len(value)))
@debugserver_test
def test_stop_notification_contains_no_duplicate_registers_debugserver(
self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_no_duplicate_registers()
@llgs_test
def test_stop_notification_contains_no_duplicate_registers_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_no_duplicate_registers()
def stop_notification_contains_pc_register(self):
self.stop_notification_contains_generic_register("pc")
@debugserver_test
def test_stop_notification_contains_pc_register_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_pc_register()
@llgs_test
def test_stop_notification_contains_pc_register_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_pc_register()
# powerpc64 has no FP register
@skipIf(triple='^powerpc64')
def stop_notification_contains_fp_register(self):
self.stop_notification_contains_generic_register("fp")
@debugserver_test
def test_stop_notification_contains_fp_register_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_fp_register()
@llgs_test
def test_stop_notification_contains_fp_register_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_fp_register()
def stop_notification_contains_sp_register(self):
self.stop_notification_contains_generic_register("sp")
@debugserver_test
def test_stop_notification_contains_sp_register_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_sp_register()
@llgs_test
def test_stop_notification_contains_sp_register_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_notification_contains_sp_register()

View File

@ -1,131 +0,0 @@
from __future__ import print_function
# lldb test suite imports
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import TestBase
# gdb-remote-specific imports
import lldbgdbserverutils
from gdbremote_testcase import GdbRemoteTestCaseBase
class TestGdbRemoteHostInfo(GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
KNOWN_HOST_INFO_KEYS = set([
"arch",
"cputype",
"cpusubtype",
"distribution_id",
"endian",
"hostname",
"ostype",
"os_build",
"os_kernel",
"os_version",
"ptrsize",
"triple",
"vendor",
"watchpoint_exceptions_received",
"default_packet_timeout",
])
DARWIN_REQUIRED_HOST_INFO_KEYS = set([
"cputype",
"cpusubtype",
"endian",
"ostype",
"ptrsize",
"vendor",
"watchpoint_exceptions_received"
])
def add_host_info_collection_packets(self):
self.test_sequence.add_log_lines(
["read packet: $qHostInfo#9b",
{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
"capture": {1: "host_info_raw"}}],
True)
def parse_host_info_response(self, context):
# Ensure we have a host info response.
self.assertIsNotNone(context)
host_info_raw = context.get("host_info_raw")
self.assertIsNotNone(host_info_raw)
# Pull out key:value; pairs.
host_info_dict = {match.group(1): match.group(2)
for match in re.finditer(r"([^:]+):([^;]+);",
host_info_raw)}
import pprint
print("\nqHostInfo response:")
pprint.pprint(host_info_dict)
# Validate keys are known.
for (key, val) in list(host_info_dict.items()):
self.assertTrue(key in self.KNOWN_HOST_INFO_KEYS,
"unknown qHostInfo key: " + key)
self.assertIsNotNone(val)
# Return the key:val pairs.
return host_info_dict
def get_qHostInfo_response(self):
# Launch the debug monitor stub, attaching to the inferior.
server = self.connect_to_debug_monitor()
self.assertIsNotNone(server)
self.add_no_ack_remote_stream()
# Request qHostInfo and get response
self.add_host_info_collection_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Parse qHostInfo response.
host_info = self.parse_host_info_response(context)
self.assertIsNotNone(host_info)
self.assertGreater(len(host_info), 0, "qHostInfo should have returned "
"at least one key:val pair.")
return host_info
def validate_darwin_minimum_host_info_keys(self, host_info_dict):
self.assertIsNotNone(host_info_dict)
missing_keys = [key for key in self.DARWIN_REQUIRED_HOST_INFO_KEYS
if key not in host_info_dict]
self.assertEquals(0, len(missing_keys),
"qHostInfo is missing the following required "
"keys: " + str(missing_keys))
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_qHostInfo_returns_at_least_one_key_val_pair_debugserver(self):
self.init_debugserver_test()
self.build()
self.get_qHostInfo_response()
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@llgs_test
def test_qHostInfo_returns_at_least_one_key_val_pair_llgs(self):
self.init_llgs_test()
self.build()
self.get_qHostInfo_response()
@skipUnlessDarwin
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_qHostInfo_contains_darwin_required_keys_debugserver(self):
self.init_debugserver_test()
self.build()
host_info_dict = self.get_qHostInfo_response()
self.validate_darwin_minimum_host_info_keys(host_info_dict)
@skipUnlessDarwin
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@llgs_test
def test_qHostInfo_contains_darwin_required_keys_llgs(self):
self.init_llgs_test()
self.build()
host_info_dict = self.get_qHostInfo_response()
self.validate_darwin_minimum_host_info_keys(host_info_dict)

View File

@ -1,59 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteKill(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def attach_commandline_kill_after_initial_stop(self):
procs = self.prep_debug_monitor_and_inferior()
self.test_sequence.add_log_lines([
"read packet: $k#6b",
{"direction": "send", "regex": r"^\$X[0-9a-fA-F]+([^#]*)#[0-9A-Fa-f]{2}"},
], True)
if self.stub_sends_two_stop_notifications_on_kill:
# Add an expectation for a second X result for stubs that send two
# of these.
self.test_sequence.add_log_lines([
{"direction": "send", "regex": r"^\$X[0-9a-fA-F]+([^#]*)#[0-9A-Fa-f]{2}"},
], True)
self.expect_gdbremote_sequence()
# Wait a moment for completed and now-detached inferior process to
# clear.
time.sleep(1)
if not lldb.remote_platform:
# Process should be dead now. Reap results.
poll_result = procs["inferior"].poll()
self.assertIsNotNone(poll_result)
# Where possible, verify at the system level that the process is not
# running.
self.assertFalse(
lldbgdbserverutils.process_is_running(
procs["inferior"].pid, False))
@debugserver_test
def test_attach_commandline_kill_after_initial_stop_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_attach()
self.attach_commandline_kill_after_initial_stop()
@llgs_test
def test_attach_commandline_kill_after_initial_stop_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_attach()
self.attach_commandline_kill_after_initial_stop()

View File

@ -1,44 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
from lldbsuite.support import seven
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteModuleInfo(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def module_info(self):
procs = self.prep_debug_monitor_and_inferior()
self.add_process_info_collection_packets()
context = self.expect_gdbremote_sequence()
info = self.parse_process_info_response(context)
self.test_sequence.add_log_lines([
'read packet: $jModulesInfo:[{"file":"%s","triple":"%s"}]]#00' % (
lldbutil.append_to_process_working_directory(self, "a.out"),
seven.unhexlify(info["triple"])),
{"direction": "send",
"regex": r'^\$\[{(.*)}\]\]#[0-9A-Fa-f]{2}',
"capture": {1: "spec"}},
], True)
context = self.expect_gdbremote_sequence()
spec = context.get("spec")
self.assertRegexpMatches(spec, '"file_path":".*"')
self.assertRegexpMatches(spec, '"file_offset":\d+')
self.assertRegexpMatches(spec, '"file_size":\d+')
self.assertRegexpMatches(spec, '"triple":"\w*-\w*-.*"')
self.assertRegexpMatches(spec, '"uuid":"[A-Fa-f0-9]+"')
@llgs_test
def test_module_info(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.module_info()

View File

@ -1,211 +0,0 @@
from __future__ import print_function
import sys
import gdbremote_testcase
import lldbgdbserverutils
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteProcessInfo(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def qProcessInfo_returns_running_process(self):
procs = self.prep_debug_monitor_and_inferior()
self.add_process_info_collection_packets()
# Run the stream
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info response
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
# Ensure the process id looks reasonable.
pid_text = process_info.get("pid")
self.assertIsNotNone(pid_text)
pid = int(pid_text, base=16)
self.assertNotEqual(0, pid)
# If possible, verify that the process is running.
self.assertTrue(lldbgdbserverutils.process_is_running(pid, True))
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_qProcessInfo_returns_running_process_debugserver(self):
self.init_debugserver_test()
self.build()
self.qProcessInfo_returns_running_process()
@llgs_test
def test_qProcessInfo_returns_running_process_llgs(self):
self.init_llgs_test()
self.build()
self.qProcessInfo_returns_running_process()
def attach_commandline_qProcessInfo_reports_correct_pid(self):
procs = self.prep_debug_monitor_and_inferior()
self.assertIsNotNone(procs)
self.add_process_info_collection_packets()
# Run the stream
context = self.expect_gdbremote_sequence(timeout_seconds=8)
self.assertIsNotNone(context)
# Gather process info response
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
# Ensure the process id matches what we expected.
pid_text = process_info.get('pid', None)
self.assertIsNotNone(pid_text)
reported_pid = int(pid_text, base=16)
self.assertEqual(reported_pid, procs["inferior"].pid)
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_attach_commandline_qProcessInfo_reports_correct_pid_debugserver(
self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_attach()
self.attach_commandline_qProcessInfo_reports_correct_pid()
@llgs_test
def test_attach_commandline_qProcessInfo_reports_correct_pid_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_attach()
self.attach_commandline_qProcessInfo_reports_correct_pid()
def qProcessInfo_reports_valid_endian(self):
procs = self.prep_debug_monitor_and_inferior()
self.add_process_info_collection_packets()
# Run the stream
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info response
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
# Ensure the process id looks reasonable.
endian = process_info.get("endian")
self.assertIsNotNone(endian)
self.assertTrue(endian in ["little", "big", "pdp"])
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_qProcessInfo_reports_valid_endian_debugserver(self):
self.init_debugserver_test()
self.build()
self.qProcessInfo_reports_valid_endian()
@llgs_test
def test_qProcessInfo_reports_valid_endian_llgs(self):
self.init_llgs_test()
self.build()
self.qProcessInfo_reports_valid_endian()
def qProcessInfo_contains_keys(self, expected_key_set):
procs = self.prep_debug_monitor_and_inferior()
self.add_process_info_collection_packets()
# Run the stream
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info response
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
# Ensure the expected keys are present and non-None within the process
# info.
missing_key_set = set()
for expected_key in expected_key_set:
if expected_key not in process_info:
missing_key_set.add(expected_key)
self.assertEqual(
missing_key_set,
set(),
"the listed keys are missing in the qProcessInfo result")
def qProcessInfo_does_not_contain_keys(self, absent_key_set):
procs = self.prep_debug_monitor_and_inferior()
self.add_process_info_collection_packets()
# Run the stream
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info response
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)
# Ensure the unexpected keys are not present
unexpected_key_set = set()
for unexpected_key in absent_key_set:
if unexpected_key in process_info:
unexpected_key_set.add(unexpected_key)
self.assertEqual(
unexpected_key_set,
set(),
"the listed keys were present but unexpected in qProcessInfo result")
@skipUnlessDarwin
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_qProcessInfo_contains_cputype_cpusubtype_debugserver_darwin(self):
self.init_debugserver_test()
self.build()
self.qProcessInfo_contains_keys(set(['cputype', 'cpusubtype']))
@skipUnlessDarwin
@llgs_test
def test_qProcessInfo_contains_cputype_cpusubtype_llgs_darwin(self):
self.init_llgs_test()
self.build()
self.qProcessInfo_contains_keys(set(['cputype', 'cpusubtype']))
@skipUnlessPlatform(["linux"])
@llgs_test
def test_qProcessInfo_contains_triple_llgs_linux(self):
self.init_llgs_test()
self.build()
self.qProcessInfo_contains_keys(set(['triple']))
@skipUnlessDarwin
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_qProcessInfo_does_not_contain_triple_debugserver_darwin(self):
self.init_debugserver_test()
self.build()
# We don't expect to see triple on darwin. If we do, we'll prefer triple
# to cputype/cpusubtype and skip some darwin-based ProcessGDBRemote ArchSpec setup
# for the remote Host and Process.
self.qProcessInfo_does_not_contain_keys(set(['triple']))
@skipUnlessDarwin
@llgs_test
def test_qProcessInfo_does_not_contain_triple_llgs_darwin(self):
self.init_llgs_test()
self.build()
# We don't expect to see triple on darwin. If we do, we'll prefer triple
# to cputype/cpusubtype and skip some darwin-based ProcessGDBRemote ArchSpec setup
# for the remote Host and Process.
self.qProcessInfo_does_not_contain_keys(set(['triple']))
@skipUnlessPlatform(["linux"])
@llgs_test
def test_qProcessInfo_does_not_contain_cputype_cpusubtype_llgs_linux(self):
self.init_llgs_test()
self.build()
self.qProcessInfo_does_not_contain_keys(set(['cputype', 'cpusubtype']))

View File

@ -1,128 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
"""Test QSaveRegisterState/QRestoreRegisterState support."""
mydir = TestBase.compute_mydir(__file__)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def grp_register_save_restore_works(self, with_suffix):
# Start up the process, use thread suffix, grab main thread id.
inferior_args = ["message:main entered", "sleep:5"]
procs = self.prep_debug_monitor_and_inferior(
inferior_args=inferior_args)
self.add_process_info_collection_packets()
self.add_register_info_collection_packets()
if with_suffix:
self.add_thread_suffix_request_packets()
self.add_threadinfo_collection_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info.
process_info = self.parse_process_info_response(context)
endian = process_info.get("endian")
self.assertIsNotNone(endian)
# Gather register info.
reg_infos = self.parse_register_info_packets(context)
self.assertIsNotNone(reg_infos)
self.add_lldb_register_index(reg_infos)
# Pull out the register infos that we think we can bit flip
# successfully.
gpr_reg_infos = [
reg_info for reg_info in reg_infos if self.is_bit_flippable_register(reg_info)]
self.assertTrue(len(gpr_reg_infos) > 0)
# Gather thread info.
if with_suffix:
threads = self.parse_threadinfo_packets(context)
self.assertIsNotNone(threads)
thread_id = threads[0]
self.assertIsNotNone(thread_id)
# print("Running on thread: 0x{:x}".format(thread_id))
else:
thread_id = None
# Save register state.
self.reset_test_sequence()
self.add_QSaveRegisterState_packets(thread_id)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
(success, state_id) = self.parse_QSaveRegisterState_response(context)
self.assertTrue(success)
self.assertIsNotNone(state_id)
# print("saved register state id: {}".format(state_id))
# Remember initial register values.
initial_reg_values = self.read_register_values(
gpr_reg_infos, endian, thread_id=thread_id)
# print("initial_reg_values: {}".format(initial_reg_values))
# Flip gpr register values.
(successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
gpr_reg_infos, endian, thread_id=thread_id)
# print("successful writes: {}, failed writes: {}".format(successful_writes, failed_writes))
self.assertTrue(successful_writes > 0)
flipped_reg_values = self.read_register_values(
gpr_reg_infos, endian, thread_id=thread_id)
# print("flipped_reg_values: {}".format(flipped_reg_values))
# Restore register values.
self.reset_test_sequence()
self.add_QRestoreRegisterState_packets(state_id, thread_id)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Verify registers match initial register values.
final_reg_values = self.read_register_values(
gpr_reg_infos, endian, thread_id=thread_id)
# print("final_reg_values: {}".format(final_reg_values))
self.assertIsNotNone(final_reg_values)
self.assertEqual(final_reg_values, initial_reg_values)
@debugserver_test
def test_grp_register_save_restore_works_with_suffix_debugserver(self):
USE_THREAD_SUFFIX = True
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
@llgs_test
def test_grp_register_save_restore_works_with_suffix_llgs(self):
USE_THREAD_SUFFIX = True
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
@debugserver_test
def test_grp_register_save_restore_works_no_suffix_debugserver(self):
USE_THREAD_SUFFIX = False
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
@llgs_test
def test_grp_register_save_restore_works_no_suffix_llgs(self):
USE_THREAD_SUFFIX = False
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)

View File

@ -1,41 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteSingleStep(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_single_step_only_steps_one_instruction_with_s_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.single_step_only_steps_one_instruction(
use_Hc_packet=True, step_instruction="s")
@llgs_test
@expectedFailureAndroid(
bugnumber="llvm.org/pr24739",
archs=[
"arm",
"aarch64"])
@expectedFailureAll(
oslist=["linux"],
archs=[
"arm",
"aarch64"],
bugnumber="llvm.org/pr24739")
@skipIf(triple='^mips')
def test_single_step_only_steps_one_instruction_with_s_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.single_step_only_steps_one_instruction(
use_Hc_packet=True, step_instruction="s")

View File

@ -1,303 +0,0 @@
from __future__ import print_function
import json
import re
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteThreadsInStopReply(
gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
ENABLE_THREADS_IN_STOP_REPLY_ENTRIES = [
"read packet: $QListThreadsInStopReply#21",
"send packet: $OK#00",
]
def gather_stop_reply_fields(self, post_startup_log_lines, thread_count,
field_names):
# Set up the inferior args.
inferior_args = []
for i in range(thread_count - 1):
inferior_args.append("thread:new")
inferior_args.append("sleep:10")
procs = self.prep_debug_monitor_and_inferior(
inferior_args=inferior_args)
self.add_register_info_collection_packets()
self.add_process_info_collection_packets()
# Assumes test_sequence has anything added needed to setup the initial state.
# (Like optionally enabling QThreadsInStopReply.)
if post_startup_log_lines:
self.test_sequence.add_log_lines(post_startup_log_lines, True)
self.test_sequence.add_log_lines([
"read packet: $c#63"
], True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
hw_info = self.parse_hw_info(context)
# Give threads time to start up, then break.
time.sleep(1)
self.reset_test_sequence()
self.test_sequence.add_log_lines(
[
"read packet: {}".format(
chr(3)),
{
"direction": "send",
"regex": r"^\$T([0-9a-fA-F]+)([^#]+)#[0-9a-fA-F]{2}$",
"capture": {
1: "stop_result",
2: "key_vals_text"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Wait until all threads have started.
threads = self.wait_for_thread_count(thread_count, timeout_seconds=3)
self.assertIsNotNone(threads)
self.assertEqual(len(threads), thread_count)
# Run, then stop the process, grab the stop reply content.
self.reset_test_sequence()
self.test_sequence.add_log_lines(["read packet: $c#63",
"read packet: {}".format(chr(3)),
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]+)([^#]+)#[0-9a-fA-F]{2}$",
"capture": {1: "stop_result",
2: "key_vals_text"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Parse the stop reply contents.
key_vals_text = context.get("key_vals_text")
self.assertIsNotNone(key_vals_text)
kv_dict = self.parse_key_val_dict(key_vals_text)
self.assertIsNotNone(kv_dict)
result = dict();
result["pc_register"] = hw_info["pc_register"]
result["little_endian"] = hw_info["little_endian"]
for key_field in field_names:
result[key_field] = kv_dict.get(key_field)
return result
def gather_stop_reply_threads(self, post_startup_log_lines, thread_count):
# Pull out threads from stop response.
stop_reply_threads_text = self.gather_stop_reply_fields(
post_startup_log_lines, thread_count, ["threads"])["threads"]
if stop_reply_threads_text:
return [int(thread_id, 16)
for thread_id in stop_reply_threads_text.split(",")]
else:
return []
def gather_stop_reply_pcs(self, post_startup_log_lines, thread_count):
results = self.gather_stop_reply_fields( post_startup_log_lines,
thread_count, ["threads", "thread-pcs"])
if not results:
return []
threads_text = results["threads"]
pcs_text = results["thread-pcs"]
thread_ids = threads_text.split(",")
pcs = pcs_text.split(",")
self.assertTrue(len(thread_ids) == len(pcs))
thread_pcs = dict()
for i in range(0, len(pcs)):
thread_pcs[int(thread_ids[i], 16)] = pcs[i]
result = dict()
result["thread_pcs"] = thread_pcs
result["pc_register"] = results["pc_register"]
result["little_endian"] = results["little_endian"]
return result
def switch_endian(self, egg):
return "".join(reversed(re.findall("..", egg)))
def parse_hw_info(self, context):
self.assertIsNotNone(context)
process_info = self.parse_process_info_response(context)
endian = process_info.get("endian")
reg_info = self.parse_register_info_packets(context)
(pc_lldb_reg_index, pc_reg_info) = self.find_pc_reg_info(reg_info)
hw_info = dict()
hw_info["pc_register"] = pc_lldb_reg_index
hw_info["little_endian"] = (endian == "little")
return hw_info
def gather_threads_info_pcs(self, pc_register, little_endian):
self.reset_test_sequence()
self.test_sequence.add_log_lines(
[
"read packet: $jThreadsInfo#c1",
{
"direction": "send",
"regex": r"^\$(.*)#[0-9a-fA-F]{2}$",
"capture": {
1: "threads_info"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
threads_info = context.get("threads_info")
register = str(pc_register)
# The jThreadsInfo response is not valid JSON data, so we have to
# clean it up first.
jthreads_info = json.loads(re.sub(r"}]", "}", threads_info))
thread_pcs = dict()
for thread_info in jthreads_info:
tid = thread_info["tid"]
pc = thread_info["registers"][register]
thread_pcs[tid] = self.switch_endian(pc) if little_endian else pc
return thread_pcs
def QListThreadsInStopReply_supported(self):
procs = self.prep_debug_monitor_and_inferior()
self.test_sequence.add_log_lines(
self.ENABLE_THREADS_IN_STOP_REPLY_ENTRIES, True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_QListThreadsInStopReply_supported_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.QListThreadsInStopReply_supported()
@llgs_test
def test_QListThreadsInStopReply_supported_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.QListThreadsInStopReply_supported()
def stop_reply_reports_multiple_threads(self, thread_count):
# Gather threads from stop notification when QThreadsInStopReply is
# enabled.
stop_reply_threads = self.gather_stop_reply_threads(
self.ENABLE_THREADS_IN_STOP_REPLY_ENTRIES, thread_count)
self.assertEqual(len(stop_reply_threads), thread_count)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_stop_reply_reports_multiple_threads_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_reply_reports_multiple_threads(5)
@llgs_test
def test_stop_reply_reports_multiple_threads_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_reply_reports_multiple_threads(5)
def no_QListThreadsInStopReply_supplies_no_threads(self, thread_count):
# Gather threads from stop notification when QThreadsInStopReply is not
# enabled.
stop_reply_threads = self.gather_stop_reply_threads(None, thread_count)
self.assertEqual(len(stop_reply_threads), 0)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_no_QListThreadsInStopReply_supplies_no_threads_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.no_QListThreadsInStopReply_supplies_no_threads(5)
@llgs_test
def test_no_QListThreadsInStopReply_supplies_no_threads_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.no_QListThreadsInStopReply_supplies_no_threads(5)
def stop_reply_reports_correct_threads(self, thread_count):
# Gather threads from stop notification when QThreadsInStopReply is
# enabled.
stop_reply_threads = self.gather_stop_reply_threads(
self.ENABLE_THREADS_IN_STOP_REPLY_ENTRIES, thread_count)
self.assertEqual(len(stop_reply_threads), thread_count)
# Gather threads from q{f,s}ThreadInfo.
self.reset_test_sequence()
self.add_threadinfo_collection_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
threads = self.parse_threadinfo_packets(context)
self.assertIsNotNone(threads)
self.assertEqual(len(threads), thread_count)
# Ensure each thread in q{f,s}ThreadInfo appears in stop reply threads
for tid in threads:
self.assertTrue(tid in stop_reply_threads)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_stop_reply_reports_correct_threads_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_reply_reports_correct_threads(5)
@llgs_test
def test_stop_reply_reports_correct_threads_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_reply_reports_correct_threads(5)
def stop_reply_contains_thread_pcs(self, thread_count):
results = self.gather_stop_reply_pcs(
self.ENABLE_THREADS_IN_STOP_REPLY_ENTRIES, thread_count)
stop_reply_pcs = results["thread_pcs"]
pc_register = results["pc_register"]
little_endian = results["little_endian"]
self.assertEqual(len(stop_reply_pcs), thread_count)
threads_info_pcs = self.gather_threads_info_pcs(pc_register,
little_endian)
self.assertEqual(len(threads_info_pcs), thread_count)
for thread_id in stop_reply_pcs:
self.assertTrue(thread_id in threads_info_pcs)
self.assertTrue(int(stop_reply_pcs[thread_id], 16)
== int(threads_info_pcs[thread_id], 16))
@llgs_test
def test_stop_reply_contains_thread_pcs_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.stop_reply_contains_thread_pcs(5)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@debugserver_test
def test_stop_reply_contains_thread_pcs_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.stop_reply_contains_thread_pcs(5)

View File

@ -1,182 +0,0 @@
from __future__ import print_function
import sys
import unittest2
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemote_qThreadStopInfo(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
THREAD_COUNT = 5
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
@skipIfDarwinEmbedded # <rdar://problem/27005337>
def gather_stop_replies_via_qThreadStopInfo(self, thread_count):
# Set up the inferior args.
inferior_args = []
for i in range(thread_count - 1):
inferior_args.append("thread:new")
inferior_args.append("sleep:10")
procs = self.prep_debug_monitor_and_inferior(
inferior_args=inferior_args)
# Assumes test_sequence has anything added needed to setup the initial state.
# (Like optionally enabling QThreadsInStopReply.)
self.test_sequence.add_log_lines([
"read packet: $c#63"
], True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Give threads time to start up, then break.
time.sleep(1)
self.reset_test_sequence()
self.test_sequence.add_log_lines(
[
"read packet: {}".format(
chr(3)),
{
"direction": "send",
"regex": r"^\$T([0-9a-fA-F]+)([^#]+)#[0-9a-fA-F]{2}$",
"capture": {
1: "stop_result",
2: "key_vals_text"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Wait until all threads have started.
threads = self.wait_for_thread_count(thread_count, timeout_seconds=3)
self.assertIsNotNone(threads)
self.assertEqual(len(threads), thread_count)
# Grab stop reply for each thread via qThreadStopInfo{tid:hex}.
stop_replies = {}
thread_dicts = {}
for thread in threads:
# Run the qThreadStopInfo command.
self.reset_test_sequence()
self.test_sequence.add_log_lines(
[
"read packet: $qThreadStopInfo{:x}#00".format(thread),
{
"direction": "send",
"regex": r"^\$T([0-9a-fA-F]+)([^#]+)#[0-9a-fA-F]{2}$",
"capture": {
1: "stop_result",
2: "key_vals_text"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Parse stop reply contents.
key_vals_text = context.get("key_vals_text")
self.assertIsNotNone(key_vals_text)
kv_dict = self.parse_key_val_dict(key_vals_text)
self.assertIsNotNone(kv_dict)
# Verify there is a thread and that it matches the expected thread
# id.
kv_thread = kv_dict.get("thread")
self.assertIsNotNone(kv_thread)
kv_thread_id = int(kv_thread, 16)
self.assertEqual(kv_thread_id, thread)
# Grab the stop id reported.
stop_result_text = context.get("stop_result")
self.assertIsNotNone(stop_result_text)
stop_replies[kv_thread_id] = int(stop_result_text, 16)
# Hang on to the key-val dictionary for the thread.
thread_dicts[kv_thread_id] = kv_dict
return (stop_replies, thread_dicts)
def qThreadStopInfo_works_for_multiple_threads(self, thread_count):
(stop_replies, _) = self.gather_stop_replies_via_qThreadStopInfo(thread_count)
self.assertEqual(len(stop_replies), thread_count)
@debugserver_test
def test_qThreadStopInfo_works_for_multiple_threads_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.qThreadStopInfo_works_for_multiple_threads(self.THREAD_COUNT)
@llgs_test
def test_qThreadStopInfo_works_for_multiple_threads_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.qThreadStopInfo_works_for_multiple_threads(self.THREAD_COUNT)
def qThreadStopInfo_only_reports_one_thread_stop_reason_during_interrupt(
self, thread_count):
(stop_replies, _) = self.gather_stop_replies_via_qThreadStopInfo(thread_count)
self.assertIsNotNone(stop_replies)
no_stop_reason_count = sum(
1 for stop_reason in list(
stop_replies.values()) if stop_reason == 0)
with_stop_reason_count = sum(
1 for stop_reason in list(
stop_replies.values()) if stop_reason != 0)
# All but one thread should report no stop reason.
self.assertEqual(no_stop_reason_count, thread_count - 1)
# Only one thread should should indicate a stop reason.
self.assertEqual(with_stop_reason_count, 1)
@debugserver_test
def test_qThreadStopInfo_only_reports_one_thread_stop_reason_during_interrupt_debugserver(
self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.qThreadStopInfo_only_reports_one_thread_stop_reason_during_interrupt(
self.THREAD_COUNT)
@llgs_test
def test_qThreadStopInfo_only_reports_one_thread_stop_reason_during_interrupt_llgs(
self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.qThreadStopInfo_only_reports_one_thread_stop_reason_during_interrupt(
self.THREAD_COUNT)
def qThreadStopInfo_has_valid_thread_names(
self, thread_count, expected_thread_name):
(_, thread_dicts) = self.gather_stop_replies_via_qThreadStopInfo(thread_count)
self.assertIsNotNone(thread_dicts)
for thread_dict in list(thread_dicts.values()):
name = thread_dict.get("name")
self.assertIsNotNone(name)
self.assertEqual(name, expected_thread_name)
@unittest2.skip("MacOSX doesn't have a default thread name")
@debugserver_test
def test_qThreadStopInfo_has_valid_thread_names_debugserver(self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.qThreadStopInfo_has_valid_thread_names(self.THREAD_COUNT, "a.out")
# test requires OS with set, equal thread names by default.
@skipUnlessPlatform(["linux"])
@llgs_test
def test_qThreadStopInfo_has_valid_thread_names_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.qThreadStopInfo_has_valid_thread_names(self.THREAD_COUNT, "a.out")

View File

@ -1,159 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemote_vCont(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def vCont_supports_mode(self, mode, inferior_args=None):
# Setup the stub and set the gdb remote command stream.
procs = self.prep_debug_monitor_and_inferior(
inferior_args=inferior_args)
self.add_vCont_query_packets()
# Run the gdb remote command stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Pull out supported modes.
supported_vCont_modes = self.parse_vCont_query_response(context)
self.assertIsNotNone(supported_vCont_modes)
# Verify we support the given mode.
self.assertTrue(mode in supported_vCont_modes)
def vCont_supports_c(self):
self.vCont_supports_mode("c")
def vCont_supports_C(self):
self.vCont_supports_mode("C")
def vCont_supports_s(self):
self.vCont_supports_mode("s")
def vCont_supports_S(self):
self.vCont_supports_mode("S")
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@debugserver_test
def test_vCont_supports_c_debugserver(self):
self.init_debugserver_test()
self.build()
self.vCont_supports_c()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@llgs_test
def test_vCont_supports_c_llgs(self):
self.init_llgs_test()
self.build()
self.vCont_supports_c()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@debugserver_test
def test_vCont_supports_C_debugserver(self):
self.init_debugserver_test()
self.build()
self.vCont_supports_C()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@llgs_test
def test_vCont_supports_C_llgs(self):
self.init_llgs_test()
self.build()
self.vCont_supports_C()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@debugserver_test
def test_vCont_supports_s_debugserver(self):
self.init_debugserver_test()
self.build()
self.vCont_supports_s()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@llgs_test
def test_vCont_supports_s_llgs(self):
self.init_llgs_test()
self.build()
self.vCont_supports_s()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@debugserver_test
def test_vCont_supports_S_debugserver(self):
self.init_debugserver_test()
self.build()
self.vCont_supports_S()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@llgs_test
def test_vCont_supports_S_llgs(self):
self.init_llgs_test()
self.build()
self.vCont_supports_S()
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@debugserver_test
def test_single_step_only_steps_one_instruction_with_Hc_vCont_s_debugserver(
self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.single_step_only_steps_one_instruction(
use_Hc_packet=True, step_instruction="vCont;s")
@llgs_test
@expectedFailureAndroid(
bugnumber="llvm.org/pr24739",
archs=[
"arm",
"aarch64"])
@expectedFailureAll(
oslist=["linux"],
archs=[
"arm",
"aarch64"],
bugnumber="llvm.org/pr24739")
@skipIf(triple='^mips')
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
def test_single_step_only_steps_one_instruction_with_Hc_vCont_s_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.single_step_only_steps_one_instruction(
use_Hc_packet=True, step_instruction="vCont;s")
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
@debugserver_test
def test_single_step_only_steps_one_instruction_with_vCont_s_thread_debugserver(
self):
self.init_debugserver_test()
self.build()
self.set_inferior_startup_launch()
self.single_step_only_steps_one_instruction(
use_Hc_packet=False, step_instruction="vCont;s:{thread}")
@llgs_test
@expectedFailureAndroid(
bugnumber="llvm.org/pr24739",
archs=[
"arm",
"aarch64"])
@expectedFailureAll(
oslist=["linux"],
archs=[
"arm",
"aarch64"],
bugnumber="llvm.org/pr24739")
@skipIf(triple='^mips')
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://27005337")
def test_single_step_only_steps_one_instruction_with_vCont_s_thread_llgs(
self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.single_step_only_steps_one_instruction(
use_Hc_packet=False, step_instruction="vCont;s:{thread}")

View File

@ -1,98 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
import re
import select
import socket
import time
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestStubReverseConnect(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
_DEFAULT_TIMEOUT = 20
def setUp(self):
# Set up the test.
gdbremote_testcase.GdbRemoteTestCaseBase.setUp(self)
# Create a listener on a local port.
self.listener_socket = self.create_listener_socket()
self.assertIsNotNone(self.listener_socket)
self.listener_port = self.listener_socket.getsockname()[1]
def create_listener_socket(self, timeout_seconds=_DEFAULT_TIMEOUT):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.assertIsNotNone(sock)
sock.settimeout(timeout_seconds)
sock.bind(("127.0.0.1", 0))
sock.listen(1)
def tear_down_listener():
try:
sock.shutdown(socket.SHUT_RDWR)
except:
# ignore
None
self.addTearDownHook(tear_down_listener)
return sock
def reverse_connect_works(self):
# Indicate stub startup should do a reverse connect.
appended_stub_args = ["--reverse-connect"]
if self.debug_monitor_extra_args:
self.debug_monitor_extra_args += appended_stub_args
else:
self.debug_monitor_extra_args = appended_stub_args
self.stub_hostname = "127.0.0.1"
self.port = self.listener_port
triple = self.dbg.GetSelectedPlatform().GetTriple()
if re.match(".*-.*-.*-android", triple):
self.forward_adb_port(
self.port,
self.port,
"reverse",
self.stub_device)
# Start the stub.
server = self.launch_debug_monitor(logfile=sys.stdout)
self.assertIsNotNone(server)
self.assertTrue(
lldbgdbserverutils.process_is_running(
server.pid, True))
# Listen for the stub's connection to us.
(stub_socket, address) = self.listener_socket.accept()
self.assertIsNotNone(stub_socket)
self.assertIsNotNone(address)
print("connected to stub {} on {}".format(
address, stub_socket.getsockname()))
# Verify we can do the handshake. If that works, we'll call it good.
self.do_handshake(stub_socket, timeout_seconds=self._DEFAULT_TIMEOUT)
# Clean up.
stub_socket.shutdown(socket.SHUT_RDWR)
@debugserver_test
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def test_reverse_connect_works_debugserver(self):
self.init_debugserver_test(use_named_pipe=False)
self.set_inferior_startup_launch()
self.reverse_connect_works()
@llgs_test
@skipIfRemote # reverse connect is not a supported use case for now
def test_reverse_connect_works_llgs(self):
self.init_llgs_test(use_named_pipe=False)
self.set_inferior_startup_launch()
self.reverse_connect_works()

View File

@ -1,86 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
import os
import select
import tempfile
import time
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestStubSetSIDTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def get_stub_sid(self, extra_stub_args=None):
# Launch debugserver
if extra_stub_args:
self.debug_monitor_extra_args += extra_stub_args
server = self.launch_debug_monitor()
self.assertIsNotNone(server)
self.assertTrue(
lldbgdbserverutils.process_is_running(
server.pid, True))
# Get the process id for the stub.
return os.getsid(server.pid)
def sid_is_same_without_setsid(self):
stub_sid = self.get_stub_sid()
self.assertEqual(stub_sid, os.getsid(0))
def sid_is_different_with_setsid(self):
stub_sid = self.get_stub_sid(["--setsid"])
self.assertNotEqual(stub_sid, os.getsid(0))
def sid_is_different_with_S(self):
stub_sid = self.get_stub_sid(["-S"])
self.assertNotEqual(stub_sid, os.getsid(0))
@debugserver_test
@skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target
def test_sid_is_same_without_setsid_debugserver(self):
self.init_debugserver_test()
self.set_inferior_startup_launch()
self.sid_is_same_without_setsid()
@llgs_test
@skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target
@expectedFailureAll(oslist=['freebsd'])
def test_sid_is_same_without_setsid_llgs(self):
self.init_llgs_test()
self.set_inferior_startup_launch()
self.sid_is_same_without_setsid()
@debugserver_test
@skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target
def test_sid_is_different_with_setsid_debugserver(self):
self.init_debugserver_test()
self.set_inferior_startup_launch()
self.sid_is_different_with_setsid()
@llgs_test
@skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target
def test_sid_is_different_with_setsid_llgs(self):
self.init_llgs_test()
self.set_inferior_startup_launch()
self.sid_is_different_with_setsid()
@debugserver_test
@skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target
def test_sid_is_different_with_S_debugserver(self):
self.init_debugserver_test()
self.set_inferior_startup_launch()
self.sid_is_different_with_S()
@llgs_test
@skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target
def test_sid_is_different_with_S_llgs(self):
self.init_llgs_test()
self.set_inferior_startup_launch()
self.sid_is_different_with_S()

View File

@ -1,8 +0,0 @@
LEVEL = ../../../make
CFLAGS_EXTRAS += -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -std=c++11
# LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
MAKE_DSYM :=NO
include $(LEVEL)/Makefile.rules

View File

@ -1,46 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import signal
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteAbort(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def inferior_abort_received(self):
procs = self.prep_debug_monitor_and_inferior(inferior_args=["abort"])
self.assertIsNotNone(procs)
self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2}).*#[0-9a-fA-F]{2}$",
"capture": {1: "hex_exit_code"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
hex_exit_code = context.get("hex_exit_code")
self.assertIsNotNone(hex_exit_code)
self.assertEqual(int(hex_exit_code, 16),
lldbutil.get_signal_number('SIGABRT'))
@debugserver_test
def test_inferior_abort_received_debugserver(self):
self.init_debugserver_test()
self.build()
self.inferior_abort_received()
@llgs_test
# std::abort() on <= API 16 raises SIGSEGV - b.android.com/179836
@expectedFailureAndroid(api_levels=list(range(16 + 1)))
def test_inferior_abort_received_llgs(self):
self.init_llgs_test()
self.build()
self.inferior_abort_received()

View File

@ -1,46 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import signal
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteSegFault(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
GDB_REMOTE_STOP_CODE_BAD_ACCESS = 0x91
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
def inferior_seg_fault_received(self, expected_signo):
procs = self.prep_debug_monitor_and_inferior(
inferior_args=["segfault"])
self.assertIsNotNone(procs)
self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2}).*#[0-9a-fA-F]{2}$",
"capture": {1: "hex_exit_code"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
hex_exit_code = context.get("hex_exit_code")
self.assertIsNotNone(hex_exit_code)
self.assertEqual(int(hex_exit_code, 16), expected_signo)
@debugserver_test
def test_inferior_seg_fault_received_debugserver(self):
self.init_debugserver_test()
self.build()
self.inferior_seg_fault_received(self.GDB_REMOTE_STOP_CODE_BAD_ACCESS)
@llgs_test
def test_inferior_seg_fault_received_llgs(self):
self.init_llgs_test()
self.build()
self.inferior_seg_fault_received(lldbutil.get_signal_number('SIGSEGV'))

View File

@ -1,31 +0,0 @@
#include <cstdlib>
#include <cstring>
#include <iostream>
namespace {
const char *const SEGFAULT_COMMAND = "segfault";
const char *const ABORT_COMMAND = "abort";
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cout << "expected at least one command provided on the command line"
<< std::endl;
}
// Process command line args.
for (int i = 1; i < argc; ++i) {
const char *const command = argv[i];
if (std::strstr(command, SEGFAULT_COMMAND)) {
// Perform a null pointer access.
int *const null_int_ptr = nullptr;
*null_int_ptr = 0xDEAD;
} else if (std::strstr(command, ABORT_COMMAND)) {
std::abort();
} else {
std::cout << "Unsupported command: " << command << std::endl;
}
}
return 0;
}

View File

@ -1,945 +0,0 @@
"""Module for supporting unit testing of the lldb-server debug monitor exe.
"""
from __future__ import division, print_function
import os
import os.path
import platform
import re
import six
import socket_packet_pump
import subprocess
import time
from lldbsuite.test.lldbtest import *
from six.moves import queue
def _get_debug_monitor_from_lldb(lldb_exe, debug_monitor_basename):
"""Return the debug monitor exe path given the lldb exe path.
This method attempts to construct a valid debug monitor exe name
from a given lldb exe name. It will return None if the synthesized
debug monitor name is not found to exist.
The debug monitor exe path is synthesized by taking the directory
of the lldb exe, and replacing the portion of the base name that
matches "lldb" (case insensitive) and replacing with the value of
debug_monitor_basename.
Args:
lldb_exe: the path to an lldb executable.
debug_monitor_basename: the base name portion of the debug monitor
that will replace 'lldb'.
Returns:
A path to the debug monitor exe if it is found to exist; otherwise,
returns None.
"""
if not lldb_exe:
return None
exe_dir = os.path.dirname(lldb_exe)
exe_base = os.path.basename(lldb_exe)
# we'll rebuild the filename by replacing lldb with
# the debug monitor basename, keeping any prefix or suffix in place.
regex = re.compile(r"lldb", re.IGNORECASE)
new_base = regex.sub(debug_monitor_basename, exe_base)
debug_monitor_exe = os.path.join(exe_dir, new_base)
if os.path.exists(debug_monitor_exe):
return debug_monitor_exe
new_base = regex.sub(
'LLDB.framework/Versions/A/Resources/' +
debug_monitor_basename,
exe_base)
debug_monitor_exe = os.path.join(exe_dir, new_base)
if os.path.exists(debug_monitor_exe):
return debug_monitor_exe
return None
def get_lldb_server_exe():
"""Return the lldb-server exe path.
Returns:
A path to the lldb-server exe if it is found to exist; otherwise,
returns None.
"""
if "LLDB_DEBUGSERVER_PATH" in os.environ:
return os.environ["LLDB_DEBUGSERVER_PATH"]
return _get_debug_monitor_from_lldb(
lldbtest_config.lldbExec, "lldb-server")
def get_debugserver_exe():
"""Return the debugserver exe path.
Returns:
A path to the debugserver exe if it is found to exist; otherwise,
returns None.
"""
if "LLDB_DEBUGSERVER_PATH" in os.environ:
return os.environ["LLDB_DEBUGSERVER_PATH"]
return _get_debug_monitor_from_lldb(
lldbtest_config.lldbExec, "debugserver")
_LOG_LINE_REGEX = re.compile(r'^(lldb-server|debugserver)\s+<\s*(\d+)>' +
'\s+(read|send)\s+packet:\s+(.+)$')
def _is_packet_lldb_gdbserver_input(packet_type, llgs_input_is_read):
"""Return whether a given packet is input for lldb-gdbserver.
Args:
packet_type: a string indicating 'send' or 'receive', from a
gdbremote packet protocol log.
llgs_input_is_read: true if lldb-gdbserver input (content sent to
lldb-gdbserver) is listed as 'read' or 'send' in the packet
log entry.
Returns:
True if the packet should be considered input for lldb-gdbserver; False
otherwise.
"""
if packet_type == 'read':
# when llgs is the read side, then a read packet is meant for
# input to llgs (when captured from the llgs/debugserver exe).
return llgs_input_is_read
elif packet_type == 'send':
# when llgs is the send side, then a send packet is meant to
# be input to llgs (when captured from the lldb exe).
return not llgs_input_is_read
else:
# don't understand what type of packet this is
raise "Unknown packet type: {}".format(packet_type)
def handle_O_packet(context, packet_contents, logger):
"""Handle O packets."""
if (not packet_contents) or (len(packet_contents) < 1):
return False
elif packet_contents[0] != "O":
return False
elif packet_contents == "OK":
return False
new_text = gdbremote_hex_decode_string(packet_contents[1:])
context["O_content"] += new_text
context["O_count"] += 1
if logger:
logger.debug(
"text: new \"{}\", cumulative: \"{}\"".format(
new_text, context["O_content"]))
return True
_STRIP_CHECKSUM_REGEX = re.compile(r'#[0-9a-fA-F]{2}$')
_STRIP_COMMAND_PREFIX_REGEX = re.compile(r"^\$")
_STRIP_COMMAND_PREFIX_M_REGEX = re.compile(r"^\$m")
def assert_packets_equal(asserter, actual_packet, expected_packet):
# strip off the checksum digits of the packet. When we're in
# no-ack mode, the # checksum is ignored, and should not be cause
# for a mismatched packet.
actual_stripped = _STRIP_CHECKSUM_REGEX.sub('', actual_packet)
expected_stripped = _STRIP_CHECKSUM_REGEX.sub('', expected_packet)
asserter.assertEqual(actual_stripped, expected_stripped)
def expect_lldb_gdbserver_replay(
asserter,
sock,
test_sequence,
pump_queues,
timeout_seconds,
logger=None):
"""Replay socket communication with lldb-gdbserver and verify responses.
Args:
asserter: the object providing assertEqual(first, second, msg=None), e.g. TestCase instance.
sock: the TCP socket connected to the lldb-gdbserver exe.
test_sequence: a GdbRemoteTestSequence instance that describes
the messages sent to the gdb remote and the responses
expected from it.
timeout_seconds: any response taking more than this number of
seconds will cause an exception to be raised.
logger: a Python logger instance.
Returns:
The context dictionary from running the given gdbremote
protocol sequence. This will contain any of the capture
elements specified to any GdbRemoteEntry instances in
test_sequence.
The context will also contain an entry, context["O_content"]
which contains the text from the inferior received via $O
packets. $O packets should not attempt to be matched
directly since they are not entirely deterministic as to
how many arrive and how much text is in each one.
context["O_count"] will contain an integer of the number of
O packets received.
"""
# Ensure we have some work to do.
if len(test_sequence.entries) < 1:
return {}
context = {"O_count": 0, "O_content": ""}
with socket_packet_pump.SocketPacketPump(sock, pump_queues, logger) as pump:
# Grab the first sequence entry.
sequence_entry = test_sequence.entries.pop(0)
# While we have an active sequence entry, send messages
# destined for the stub and collect/match/process responses
# expected from the stub.
while sequence_entry:
if sequence_entry.is_send_to_remote():
# This is an entry to send to the remote debug monitor.
send_packet = sequence_entry.get_send_packet()
if logger:
if len(send_packet) == 1 and send_packet[0] == chr(3):
packet_desc = "^C"
else:
packet_desc = send_packet
logger.info(
"sending packet to remote: {}".format(packet_desc))
sock.sendall(send_packet.encode())
else:
# This is an entry expecting to receive content from the remote
# debug monitor.
# We'll pull from (and wait on) the queue appropriate for the type of matcher.
# We keep separate queues for process output (coming from non-deterministic
# $O packet division) and for all other packets.
if sequence_entry.is_output_matcher():
try:
# Grab next entry from the output queue.
content = pump_queues.output_queue().get(True, timeout_seconds)
except queue.Empty:
if logger:
logger.warning(
"timeout waiting for stub output (accumulated output:{})".format(
pump.get_accumulated_output()))
raise Exception(
"timed out while waiting for output match (accumulated output: {})".format(
pump.get_accumulated_output()))
else:
try:
content = pump_queues.packet_queue().get(True, timeout_seconds)
except queue.Empty:
if logger:
logger.warning(
"timeout waiting for packet match (receive buffer: {})".format(
pump.get_receive_buffer()))
raise Exception(
"timed out while waiting for packet match (receive buffer: {})".format(
pump.get_receive_buffer()))
# Give the sequence entry the opportunity to match the content.
# Output matchers might match or pass after more output accumulates.
# Other packet types generally must match.
asserter.assertIsNotNone(content)
context = sequence_entry.assert_match(
asserter, content, context=context)
# Move on to next sequence entry as needed. Some sequence entries support executing multiple
# times in different states (for looping over query/response
# packets).
if sequence_entry.is_consumed():
if len(test_sequence.entries) > 0:
sequence_entry = test_sequence.entries.pop(0)
else:
sequence_entry = None
# Fill in the O_content entries.
context["O_count"] = 1
context["O_content"] = pump.get_accumulated_output()
return context
def gdbremote_hex_encode_string(str):
output = ''
for c in str:
output += '{0:02x}'.format(ord(c))
return output
def gdbremote_hex_decode_string(str):
return str.decode("hex")
def gdbremote_packet_encode_string(str):
checksum = 0
for c in str:
checksum += ord(c)
return '$' + str + '#{0:02x}'.format(checksum % 256)
def build_gdbremote_A_packet(args_list):
"""Given a list of args, create a properly-formed $A packet containing each arg.
"""
payload = "A"
# build the arg content
arg_index = 0
for arg in args_list:
# Comma-separate the args.
if arg_index > 0:
payload += ','
# Hex-encode the arg.
hex_arg = gdbremote_hex_encode_string(arg)
# Build the A entry.
payload += "{},{},{}".format(len(hex_arg), arg_index, hex_arg)
# Next arg index, please.
arg_index += 1
# return the packetized payload
return gdbremote_packet_encode_string(payload)
def parse_reg_info_response(response_packet):
if not response_packet:
raise Exception("response_packet cannot be None")
# Strip off prefix $ and suffix #xx if present.
response_packet = _STRIP_COMMAND_PREFIX_REGEX.sub("", response_packet)
response_packet = _STRIP_CHECKSUM_REGEX.sub("", response_packet)
# Build keyval pairs
values = {}
for kv in response_packet.split(";"):
if len(kv) < 1:
continue
(key, val) = kv.split(':')
values[key] = val
return values
def parse_threadinfo_response(response_packet):
if not response_packet:
raise Exception("response_packet cannot be None")
# Strip off prefix $ and suffix #xx if present.
response_packet = _STRIP_COMMAND_PREFIX_M_REGEX.sub("", response_packet)
response_packet = _STRIP_CHECKSUM_REGEX.sub("", response_packet)
# Return list of thread ids
return [int(thread_id_hex, 16) for thread_id_hex in response_packet.split(
",") if len(thread_id_hex) > 0]
def unpack_endian_binary_string(endian, value_string):
"""Unpack a gdb-remote binary (post-unescaped, i.e. not escaped) response to an unsigned int given endianness of the inferior."""
if not endian:
raise Exception("endian cannot be None")
if not value_string or len(value_string) < 1:
raise Exception("value_string cannot be None or empty")
if endian == 'little':
value = 0
i = 0
while len(value_string) > 0:
value += (ord(value_string[0]) << i)
value_string = value_string[1:]
i += 8
return value
elif endian == 'big':
value = 0
while len(value_string) > 0:
value = (value << 8) + ord(value_string[0])
value_string = value_string[1:]
return value
else:
# pdp is valid but need to add parse code once needed.
raise Exception("unsupported endian:{}".format(endian))
def unpack_register_hex_unsigned(endian, value_string):
"""Unpack a gdb-remote $p-style response to an unsigned int given endianness of inferior."""
if not endian:
raise Exception("endian cannot be None")
if not value_string or len(value_string) < 1:
raise Exception("value_string cannot be None or empty")
if endian == 'little':
value = 0
i = 0
while len(value_string) > 0:
value += (int(value_string[0:2], 16) << i)
value_string = value_string[2:]
i += 8
return value
elif endian == 'big':
return int(value_string, 16)
else:
# pdp is valid but need to add parse code once needed.
raise Exception("unsupported endian:{}".format(endian))
def pack_register_hex(endian, value, byte_size=None):
"""Unpack a gdb-remote $p-style response to an unsigned int given endianness of inferior."""
if not endian:
raise Exception("endian cannot be None")
if endian == 'little':
# Create the litt-endian return value.
retval = ""
while value != 0:
retval = retval + "{:02x}".format(value & 0xff)
value = value >> 8
if byte_size:
# Add zero-fill to the right/end (MSB side) of the value.
retval += "00" * (byte_size - len(retval) // 2)
return retval
elif endian == 'big':
retval = ""
while value != 0:
retval = "{:02x}".format(value & 0xff) + retval
value = value >> 8
if byte_size:
# Add zero-fill to the left/front (MSB side) of the value.
retval = ("00" * (byte_size - len(retval) // 2)) + retval
return retval
else:
# pdp is valid but need to add parse code once needed.
raise Exception("unsupported endian:{}".format(endian))
class GdbRemoteEntryBase(object):
def is_output_matcher(self):
return False
class GdbRemoteEntry(GdbRemoteEntryBase):
def __init__(
self,
is_send_to_remote=True,
exact_payload=None,
regex=None,
capture=None,
expect_captures=None):
"""Create an entry representing one piece of the I/O to/from a gdb remote debug monitor.
Args:
is_send_to_remote: True if this entry is a message to be
sent to the gdbremote debug monitor; False if this
entry represents text to be matched against the reply
from the gdbremote debug monitor.
exact_payload: if not None, then this packet is an exact
send (when sending to the remote) or an exact match of
the response from the gdbremote. The checksums are
ignored on exact match requests since negotiation of
no-ack makes the checksum content essentially
undefined.
regex: currently only valid for receives from gdbremote.
When specified (and only if exact_payload is None),
indicates the gdbremote response must match the given
regex. Match groups in the regex can be used for two
different purposes: saving the match (see capture
arg), or validating that a match group matches a
previously established value (see expect_captures). It
is perfectly valid to have just a regex arg and to
specify neither capture or expect_captures args. This
arg only makes sense if exact_payload is not
specified.
capture: if specified, is a dictionary of regex match
group indices (should start with 1) to variable names
that will store the capture group indicated by the
index. For example, {1:"thread_id"} will store capture
group 1's content in the context dictionary where
"thread_id" is the key and the match group value is
the value. The value stored off can be used later in a
expect_captures expression. This arg only makes sense
when regex is specified.
expect_captures: if specified, is a dictionary of regex
match group indices (should start with 1) to variable
names, where the match group should match the value
existing in the context at the given variable name.
For example, {2:"thread_id"} indicates that the second
match group must match the value stored under the
context's previously stored "thread_id" key. This arg
only makes sense when regex is specified.
"""
self._is_send_to_remote = is_send_to_remote
self.exact_payload = exact_payload
self.regex = regex
self.capture = capture
self.expect_captures = expect_captures
def is_send_to_remote(self):
return self._is_send_to_remote
def is_consumed(self):
# For now, all packets are consumed after first use.
return True
def get_send_packet(self):
if not self.is_send_to_remote():
raise Exception(
"get_send_packet() called on GdbRemoteEntry that is not a send-to-remote packet")
if not self.exact_payload:
raise Exception(
"get_send_packet() called on GdbRemoteEntry but it doesn't have an exact payload")
return self.exact_payload
def _assert_exact_payload_match(self, asserter, actual_packet):
assert_packets_equal(asserter, actual_packet, self.exact_payload)
return None
def _assert_regex_match(self, asserter, actual_packet, context):
# Ensure the actual packet matches from the start of the actual packet.
match = self.regex.match(actual_packet)
if not match:
asserter.fail(
"regex '{}' failed to match against content '{}'".format(
self.regex.pattern, actual_packet))
if self.capture:
# Handle captures.
for group_index, var_name in list(self.capture.items()):
capture_text = match.group(group_index)
# It is okay for capture text to be None - which it will be if it is a group that can match nothing.
# The user must be okay with it since the regex itself matched
# above.
context[var_name] = capture_text
if self.expect_captures:
# Handle comparing matched groups to context dictionary entries.
for group_index, var_name in list(self.expect_captures.items()):
capture_text = match.group(group_index)
if not capture_text:
raise Exception(
"No content to expect for group index {}".format(group_index))
asserter.assertEqual(capture_text, context[var_name])
return context
def assert_match(self, asserter, actual_packet, context=None):
# This only makes sense for matching lines coming from the
# remote debug monitor.
if self.is_send_to_remote():
raise Exception(
"Attempted to match a packet being sent to the remote debug monitor, doesn't make sense.")
# Create a new context if needed.
if not context:
context = {}
# If this is an exact payload, ensure they match exactly,
# ignoring the packet checksum which is optional for no-ack
# mode.
if self.exact_payload:
self._assert_exact_payload_match(asserter, actual_packet)
return context
elif self.regex:
return self._assert_regex_match(asserter, actual_packet, context)
else:
raise Exception(
"Don't know how to match a remote-sent packet when exact_payload isn't specified.")
class MultiResponseGdbRemoteEntry(GdbRemoteEntryBase):
"""Represents a query/response style packet.
Assumes the first item is sent to the gdb remote.
An end sequence regex indicates the end of the query/response
packet sequence. All responses up through (but not including) the
end response are stored in a context variable.
Settings accepted from params:
next_query or query: required. The typical query packet without the $ prefix or #xx suffix.
If there is a special first packet to start the iteration query, see the
first_query key.
first_query: optional. If the first query requires a special query command, specify
it with this key. Do not specify the $ prefix or #xx suffix.
append_iteration_suffix: defaults to False. Specify True if the 0-based iteration
index should be appended as a suffix to the command. e.g. qRegisterInfo with
this key set true will generate query packets of qRegisterInfo0, qRegisterInfo1,
etc.
end_regex: required. Specifies a compiled regex object that will match the full text
of any response that signals an end to the iteration. It must include the
initial $ and ending #xx and must match the whole packet.
save_key: required. Specifies the key within the context where an array will be stored.
Each packet received from the gdb remote that does not match the end_regex will get
appended to the array stored within the context at that key.
runaway_response_count: optional. Defaults to 10000. If this many responses are retrieved,
assume there is something wrong with either the response collection or the ending
detection regex and throw an exception.
"""
def __init__(self, params):
self._next_query = params.get("next_query", params.get("query"))
if not self._next_query:
raise "either next_query or query key must be specified for MultiResponseGdbRemoteEntry"
self._first_query = params.get("first_query", self._next_query)
self._append_iteration_suffix = params.get(
"append_iteration_suffix", False)
self._iteration = 0
self._end_regex = params["end_regex"]
self._save_key = params["save_key"]
self._runaway_response_count = params.get(
"runaway_response_count", 10000)
self._is_send_to_remote = True
self._end_matched = False
def is_send_to_remote(self):
return self._is_send_to_remote
def get_send_packet(self):
if not self.is_send_to_remote():
raise Exception(
"get_send_packet() called on MultiResponseGdbRemoteEntry that is not in the send state")
if self._end_matched:
raise Exception(
"get_send_packet() called on MultiResponseGdbRemoteEntry but end of query/response sequence has already been seen.")
# Choose the first or next query for the base payload.
if self._iteration == 0 and self._first_query:
payload = self._first_query
else:
payload = self._next_query
# Append the suffix as needed.
if self._append_iteration_suffix:
payload += "%x" % self._iteration
# Keep track of the iteration.
self._iteration += 1
# Now that we've given the query packet, flip the mode to
# receive/match.
self._is_send_to_remote = False
# Return the result, converted to packet form.
return gdbremote_packet_encode_string(payload)
def is_consumed(self):
return self._end_matched
def assert_match(self, asserter, actual_packet, context=None):
# This only makes sense for matching lines coming from the remote debug
# monitor.
if self.is_send_to_remote():
raise Exception(
"assert_match() called on MultiResponseGdbRemoteEntry but state is set to send a query packet.")
if self._end_matched:
raise Exception(
"assert_match() called on MultiResponseGdbRemoteEntry but end of query/response sequence has already been seen.")
# Set up a context as needed.
if not context:
context = {}
# Check if the packet matches the end condition.
match = self._end_regex.match(actual_packet)
if match:
# We're done iterating.
self._end_matched = True
return context
# Not done iterating - save the packet.
context[self._save_key] = context.get(self._save_key, [])
context[self._save_key].append(actual_packet)
# Check for a runaway response cycle.
if len(context[self._save_key]) >= self._runaway_response_count:
raise Exception(
"runaway query/response cycle detected: %d responses captured so far. Last response: %s" %
(len(
context[
self._save_key]), context[
self._save_key][
-1]))
# Flip the mode to send for generating the query.
self._is_send_to_remote = True
return context
class MatchRemoteOutputEntry(GdbRemoteEntryBase):
"""Waits for output from the debug monitor to match a regex or time out.
This entry type tries to match each time new gdb remote output is accumulated
using a provided regex. If the output does not match the regex within the
given timeframe, the command fails the playback session. If the regex does
match, any capture fields are recorded in the context.
Settings accepted from params:
regex: required. Specifies a compiled regex object that must either succeed
with re.match or re.search (see regex_mode below) within the given timeout
(see timeout_seconds below) or cause the playback to fail.
regex_mode: optional. Available values: "match" or "search". If "match", the entire
stub output as collected so far must match the regex. If search, then the regex
must match starting somewhere within the output text accumulated thus far.
Default: "match" (i.e. the regex must match the entirety of the accumulated output
buffer, so unexpected text will generally fail the match).
capture: optional. If specified, is a dictionary of regex match group indices (should start
with 1) to variable names that will store the capture group indicated by the
index. For example, {1:"thread_id"} will store capture group 1's content in the
context dictionary where "thread_id" is the key and the match group value is
the value. The value stored off can be used later in a expect_captures expression.
This arg only makes sense when regex is specified.
"""
def __init__(self, regex=None, regex_mode="match", capture=None):
self._regex = regex
self._regex_mode = regex_mode
self._capture = capture
self._matched = False
if not self._regex:
raise Exception("regex cannot be None")
if not self._regex_mode in ["match", "search"]:
raise Exception(
"unsupported regex mode \"{}\": must be \"match\" or \"search\"".format(
self._regex_mode))
def is_output_matcher(self):
return True
def is_send_to_remote(self):
# This is always a "wait for remote" command.
return False
def is_consumed(self):
return self._matched
def assert_match(self, asserter, accumulated_output, context):
# Validate args.
if not accumulated_output:
raise Exception("accumulated_output cannot be none")
if not context:
raise Exception("context cannot be none")
# Validate that we haven't already matched.
if self._matched:
raise Exception(
"invalid state - already matched, attempting to match again")
# If we don't have any content yet, we don't match.
if len(accumulated_output) < 1:
return context
# Check if we match
if self._regex_mode == "match":
match = self._regex.match(accumulated_output)
elif self._regex_mode == "search":
match = self._regex.search(accumulated_output)
else:
raise Exception(
"Unexpected regex mode: {}".format(
self._regex_mode))
# If we don't match, wait to try again after next $O content, or time
# out.
if not match:
# print("re pattern \"{}\" did not match against \"{}\"".format(self._regex.pattern, accumulated_output))
return context
# We do match.
self._matched = True
# print("re pattern \"{}\" matched against \"{}\"".format(self._regex.pattern, accumulated_output))
# Collect up any captures into the context.
if self._capture:
# Handle captures.
for group_index, var_name in list(self._capture.items()):
capture_text = match.group(group_index)
if not capture_text:
raise Exception(
"No content for group index {}".format(group_index))
context[var_name] = capture_text
return context
class GdbRemoteTestSequence(object):
_LOG_LINE_REGEX = re.compile(r'^.*(read|send)\s+packet:\s+(.+)$')
def __init__(self, logger):
self.entries = []
self.logger = logger
def add_log_lines(self, log_lines, remote_input_is_read):
for line in log_lines:
if isinstance(line, str):
# Handle log line import
# if self.logger:
# self.logger.debug("processing log line: {}".format(line))
match = self._LOG_LINE_REGEX.match(line)
if match:
playback_packet = match.group(2)
direction = match.group(1)
if _is_packet_lldb_gdbserver_input(
direction, remote_input_is_read):
# Handle as something to send to the remote debug monitor.
# if self.logger:
# self.logger.info("processed packet to send to remote: {}".format(playback_packet))
self.entries.append(
GdbRemoteEntry(
is_send_to_remote=True,
exact_payload=playback_packet))
else:
# Log line represents content to be expected from the remote debug monitor.
# if self.logger:
# self.logger.info("receiving packet from llgs, should match: {}".format(playback_packet))
self.entries.append(
GdbRemoteEntry(
is_send_to_remote=False,
exact_payload=playback_packet))
else:
raise Exception(
"failed to interpret log line: {}".format(line))
elif isinstance(line, dict):
entry_type = line.get("type", "regex_capture")
if entry_type == "regex_capture":
# Handle more explicit control over details via dictionary.
direction = line.get("direction", None)
regex = line.get("regex", None)
capture = line.get("capture", None)
expect_captures = line.get("expect_captures", None)
# Compile the regex.
if regex and (isinstance(regex, str)):
regex = re.compile(regex)
if _is_packet_lldb_gdbserver_input(
direction, remote_input_is_read):
# Handle as something to send to the remote debug monitor.
# if self.logger:
# self.logger.info("processed dict sequence to send to remote")
self.entries.append(
GdbRemoteEntry(
is_send_to_remote=True,
regex=regex,
capture=capture,
expect_captures=expect_captures))
else:
# Log line represents content to be expected from the remote debug monitor.
# if self.logger:
# self.logger.info("processed dict sequence to match receiving from remote")
self.entries.append(
GdbRemoteEntry(
is_send_to_remote=False,
regex=regex,
capture=capture,
expect_captures=expect_captures))
elif entry_type == "multi_response":
self.entries.append(MultiResponseGdbRemoteEntry(line))
elif entry_type == "output_match":
regex = line.get("regex", None)
# Compile the regex.
if regex and (isinstance(regex, str)):
regex = re.compile(regex, re.DOTALL)
regex_mode = line.get("regex_mode", "match")
capture = line.get("capture", None)
self.entries.append(
MatchRemoteOutputEntry(
regex=regex,
regex_mode=regex_mode,
capture=capture))
else:
raise Exception("unknown entry type \"%s\"" % entry_type)
def process_is_running(pid, unknown_value=True):
"""If possible, validate that the given pid represents a running process on the local system.
Args:
pid: an OS-specific representation of a process id. Should be an integral value.
unknown_value: value used when we cannot determine how to check running local
processes on the OS.
Returns:
If we can figure out how to check running process ids on the given OS:
return True if the process is running, or False otherwise.
If we don't know how to check running process ids on the given OS:
return the value provided by the unknown_value arg.
"""
if not isinstance(pid, six.integer_types):
raise Exception(
"pid must be an integral type (actual type: %s)" % str(
type(pid)))
process_ids = []
if lldb.remote_platform:
# Don't know how to get list of running process IDs on a remote
# platform
return unknown_value
elif platform.system() in ['Darwin', 'Linux', 'FreeBSD', 'NetBSD']:
# Build the list of running process ids
output = subprocess.check_output(
"ps ax | awk '{ print $1; }'", shell=True).decode("utf-8")
text_process_ids = output.split('\n')[1:]
# Convert text pids to ints
process_ids = [int(text_pid)
for text_pid in text_process_ids if text_pid != '']
# elif {your_platform_here}:
# fill in process_ids as a list of int type process IDs running on
# the local system.
else:
# Don't know how to get list of running process IDs on this
# OS, so return the "don't know" value.
return unknown_value
# Check if the pid is in the process_ids
return pid in process_ids
if __name__ == '__main__':
EXE_PATH = get_lldb_server_exe()
if EXE_PATH:
print("lldb-server path detected: {}".format(EXE_PATH))
else:
print("lldb-server could not be found")

View File

@ -1,370 +0,0 @@
//===-- main.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 <atomic>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <errno.h>
#include <inttypes.h>
#include <memory>
#include <mutex>
#if !defined(_WIN32)
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#endif
#include <setjmp.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <thread>
#include <time.h>
#include <vector>
#if defined(__APPLE__)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
int pthread_threadid_np(pthread_t, __uint64_t *);
#elif defined(__linux__)
#include <sys/syscall.h>
#elif defined(__NetBSD__)
#include <lwp.h>
#elif defined(_WIN32)
#include <windows.h>
#endif
static const char *const RETVAL_PREFIX = "retval:";
static const char *const SLEEP_PREFIX = "sleep:";
static const char *const STDERR_PREFIX = "stderr:";
static const char *const SET_MESSAGE_PREFIX = "set-message:";
static const char *const PRINT_MESSAGE_COMMAND = "print-message:";
static const char *const GET_DATA_ADDRESS_PREFIX = "get-data-address-hex:";
static const char *const GET_STACK_ADDRESS_COMMAND = "get-stack-address-hex:";
static const char *const GET_HEAP_ADDRESS_COMMAND = "get-heap-address-hex:";
static const char *const GET_CODE_ADDRESS_PREFIX = "get-code-address-hex:";
static const char *const CALL_FUNCTION_PREFIX = "call-function:";
static const char *const THREAD_PREFIX = "thread:";
static const char *const THREAD_COMMAND_NEW = "new";
static const char *const THREAD_COMMAND_PRINT_IDS = "print-ids";
static const char *const THREAD_COMMAND_SEGFAULT = "segfault";
static const char *const PRINT_PID_COMMAND = "print-pid";
static bool g_print_thread_ids = false;
static std::mutex g_print_mutex;
static bool g_threads_do_segfault = false;
static std::mutex g_jump_buffer_mutex;
static jmp_buf g_jump_buffer;
static bool g_is_segfaulting = false;
static char g_message[256];
static volatile char g_c1 = '0';
static volatile char g_c2 = '1';
static void print_pid() {
#if defined(_WIN32)
fprintf(stderr, "PID: %d\n", ::GetCurrentProcessId());
#else
fprintf(stderr, "PID: %d\n", getpid());
#endif
}
static void print_thread_id() {
// Put in the right magic here for your platform to spit out the thread id (tid)
// that debugserver/lldb-gdbserver would see as a TID. Otherwise, let the else
// clause print out the unsupported text so that the unit test knows to skip
// verifying thread ids.
#if defined(__APPLE__)
__uint64_t tid = 0;
pthread_threadid_np(pthread_self(), &tid);
printf("%" PRIx64, tid);
#elif defined(__linux__)
// This is a call to gettid() via syscall.
printf("%" PRIx64, static_cast<uint64_t>(syscall(__NR_gettid)));
#elif defined(__NetBSD__)
// Technically lwpid_t is 32-bit signed integer
printf("%" PRIx64, static_cast<uint64_t>(_lwp_self()));
#elif defined(_WIN32)
printf("%" PRIx64, static_cast<uint64_t>(::GetCurrentThreadId()));
#else
printf("{no-tid-support}");
#endif
}
static void signal_handler(int signo) {
#if defined(_WIN32)
// No signal support on Windows.
#else
const char *signal_name = nullptr;
switch (signo) {
case SIGUSR1:
signal_name = "SIGUSR1";
break;
case SIGSEGV:
signal_name = "SIGSEGV";
break;
default:
signal_name = nullptr;
}
// Print notice that we received the signal on a given thread.
{
std::lock_guard<std::mutex> lock(g_print_mutex);
if (signal_name)
printf("received %s on thread id: ", signal_name);
else
printf("received signo %d (%s) on thread id: ", signo, strsignal(signo));
print_thread_id();
printf("\n");
}
// Reset the signal handler if we're one of the expected signal handlers.
switch (signo) {
case SIGSEGV:
if (g_is_segfaulting) {
// Fix up the pointer we're writing to. This needs to happen if nothing
// intercepts the SIGSEGV (i.e. if somebody runs this from the command
// line).
longjmp(g_jump_buffer, 1);
}
break;
case SIGUSR1:
if (g_is_segfaulting) {
// Fix up the pointer we're writing to. This is used to test gdb remote
// signal delivery. A SIGSEGV will be raised when the thread is created,
// switched out for a SIGUSR1, and then this code still needs to fix the
// seg fault. (i.e. if somebody runs this from the command line).
longjmp(g_jump_buffer, 1);
}
break;
}
// Reset the signal handler.
sig_t sig_result = signal(signo, signal_handler);
if (sig_result == SIG_ERR) {
fprintf(stderr, "failed to set signal handler: errno=%d\n", errno);
exit(1);
}
#endif
}
static void swap_chars() {
g_c1 = '1';
g_c2 = '0';
g_c1 = '0';
g_c2 = '1';
}
static void hello() {
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("hello, world\n");
}
static void *thread_func(void *arg) {
static std::atomic<int> s_thread_index(1);
const int this_thread_index = s_thread_index++;
if (g_print_thread_ids) {
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("thread %d id: ", this_thread_index);
print_thread_id();
printf("\n");
}
if (g_threads_do_segfault) {
// Sleep for a number of seconds based on the thread index.
// TODO add ability to send commands to test exe so we can
// handle timing more precisely. This is clunky. All we're
// trying to do is add predictability as to the timing of
// signal generation by created threads.
int sleep_seconds = 2 * (this_thread_index - 1);
std::this_thread::sleep_for(std::chrono::seconds(sleep_seconds));
// Test creating a SEGV.
{
std::lock_guard<std::mutex> lock(g_jump_buffer_mutex);
g_is_segfaulting = true;
int *bad_p = nullptr;
if (setjmp(g_jump_buffer) == 0) {
// Force a seg fault signal on this thread.
*bad_p = 0;
} else {
// Tell the system we're no longer seg faulting.
// Used by the SIGUSR1 signal handler that we inject
// in place of the SIGSEGV so it only tries to
// recover from the SIGSEGV if this seg fault code
// was in play.
g_is_segfaulting = false;
}
}
{
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("thread ");
print_thread_id();
printf(": past SIGSEGV\n");
}
}
int sleep_seconds_remaining = 60;
std::this_thread::sleep_for(std::chrono::seconds(sleep_seconds_remaining));
return nullptr;
}
int main(int argc, char **argv) {
lldb_enable_attach();
std::vector<std::thread> threads;
std::unique_ptr<uint8_t[]> heap_array_up;
int return_value = 0;
#if !defined(_WIN32)
// Set the signal handler.
sig_t sig_result = signal(SIGALRM, signal_handler);
if (sig_result == SIG_ERR) {
fprintf(stderr, "failed to set SIGALRM signal handler: errno=%d\n", errno);
exit(1);
}
sig_result = signal(SIGUSR1, signal_handler);
if (sig_result == SIG_ERR) {
fprintf(stderr, "failed to set SIGUSR1 handler: errno=%d\n", errno);
exit(1);
}
sig_result = signal(SIGSEGV, signal_handler);
if (sig_result == SIG_ERR) {
fprintf(stderr, "failed to set SIGUSR1 handler: errno=%d\n", errno);
exit(1);
}
#endif
// Process command line args.
for (int i = 1; i < argc; ++i) {
if (std::strstr(argv[i], STDERR_PREFIX)) {
// Treat remainder as text to go to stderr.
fprintf(stderr, "%s\n", (argv[i] + strlen(STDERR_PREFIX)));
} else if (std::strstr(argv[i], RETVAL_PREFIX)) {
// Treat as the return value for the program.
return_value = std::atoi(argv[i] + strlen(RETVAL_PREFIX));
} else if (std::strstr(argv[i], SLEEP_PREFIX)) {
// Treat as the amount of time to have this process sleep (in seconds).
int sleep_seconds_remaining = std::atoi(argv[i] + strlen(SLEEP_PREFIX));
// Loop around, sleeping until all sleep time is used up. Note that
// signals will cause sleep to end early with the number of seconds
// remaining.
std::this_thread::sleep_for(
std::chrono::seconds(sleep_seconds_remaining));
} else if (std::strstr(argv[i], SET_MESSAGE_PREFIX)) {
// Copy the contents after "set-message:" to the g_message buffer.
// Used for reading inferior memory and verifying contents match
// expectations.
strncpy(g_message, argv[i] + strlen(SET_MESSAGE_PREFIX),
sizeof(g_message));
// Ensure we're null terminated.
g_message[sizeof(g_message) - 1] = '\0';
} else if (std::strstr(argv[i], PRINT_MESSAGE_COMMAND)) {
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("message: %s\n", g_message);
} else if (std::strstr(argv[i], GET_DATA_ADDRESS_PREFIX)) {
volatile void *data_p = nullptr;
if (std::strstr(argv[i] + strlen(GET_DATA_ADDRESS_PREFIX), "g_message"))
data_p = &g_message[0];
else if (std::strstr(argv[i] + strlen(GET_DATA_ADDRESS_PREFIX), "g_c1"))
data_p = &g_c1;
else if (std::strstr(argv[i] + strlen(GET_DATA_ADDRESS_PREFIX), "g_c2"))
data_p = &g_c2;
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("data address: %p\n", data_p);
} else if (std::strstr(argv[i], GET_HEAP_ADDRESS_COMMAND)) {
// Create a byte array if not already present.
if (!heap_array_up)
heap_array_up.reset(new uint8_t[32]);
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("heap address: %p\n", heap_array_up.get());
} else if (std::strstr(argv[i], GET_STACK_ADDRESS_COMMAND)) {
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("stack address: %p\n", &return_value);
} else if (std::strstr(argv[i], GET_CODE_ADDRESS_PREFIX)) {
void (*func_p)() = nullptr;
if (std::strstr(argv[i] + strlen(GET_CODE_ADDRESS_PREFIX), "hello"))
func_p = hello;
else if (std::strstr(argv[i] + strlen(GET_CODE_ADDRESS_PREFIX),
"swap_chars"))
func_p = swap_chars;
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("code address: %p\n", func_p);
} else if (std::strstr(argv[i], CALL_FUNCTION_PREFIX)) {
void (*func_p)() = nullptr;
// Defaut to providing the address of main.
if (std::strcmp(argv[i] + strlen(CALL_FUNCTION_PREFIX), "hello") == 0)
func_p = hello;
else if (std::strcmp(argv[i] + strlen(CALL_FUNCTION_PREFIX),
"swap_chars") == 0)
func_p = swap_chars;
else {
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("unknown function: %s\n",
argv[i] + strlen(CALL_FUNCTION_PREFIX));
}
if (func_p)
func_p();
} else if (std::strstr(argv[i], THREAD_PREFIX)) {
// Check if we're creating a new thread.
if (std::strstr(argv[i] + strlen(THREAD_PREFIX), THREAD_COMMAND_NEW)) {
threads.push_back(std::thread(thread_func, nullptr));
} else if (std::strstr(argv[i] + strlen(THREAD_PREFIX),
THREAD_COMMAND_PRINT_IDS)) {
// Turn on thread id announcing.
g_print_thread_ids = true;
// And announce us.
{
std::lock_guard<std::mutex> lock(g_print_mutex);
printf("thread 0 id: ");
print_thread_id();
printf("\n");
}
} else if (std::strstr(argv[i] + strlen(THREAD_PREFIX),
THREAD_COMMAND_SEGFAULT)) {
g_threads_do_segfault = true;
} else {
// At this point we don't do anything else with threads.
// Later use thread index and send command to thread.
}
} else if (std::strstr(argv[i], PRINT_PID_COMMAND)) {
print_pid();
} else {
// Treat the argument as text for stdout.
printf("%s\n", argv[i]);
}
}
// If we launched any threads, join them
for (std::vector<std::thread>::iterator it = threads.begin();
it != threads.end(); ++it)
it->join();
return return_value;
}

View File

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

View File

@ -1,96 +0,0 @@
from __future__ import print_function
import time
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@llgs_test
@no_debug_info_test
@skipIf(remote=False)
@expectedFailureAll(hostoslist=["windows"], triple='.*-android')
def test_platform_process_connect(self):
self.build()
self.init_llgs_test(False)
working_dir = lldb.remote_platform.GetWorkingDirectory()
src = lldb.SBFileSpec(self.getBuildArtifact("a.out"))
dest = lldb.SBFileSpec(os.path.join(working_dir, "a.out"))
err = lldb.remote_platform.Put(src, dest)
if err.Fail():
raise RuntimeError(
"Unable copy '%s' to '%s'.\n>>> %s" %
(f, wd, err.GetCString()))
m = re.search("^(.*)://([^:/]*)", configuration.lldb_platform_url)
protocol = m.group(1)
hostname = m.group(2)
unix_protocol = protocol.startswith("unix-")
if unix_protocol:
p = re.search("^(.*)-connect", protocol)
path = lldbutil.join_remote_paths(configuration.lldb_platform_working_dir,
self.getBuildDirBasename(), "platform-%d.sock" % int(time.time()))
listen_url = "%s://%s" % (p.group(1), path)
else:
listen_url = "*:0"
port_file = "%s/port" % working_dir
commandline_args = [
"platform",
"--listen",
listen_url,
"--socket-file",
port_file,
"--",
"%s/a.out" %
working_dir,
"foo"]
self.spawnSubprocess(
self.debug_monitor_exe,
commandline_args,
install_remote=False)
self.addTearDownHook(self.cleanupSubprocesses)
socket_id = lldbutil.wait_for_file_on_target(self, port_file)
new_debugger = lldb.SBDebugger.Create()
new_debugger.SetAsync(False)
def del_debugger(new_debugger=new_debugger):
del new_debugger
self.addTearDownHook(del_debugger)
new_platform = lldb.SBPlatform(lldb.remote_platform.GetName())
new_debugger.SetSelectedPlatform(new_platform)
new_interpreter = new_debugger.GetCommandInterpreter()
if unix_protocol:
connect_url = "%s://%s%s" % (protocol, hostname, socket_id)
else:
connect_url = "%s://%s:%s" % (protocol, hostname, socket_id)
command = "platform connect %s" % (connect_url)
result = lldb.SBCommandReturnObject()
new_interpreter.HandleCommand(command, result)
self.assertTrue(
result.Succeeded(),
"platform process connect failed: %s" %
result.GetOutput())
target = new_debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetThreadAtIndex(0)
breakpoint = target.BreakpointCreateByName("main")
process.Continue()
frame = thread.GetFrameAtIndex(0)
self.assertEqual(frame.GetFunction().GetName(), "main")
self.assertEqual(frame.FindVariable("argc").GetValueAsSigned(), 2)
process.Continue()

View File

@ -1,6 +0,0 @@
#include <cstdio>
int main(int argc, char **argv) {
printf("argc: %d\n", argc);
return argv[0][0];
}

View File

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

View File

@ -1,153 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
import textwrap
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
def _extract_register_value(reg_info, reg_bank, byte_order, bytes_per_entry=8):
reg_offset = int(reg_info["offset"])*2
reg_byte_size = int(2 * int(reg_info["bitsize"]) / 8)
# Create slice with the contents of the register.
reg_slice = reg_bank[reg_offset:reg_offset+reg_byte_size]
reg_value = []
# Wrap slice according to bytes_per_entry.
for entry in textwrap.wrap(reg_slice, 2 * bytes_per_entry):
# Invert the bytes order if target uses little-endian.
if byte_order == lldb.eByteOrderLittle:
entry = "".join(reversed([entry[i:i+2] for i in range(0,
len(entry),2)]))
reg_value.append("0x" + entry)
return reg_value
class TestGdbRemoteGPacket(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def run_test_g_packet(self):
self.build()
self.prep_debug_monitor_and_inferior()
self.test_sequence.add_log_lines(
["read packet: $g#67",
{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
"capture": {1: "register_bank"}}],
True)
self.connect_to_debug_monitor()
context = self.expect_gdbremote_sequence()
register_bank = context.get("register_bank")
self.assertTrue(register_bank[0] != 'E')
self.test_sequence.add_log_lines(
["read packet: $G" + register_bank + "#00",
{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
"capture": {1: "G_reply"}}],
True)
context = self.expect_gdbremote_sequence()
self.assertTrue(context.get("G_reply")[0] != 'E')
@skipIfOutOfTreeDebugserver
@debugserver_test
@skipIfDarwinEmbedded
def test_g_packet_debugserver(self):
self.init_debugserver_test()
self.run_test_g_packet()
@skipIf(archs=no_match(["x86_64"]))
def g_returns_correct_data(self, with_suffix):
procs = self.prep_debug_monitor_and_inferior()
self.add_register_info_collection_packets()
if with_suffix:
self.add_thread_suffix_request_packets()
self.add_threadinfo_collection_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather register info.
reg_infos = self.parse_register_info_packets(context)
self.assertIsNotNone(reg_infos)
self.add_lldb_register_index(reg_infos)
# Index register info entries by name.
reg_infos = {info['name']: info for info in reg_infos}
# Gather thread info.
if with_suffix:
threads = self.parse_threadinfo_packets(context)
self.assertIsNotNone(threads)
thread_id = threads[0]
self.assertIsNotNone(thread_id)
else:
thread_id = None
# Send vCont packet to resume the inferior.
self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2}).*#[0-9a-fA-F]{2}$",
"capture": {1: "hex_exit_code"}},
],
True)
# Send g packet to retrieve the register bank
if thread_id:
g_request = "read packet: $g;thread:{:x}#00".format(thread_id)
else:
g_request = "read packet: $g#00"
self.test_sequence.add_log_lines(
[g_request,
{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
"capture": {1: "register_bank"}}],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
reg_bank = context.get("register_bank")
self.assertTrue(reg_bank[0] != 'E')
byte_order = self.get_target_byte_order()
get_reg_value = lambda reg_name : _extract_register_value(
reg_infos[reg_name], reg_bank, byte_order)
self.assertEqual(['0x0102030405060708'], get_reg_value('r8'))
self.assertEqual(['0x1112131415161718'], get_reg_value('r9'))
self.assertEqual(['0x2122232425262728'], get_reg_value('r10'))
self.assertEqual(['0x3132333435363738'], get_reg_value('r11'))
self.assertEqual(['0x4142434445464748'], get_reg_value('r12'))
self.assertEqual(['0x5152535455565758'], get_reg_value('r13'))
self.assertEqual(['0x6162636465666768'], get_reg_value('r14'))
self.assertEqual(['0x7172737475767778'], get_reg_value('r15'))
self.assertEqual(
['0x020406080a0c0e01', '0x030507090b0d0f00'], get_reg_value('xmm8'))
self.assertEqual(
['0x121416181a1c1e11', '0x131517191b1d1f10'], get_reg_value('xmm9'))
self.assertEqual(
['0x222426282a2c2e21', '0x232527292b2d2f20'], get_reg_value('xmm10'))
self.assertEqual(
['0x323436383a3c3e31', '0x333537393b3d3f30'], get_reg_value('xmm11'))
self.assertEqual(
['0x424446484a4c4e41', '0x434547494b4d4f40'], get_reg_value('xmm12'))
self.assertEqual(
['0x525456585a5c5e51', '0x535557595b5d5f50'], get_reg_value('xmm13'))
self.assertEqual(
['0x626466686a6c6e61', '0x636567696b6d6f60'], get_reg_value('xmm14'))
self.assertEqual(
['0x727476787a7c7e71', '0x737577797b7d7f70'], get_reg_value('xmm15'))
@llgs_test
def test_g_returns_correct_data_with_suffix_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.g_returns_correct_data(True)
@llgs_test
def test_g_returns_correct_data_no_suffix_llgs(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
self.g_returns_correct_data(False)

View File

@ -1,54 +0,0 @@
#include <cstdint>
struct alignas(16) xmm_t {
uint64_t a, b;
};
int main() {
uint64_t r8 = 0x0102030405060708;
uint64_t r9 = 0x1112131415161718;
uint64_t r10 = 0x2122232425262728;
uint64_t r11 = 0x3132333435363738;
uint64_t r12 = 0x4142434445464748;
uint64_t r13 = 0x5152535455565758;
uint64_t r14 = 0x6162636465666768;
uint64_t r15 = 0x7172737475767778;
xmm_t xmm8 = {0x020406080A0C0E01, 0x030507090B0D0F00};
xmm_t xmm9 = {0x121416181A1C1E11, 0x131517191B1D1F10};
xmm_t xmm10 = {0x222426282A2C2E21, 0x232527292B2D2F20};
xmm_t xmm11 = {0x323436383A3C3E31, 0x333537393B3D3F30};
xmm_t xmm12 = {0x424446484A4C4E41, 0x434547494B4D4F40};
xmm_t xmm13 = {0x525456585A5C5E51, 0x535557595B5D5F50};
xmm_t xmm14 = {0x626466686A6C6E61, 0x636567696B6D6F60};
xmm_t xmm15 = {0x727476787A7C7E71, 0x737577797B7D7F70};
asm volatile("movq %0, %%r8\n\t"
"movq %1, %%r9\n\t"
"movq %2, %%r10\n\t"
"movq %3, %%r11\n\t"
"movq %4, %%r12\n\t"
"movq %5, %%r13\n\t"
"movq %6, %%r14\n\t"
"movq %7, %%r15\n\t"
"\n\t"
"movaps %8, %%xmm8\n\t"
"movaps %9, %%xmm9\n\t"
"movaps %10, %%xmm10\n\t"
"movaps %11, %%xmm11\n\t"
"movaps %12, %%xmm12\n\t"
"movaps %13, %%xmm13\n\t"
"movaps %14, %%xmm14\n\t"
"movaps %15, %%xmm15\n\t"
"\n\t"
"int3"
:
: "g"(r8), "g"(r9), "g"(r10), "g"(r11), "g"(r12), "g"(r13),
"g"(r14), "g"(r15), "m"(xmm8), "m"(xmm9), "m"(xmm10),
"m"(xmm11), "m"(xmm12), "m"(xmm13), "m"(xmm14), "m"(xmm15)
: "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
"%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13",
"%xmm14", "%xmm15");
return 0;
}

View File

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

View File

@ -1,115 +0,0 @@
# This test makes sure that lldb-server supports and properly handles
# QPassSignals GDB protocol package.
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemote_QPassSignals(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def expect_signal(self, expected_signo):
self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2}).*#[0-9a-fA-F]{2}$",
"capture": {1: "hex_exit_code"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
hex_exit_code = context.get("hex_exit_code")
self.assertIsNotNone(hex_exit_code)
self.assertEqual(int(hex_exit_code, 16), expected_signo)
def expect_exit_code(self, exit_code):
self.test_sequence.add_log_lines(
["read packet: $vCont;c#a8",
"send packet: $W{0:02x}#00".format(exit_code)],
True)
self.expect_gdbremote_sequence()
def ignore_signals(self, signals):
def signal_name_to_hex(signame):
return format(lldbutil.get_signal_number(signame), 'x')
signals_str = ";".join(map(signal_name_to_hex, signals))
self.test_sequence.add_log_lines(["read packet: $QPassSignals:"
+ signals_str + " #00",
"send packet: $OK#00"],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
@llgs_test
@skipUnlessPlatform(["linux", "android"])
def test_q_pass_signals(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
procs = self.prep_debug_monitor_and_inferior()
expected_signals = ["SIGSEGV",
"SIGALRM", "SIGFPE", "SIGBUS", "SIGINT", "SIGHUP"]
signals_to_ignore = ["SIGUSR1", "SIGUSR2"]
self.ignore_signals(signals_to_ignore)
for signal_name in expected_signals:
signo = lldbutil.get_signal_number(signal_name)
self.expect_signal(signo)
self.expect_exit_code(len(signals_to_ignore))
@llgs_test
@skipUnlessPlatform(["linux", "android"])
def test_change_signals_at_runtime(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
procs = self.prep_debug_monitor_and_inferior()
expected_signals = ["SIGSEGV", "SIGUSR1", "SIGUSR2",
"SIGALRM", "SIGHUP"]
signals_to_ignore = ["SIGFPE", "SIGBUS", "SIGINT"]
for signal_name in expected_signals:
signo = lldbutil.get_signal_number(signal_name)
self.expect_signal(signo)
if signal_name == "SIGALRM":
self.ignore_signals(signals_to_ignore)
self.expect_exit_code(len(signals_to_ignore))
@llgs_test
def test_default_signals_behavior(self):
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
procs = self.prep_debug_monitor_and_inferior()
expected_signals = ["SIGSEGV", "SIGUSR1", "SIGUSR2",
"SIGALRM", "SIGFPE", "SIGBUS", "SIGINT", "SIGHUP"]
for signal_name in expected_signals:
signo = lldbutil.get_signal_number(signal_name)
self.expect_signal(signo)
self.expect_exit_code(0)
@llgs_test
@skipUnlessPlatform(["linux", "android"])
def test_support_q_pass_signals(self):
self.init_llgs_test()
self.build()
# Start up the stub and start/prep the inferior.
self.set_inferior_startup_launch()
procs = self.prep_debug_monitor_and_inferior()
self.add_qSupported_packets()
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Retrieve the qSupported features and check QPassSignals+
supported_dict = self.parse_qSupported_response(context)
self.assertEqual(supported_dict["QPassSignals"], "+")

View File

@ -1,36 +0,0 @@
//===-- main.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 <signal.h>
#include <stdio.h>
#include <vector>
static int signal_counter = 0;
static void count_signal(int signo) {
++signal_counter;
printf("Signal %d\n", signo);
}
static void raise_signals() {
std::vector<int> signals(
{SIGSEGV, SIGUSR1, SIGUSR2, SIGALRM, SIGFPE, SIGBUS, SIGINT, SIGHUP});
for (int signal_num : signals) {
signal(signal_num, count_signal);
}
for (int signal_num : signals) {
raise(signal_num);
}
}
int main() {
raise_signals();
return signal_counter;
}

View File

@ -1,198 +0,0 @@
from __future__ import print_function
import re
import select
import threading
import traceback
import codecs
from six.moves import queue
from lldbsuite.support import seven
def _handle_output_packet_string(packet_contents):
if (not packet_contents) or (len(packet_contents) < 1):
return None
elif packet_contents[0] != "O":
return None
elif packet_contents == "OK":
return None
else:
return seven.unhexlify(packet_contents[1:])
def _dump_queue(the_queue):
while not the_queue.empty():
print(codecs.encode(the_queue.get(True), "string_escape"))
print("\n")
class PumpQueues(object):
def __init__(self):
self._output_queue = queue.Queue()
self._packet_queue = queue.Queue()
def output_queue(self):
return self._output_queue
def packet_queue(self):
return self._packet_queue
def verify_queues_empty(self):
# Warn if there is any content left in any of the queues.
# That would represent unmatched packets.
if not self.output_queue().empty():
print("warning: output queue entries still exist:")
_dump_queue(self.output_queue())
print("from here:")
traceback.print_stack()
if not self.packet_queue().empty():
print("warning: packet queue entries still exist:")
_dump_queue(self.packet_queue())
print("from here:")
traceback.print_stack()
class SocketPacketPump(object):
"""A threaded packet reader that partitions packets into two streams.
All incoming $O packet content is accumulated with the current accumulation
state put into the OutputQueue.
All other incoming packets are placed in the packet queue.
A select thread can be started and stopped, and runs to place packet
content into the two queues.
"""
_GDB_REMOTE_PACKET_REGEX = re.compile(r'^\$([^\#]*)#[0-9a-fA-F]{2}')
def __init__(self, pump_socket, pump_queues, logger=None):
if not pump_socket:
raise Exception("pump_socket cannot be None")
self._thread = None
self._stop_thread = False
self._socket = pump_socket
self._logger = logger
self._receive_buffer = ""
self._accumulated_output = ""
self._pump_queues = pump_queues
def __enter__(self):
"""Support the python 'with' statement.
Start the pump thread."""
self.start_pump_thread()
return self
def __exit__(self, exit_type, value, the_traceback):
"""Support the python 'with' statement.
Shut down the pump thread."""
self.stop_pump_thread()
def start_pump_thread(self):
if self._thread:
raise Exception("pump thread is already running")
self._stop_thread = False
self._thread = threading.Thread(target=self._run_method)
self._thread.start()
def stop_pump_thread(self):
self._stop_thread = True
if self._thread:
self._thread.join()
def _process_new_bytes(self, new_bytes):
if not new_bytes:
return
if len(new_bytes) < 1:
return
# Add new bytes to our accumulated unprocessed packet bytes.
self._receive_buffer += new_bytes
# Parse fully-formed packets into individual packets.
has_more = len(self._receive_buffer) > 0
while has_more:
if len(self._receive_buffer) <= 0:
has_more = False
# handle '+' ack
elif self._receive_buffer[0] == "+":
self._pump_queues.packet_queue().put("+")
self._receive_buffer = self._receive_buffer[1:]
if self._logger:
self._logger.debug(
"parsed packet from stub: +\n" +
"new receive_buffer: {}".format(
self._receive_buffer))
else:
packet_match = self._GDB_REMOTE_PACKET_REGEX.match(
self._receive_buffer)
if packet_match:
# Our receive buffer matches a packet at the
# start of the receive buffer.
new_output_content = _handle_output_packet_string(
packet_match.group(1))
if new_output_content:
# This was an $O packet with new content.
self._accumulated_output += new_output_content
self._pump_queues.output_queue().put(self._accumulated_output)
else:
# Any packet other than $O.
self._pump_queues.packet_queue().put(packet_match.group(0))
# Remove the parsed packet from the receive
# buffer.
self._receive_buffer = self._receive_buffer[
len(packet_match.group(0)):]
if self._logger:
self._logger.debug(
"parsed packet from stub: " +
packet_match.group(0))
self._logger.debug(
"new receive_buffer: " +
self._receive_buffer)
else:
# We don't have enough in the receive bufferto make a full
# packet. Stop trying until we read more.
has_more = False
def _run_method(self):
self._receive_buffer = ""
self._accumulated_output = ""
if self._logger:
self._logger.info("socket pump starting")
# Keep looping around until we're asked to stop the thread.
while not self._stop_thread:
can_read, _, _ = select.select([self._socket], [], [], 0)
if can_read and self._socket in can_read:
try:
new_bytes = seven.bitcast_to_string(self._socket.recv(4096))
if self._logger and new_bytes and len(new_bytes) > 0:
self._logger.debug(
"pump received bytes: {}".format(new_bytes))
except:
# Likely a closed socket. Done with the pump thread.
if self._logger:
self._logger.debug(
"socket read failed, stopping pump read thread\n" +
traceback.format_exc(3))
break
self._process_new_bytes(new_bytes)
if self._logger:
self._logger.info("socket pump exiting")
def get_accumulated_output(self):
return self._accumulated_output
def get_receive_buffer(self):
return self._receive_buffer

View File

@ -1,65 +0,0 @@
from __future__ import print_function
import unittest2
import os.path
import re
import sys
from lldbgdbserverutils import *
class TestLldbGdbServerUtils(unittest2.TestCase):
def test_entry_exact_payload_match(self):
entry = GdbRemoteEntry(is_send_to_remote=False, exact_payload="$OK#9a")
entry.assert_match(self, "$OK#9a")
def test_entry_exact_payload_match_ignores_checksum(self):
entry = GdbRemoteEntry(is_send_to_remote=False, exact_payload="$OK#9a")
entry.assert_match(self, "$OK#00")
def test_entry_creates_context(self):
entry = GdbRemoteEntry(is_send_to_remote=False, exact_payload="$OK#9a")
context = entry.assert_match(self, "$OK#9a")
self.assertIsNotNone(context)
def test_entry_regex_matches(self):
entry = GdbRemoteEntry(
is_send_to_remote=False,
regex=re.compile(r"^\$QC([0-9a-fA-F]+)#"),
capture={
1: "thread_id"})
context = entry.assert_match(self, "$QC980#00")
def test_entry_regex_saves_match(self):
entry = GdbRemoteEntry(
is_send_to_remote=False,
regex=re.compile(r"^\$QC([0-9a-fA-F]+)#"),
capture={
1: "thread_id"})
context = entry.assert_match(self, "$QC980#00")
self.assertEqual(context["thread_id"], "980")
def test_entry_regex_expect_captures_success(self):
context = {"thread_id": "980"}
entry = GdbRemoteEntry(
is_send_to_remote=False,
regex=re.compile(r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+)"),
expect_captures={
2: "thread_id"})
entry.assert_match(self, "$T11thread:980;", context=context)
def test_entry_regex_expect_captures_raises_on_fail(self):
context = {"thread_id": "980"}
entry = GdbRemoteEntry(
is_send_to_remote=False,
regex=re.compile(r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+)"),
expect_captures={
2: "thread_id"})
try:
entry.assert_match(self, "$T11thread:970;", context=context)
self.fail()
except AssertionError:
# okay
return None

View File

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

View File

@ -1,41 +0,0 @@
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteThreadName(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def run_and_check_name(self, expected_name):
self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
{"direction": "send",
"regex":
r"^\$T([0-9a-fA-F]{2})([^#]+)#[0-9a-fA-F]{2}$",
"capture": {
1: "signal",
2: "key_vals_text"}},
],
True)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
sigint = lldbutil.get_signal_number("SIGINT")
self.assertEqual(sigint, int(context.get("signal"), 16))
kv_dict = self.parse_key_val_dict(context.get("key_vals_text"))
self.assertEqual(expected_name, kv_dict.get("name"))
@llgs_test
def test(self):
""" Make sure lldb-server can retrieve inferior thread name"""
self.init_llgs_test()
self.build()
self.set_inferior_startup_launch()
procs = self.prep_debug_monitor_and_inferior()
self.run_and_check_name("hello world")
self.run_and_check_name("goodbye world")

View File

@ -1,22 +0,0 @@
#include <pthread.h>
#include <signal.h>
void set_thread_name(const char *name) {
#if defined(__APPLE__)
::pthread_setname_np(name);
#elif defined(__FreeBSD__)
::pthread_set_name_np(::pthread_self(), name);
#elif defined(__linux__)
::pthread_setname_np(::pthread_self(), name);
#elif defined(__NetBSD__)
::pthread_setname_np(::pthread_self(), "%s", name);
#endif
}
int main() {
set_thread_name("hello world");
raise(SIGINT);
set_thread_name("goodbye world");
raise(SIGINT);
return 0;
}

View File

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

View File

@ -1,193 +0,0 @@
"""
Test lldb-vscode setBreakpoints request
"""
from __future__ import print_function
import unittest2
import vscode
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import lldbvscode_testcase
import os
import shutil
import subprocess
import tempfile
import threading
import time
def spawn_and_wait(program, delay):
if delay:
time.sleep(delay)
process = subprocess.Popen([program],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
process.wait()
class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
def set_and_hit_breakpoint(self, continueToExit=True):
source = 'main.c'
breakpoint1_line = line_number(source, '// breakpoint 1')
lines = [breakpoint1_line]
# Set breakoint in the thread function so we can step the threads
breakpoint_ids = self.set_source_breakpoints(source, lines)
self.assertEqual(len(breakpoint_ids), len(lines),
"expect correct number of breakpoints")
self.continue_to_breakpoints(breakpoint_ids)
if continueToExit:
self.continue_to_exit()
@skipIfWindows
@skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots
@skipIfNetBSD # Hangs on NetBSD as well
@no_debug_info_test
def test_by_pid(self):
'''
Tests attaching to a process by process ID.
'''
self.build_and_create_debug_adaptor()
program = self.getBuildArtifact("a.out")
self.process = subprocess.Popen([program],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
self.attach(pid=self.process.pid)
self.set_and_hit_breakpoint(continueToExit=True)
@skipIfWindows
@skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots
@skipIfNetBSD # Hangs on NetBSD as well
@no_debug_info_test
def test_by_name(self):
'''
Tests attaching to a process by process name.
'''
self.build_and_create_debug_adaptor()
orig_program = self.getBuildArtifact("a.out")
# Since we are going to attach by process name, we need a unique
# process name that has minimal chance to match a process that is
# already running. To do this we use tempfile.mktemp() to give us a
# full path to a location where we can copy our executable. We then
# run this copy to ensure we don't get the error "more that one
# process matches 'a.out'".
program = tempfile.mktemp()
shutil.copyfile(orig_program, program)
shutil.copymode(orig_program, program)
def cleanup():
if os.path.exists(program):
os.unlink(program)
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
self.process = subprocess.Popen([program],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# Wait for a bit to ensure the process is launched, but not for so long
# that the process has already finished by the time we attach.
time.sleep(3)
self.attach(program=program)
self.set_and_hit_breakpoint(continueToExit=True)
@skipUnlessDarwin
@skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots
@skipIfNetBSD # Hangs on NetBSD as well
@no_debug_info_test
def test_by_name_waitFor(self):
'''
Tests attaching to a process by process name and waiting for the
next instance of a process to be launched, ingoring all current
ones.
'''
self.build_and_create_debug_adaptor()
program = self.getBuildArtifact("a.out")
self.spawn_thread = threading.Thread(target=spawn_and_wait,
args=(program, 1.0,))
self.spawn_thread.start()
self.attach(program=program, waitFor=True)
self.set_and_hit_breakpoint(continueToExit=True)
@skipIfWindows
@skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots
@skipIfNetBSD # Hangs on NetBSD as well
@no_debug_info_test
def test_commands(self):
'''
Tests the "initCommands", "preRunCommands", "stopCommands",
"exitCommands", and "attachCommands" that can be passed during
attach.
"initCommands" are a list of LLDB commands that get executed
before the targt is created.
"preRunCommands" are a list of LLDB commands that get executed
after the target has been created and before the launch.
"stopCommands" are a list of LLDB commands that get executed each
time the program stops.
"exitCommands" are a list of LLDB commands that get executed when
the process exits
"attachCommands" are a list of LLDB commands that get executed and
must have a valid process in the selected target in LLDB after
they are done executing. This allows custom commands to create any
kind of debug session.
'''
self.build_and_create_debug_adaptor()
program = self.getBuildArtifact("a.out")
# Here we just create a target and launch the process as a way to test
# if we are able to use attach commands to create any kind of a target
# and use it for debugging
attachCommands = [
'target create -d "%s"' % (program),
'process launch -- arg1'
]
initCommands = ['target list', 'platform list']
preRunCommands = ['image list a.out', 'image dump sections a.out']
stopCommands = ['frame variable', 'bt']
exitCommands = ['expr 2+3', 'expr 3+4']
self.attach(program=program,
attachCommands=attachCommands,
initCommands=initCommands,
preRunCommands=preRunCommands,
stopCommands=stopCommands,
exitCommands=exitCommands)
# Get output from the console. This should contain both the
# "initCommands" and the "preRunCommands".
output = self.get_console()
# Verify all "initCommands" were found in console output
self.verify_commands('initCommands', output, initCommands)
# Verify all "preRunCommands" were found in console output
self.verify_commands('preRunCommands', output, preRunCommands)
functions = ['main']
breakpoint_ids = self.set_function_breakpoints(functions)
self.assertTrue(len(breakpoint_ids) == len(functions),
"expect one breakpoint")
self.continue_to_breakpoints(breakpoint_ids)
output = self.get_console(timeout=1.0)
self.verify_commands('stopCommands', output, stopCommands)
# Continue after launch and hit the "pause()" call and stop the target.
# Get output from the console. This should contain both the
# "stopCommands" that were run after we stop.
self.vscode.request_continue()
time.sleep(0.5)
self.vscode.request_pause()
self.vscode.wait_for_stopped()
output = self.get_console(timeout=1.0)
self.verify_commands('stopCommands', output, stopCommands)
# Continue until the program exits
self.continue_to_exit()
# Get output from the console. This should contain both the
# "exitCommands" that were run after the second breakpoint was hit
output = self.get_console(timeout=1.0)
self.verify_commands('exitCommands', output, exitCommands)

View File

@ -1,11 +0,0 @@
#include <stdio.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
lldb_enable_attach();
printf("pid = %i\n", getpid());
sleep(10);
return 0; // breakpoint 1
}

View File

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

View File

@ -1,211 +0,0 @@
"""
Test lldb-vscode setBreakpoints request
"""
from __future__ import print_function
import pprint
import unittest2
import vscode
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import lldbvscode_testcase
import os
class TestVSCode_setBreakpoints(lldbvscode_testcase.VSCodeTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows
@skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots
@no_debug_info_test
def test_set_and_clear(self):
'''Tests setting and clearing source file and line breakpoints.
This packet is a bit tricky on the debug adaptor side since there
is no "clearBreakpoints" packet. Source file and line breakpoints
are set by sending a "setBreakpoints" packet with a source file
specified and zero or more source lines. If breakpoints have been
set in the source file before, any exising breakpoints must remain
set, and any new breakpoints must be created, and any breakpoints
that were in previous requests and are not in the current request
must be removed. This function tests this setting and clearing
and makes sure things happen correctly. It doesn't test hitting
breakpoints and the functionality of each breakpoint, like
'conditions' and 'hitCondition' settings.'''
source_basename = 'main.cpp'
source_path = os.path.join(os.getcwd(), source_basename)
first_line = line_number('main.cpp', 'break 12')
second_line = line_number('main.cpp', 'break 13')
third_line = line_number('main.cpp', 'break 14')
lines = [first_line, second_line, third_line]
# Visual Studio Code Debug Adaptors have no way to specify the file
# without launching or attaching to a process, so we must start a
# process in order to be able to set breakpoints.
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
# Set 3 breakoints and verify that they got set correctly
response = self.vscode.request_setBreakpoints(source_path, lines)
line_to_id = {}
if response:
breakpoints = response['body']['breakpoints']
self.assertTrue(len(breakpoints) == len(lines),
"expect %u source breakpoints" % (len(lines)))
for breakpoint in breakpoints:
line = breakpoint['line']
# Store the "id" of the breakpoint that was set for later
line_to_id[line] = breakpoint['id']
self.assertTrue(line in lines, "line expected in lines array")
self.assertTrue(breakpoint['verified'],
"expect breakpoint verified")
# There is no breakpoint delete packet, clients just send another
# setBreakpoints packet with the same source file with fewer lines.
# Below we remove the second line entry and call the setBreakpoints
# function again. We want to verify that any breakpoints that were set
# before still have the same "id". This means we didn't clear the
# breakpoint and set it again at the same location. We also need to
# verify that the second line location was actually removed.
lines.remove(second_line)
# Set 2 breakoints and verify that the previous breakoints that were
# set above are still set.
response = self.vscode.request_setBreakpoints(source_path, lines)
if response:
breakpoints = response['body']['breakpoints']
self.assertTrue(len(breakpoints) == len(lines),
"expect %u source breakpoints" % (len(lines)))
for breakpoint in breakpoints:
line = breakpoint['line']
# Verify the same breakpoints are still set within LLDB by
# making sure the breakpoint ID didn't change
self.assertTrue(line_to_id[line] == breakpoint['id'],
"verify previous breakpoints stayed the same")
self.assertTrue(line in lines, "line expected in lines array")
self.assertTrue(breakpoint['verified'],
"expect breakpoint still verified")
# Now get the full list of breakpoints set in the target and verify
# we have only 2 breakpoints set. The response above could have told
# us about 2 breakpoints, but we want to make sure we don't have the
# third one still set in the target
response = self.vscode.request_testGetTargetBreakpoints()
if response:
breakpoints = response['body']['breakpoints']
self.assertTrue(len(breakpoints) == len(lines),
"expect %u source breakpoints" % (len(lines)))
for breakpoint in breakpoints:
line = breakpoint['line']
# Verify the same breakpoints are still set within LLDB by
# making sure the breakpoint ID didn't change
self.assertTrue(line_to_id[line] == breakpoint['id'],
"verify previous breakpoints stayed the same")
self.assertTrue(line in lines, "line expected in lines array")
self.assertTrue(breakpoint['verified'],
"expect breakpoint still verified")
# Now clear all breakpoints for the source file by passing down an
# empty lines array
lines = []
response = self.vscode.request_setBreakpoints(source_path, lines)
if response:
breakpoints = response['body']['breakpoints']
self.assertTrue(len(breakpoints) == len(lines),
"expect %u source breakpoints" % (len(lines)))
# Verify with the target that all breakpoints have been cleared
response = self.vscode.request_testGetTargetBreakpoints()
if response:
breakpoints = response['body']['breakpoints']
self.assertTrue(len(breakpoints) == len(lines),
"expect %u source breakpoints" % (len(lines)))
# Now set a breakpoint again in the same source file and verify it
# was added.
lines = [second_line]
response = self.vscode.request_setBreakpoints(source_path, lines)
if response:
breakpoints = response['body']['breakpoints']
self.assertTrue(len(breakpoints) == len(lines),
"expect %u source breakpoints" % (len(lines)))
for breakpoint in breakpoints:
line = breakpoint['line']
self.assertTrue(line in lines, "line expected in lines array")
self.assertTrue(breakpoint['verified'],
"expect breakpoint still verified")
# Now get the full list of breakpoints set in the target and verify
# we have only 2 breakpoints set. The response above could have told
# us about 2 breakpoints, but we want to make sure we don't have the
# third one still set in the target
response = self.vscode.request_testGetTargetBreakpoints()
if response:
breakpoints = response['body']['breakpoints']
self.assertTrue(len(breakpoints) == len(lines),
"expect %u source breakpoints" % (len(lines)))
for breakpoint in breakpoints:
line = breakpoint['line']
self.assertTrue(line in lines, "line expected in lines array")
self.assertTrue(breakpoint['verified'],
"expect breakpoint still verified")
@skipIfWindows
@skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots
@no_debug_info_test
def test_functionality(self):
'''Tests hitting breakpoints and the functionality of a single
breakpoint, like 'conditions' and 'hitCondition' settings.'''
source_basename = 'main.cpp'
source_path = os.path.join(os.getcwd(), source_basename)
loop_line = line_number('main.cpp', '// break loop')
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
# Set a breakpoint at the loop line with no condition and no
# hitCondition
breakpoint_ids = self.set_source_breakpoints(source_path, [loop_line])
self.assertTrue(len(breakpoint_ids) == 1, "expect one breakpoint")
self.vscode.request_continue()
# Verify we hit the breakpoint we just set
self.verify_breakpoint_hit(breakpoint_ids)
# Make sure i is zero at first breakpoint
i = int(self.vscode.get_local_variable_value('i'))
self.assertTrue(i == 0, 'i != 0 after hitting breakpoint')
# Update the condition on our breakpoint
new_breakpoint_ids = self.set_source_breakpoints(source_path,
[loop_line],
condition="i==4")
self.assertTrue(breakpoint_ids == new_breakpoint_ids,
"existing breakpoint should have its condition "
"updated")
self.continue_to_breakpoints(breakpoint_ids)
i = int(self.vscode.get_local_variable_value('i'))
self.assertTrue(i == 4,
'i != 4 showing conditional works')
new_breakpoint_ids = self.set_source_breakpoints(source_path,
[loop_line],
hitCondition="2")
self.assertTrue(breakpoint_ids == new_breakpoint_ids,
"existing breakpoint should have its condition "
"updated")
# Continue with a hitContidtion of 2 and expect it to skip 1 value
self.continue_to_breakpoints(breakpoint_ids)
i = int(self.vscode.get_local_variable_value('i'))
self.assertTrue(i == 6,
'i != 6 showing hitCondition works')
# continue after hitting our hitCondition and make sure it only goes
# up by 1
self.continue_to_breakpoints(breakpoint_ids)
i = int(self.vscode.get_local_variable_value('i'))
self.assertTrue(i == 7,
'i != 7 showing post hitCondition hits every time')

Some files were not shown because too many files have changed in this diff Show More