#include "lldb/API/SBProcessInfo.h"
#include "lldb/API/SBQueue.h"
#include "lldb/API/SBQueueItem.h"
+#include "lldb/API/SBReproducer.h"
#include "lldb/API/SBSection.h"
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBStream.h"
--- /dev/null
+//===-- SWIG Interface for SBReproducer--------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+class SBReproducer
+{
+ public:
+ static const char *Capture(const char *path);
+ static const char *PassiveReplay(const char *path);
+ static bool SetAutoGenerate(bool b);
+};
+}
%include "./interface/SBProcessInfo.i"
%include "./interface/SBQueue.i"
%include "./interface/SBQueueItem.i"
+%include "./interface/SBReproducer.i"
%include "./interface/SBSection.i"
%include "./interface/SBSourceManager.i"
%include "./interface/SBStream.i"
static const char *Capture(const char *path);
static const char *Replay(const char *path);
static const char *Replay(const char *path, bool skip_version_check);
+ static const char *PassiveReplay(const char *path);
static const char *GetPath();
static bool SetAutoGenerate(bool b);
static bool Generate();
# Set this flag if there is any session info dumped during the test run.
sdir_has_content = False
-
# svn_info stores the output from 'svn info lldb.base.dir'.
svn_info = ''
results_formatter_options = None
test_result = None
+# Reproducers
+capture_path = None
+replay_path = None
+
# Test rerun configuration vars
rerun_all_issues = False
return "ASAN unsupported"
return None
return skipTestIfFn(is_asan)(func)
+
+def skipIfReproducer(func):
+ """Skip this test if the environment is set up to run LLDB with reproducers."""
+ def is_reproducer():
+ if configuration.capture_path or configuration.replay_path:
+ return "reproducers unsupported"
+ return None
+ return skipTestIfFn(is_reproducer)(func)
configuration.results_formatter_name = (
"lldbsuite.test_event.formatter.results_formatter.ResultsFormatter")
+ # Reproducer arguments
+ if args.capture_path and args.replay_path:
+ logging.error('Cannot specify both a capture and a replay path.')
+ sys.exit(-1)
+
+ if args.capture_path:
+ configuration.capture_path = args.capture_path
+
+ if args.replay_path:
+ configuration.replay_path = args.replay_path
+
# rerun-related arguments
configuration.rerun_all_issues = args.rerun_all_issues
setupSysPath()
import lldbconfig
+ if configuration.capture_path or configuration.replay_path:
+ lldbconfig.INITIALIZE = False
import lldb
+ if configuration.capture_path:
+ lldb.SBReproducer.Capture(configuration.capture_path)
+ lldb.SBReproducer.SetAutoGenerate(True)
+ elif configuration.replay_path:
+ lldb.SBReproducer.PassiveReplay(configuration.replay_path)
+
+ if not lldbconfig.INITIALIZE:
+ lldb.SBDebugger.Initialize()
+
# Use host platform by default.
lldb.selected_platform = lldb.SBPlatform.GetHostPlatform()
metavar='platform-working-dir',
help='The directory to use on the remote platform.')
+ # Reproducer options
+ group = parser.add_argument_group('Reproducer options')
+ group.add_argument(
+ '--capture-path',
+ metavar='reproducer path',
+ help='The reproducer capture path')
+ group.add_argument(
+ '--replay-path',
+ metavar='reproducer path',
+ help='The reproducer replay path')
+
# Test-suite behaviour
group = parser.add_argument_group('Runtime behaviour options')
X('-d', 'Suspend the process after launch to wait indefinitely for a debugger to attach')
return nullptr;
}
+const char *SBReproducer::PassiveReplay(const char *path) {
+ static std::string error;
+ if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) {
+ error = llvm::toString(std::move(e));
+ return error.c_str();
+ }
+ return nullptr;
+}
+
const char *SBReproducer::Replay(const char *path) {
return SBReproducer::Replay(path, false);
}
@skipIfWindows
@skipIfRemote
@skipIfiOSSimulator
+ @skipIfReproducer
def test_reproducer_attach(self):
"""Test thread creation after process attach."""
exe = '%s_%d' % (self.testMethodName, os.getpid())
config.environment['LLDB_CAPTURE_REPRODUCER'] = os.environ[
'LLDB_CAPTURE_REPRODUCER']
+# Support running the test suite under the lldb-repro wrapper. This makes it
+# possible to capture a test suite run and then rerun all the test from the
+# just captured reproducer.
+lldb_repro_mode = lit_config.params.get('lldb-run-with-repro', None)
+if lldb_repro_mode:
+ lit_config.note("Running API tests in {} mode.".format(lldb_repro_mode))
+ if lldb_repro_mode == 'capture':
+ config.available_features.add('lldb-repro-capture')
+ elif lldb_repro_mode == 'replay':
+ config.available_features.add('lldb-repro-replay')
+
# Clean the module caches in the test build directory. This is necessary in an
# incremental build whenever clang changes underneath, so doing it once per
# lit.py invocation is close enough.
from __future__ import absolute_import
import os
-
+import tempfile
import subprocess
import sys
# python exe as the first parameter of the command.
cmd = [sys.executable] + self.dotest_cmd + [testPath, '-p', testFile]
+ builddir = getBuildDir(cmd)
+ mkdir_p(builddir)
+
# The macOS system integrity protection (SIP) doesn't allow injecting
# libraries into system binaries, but this can be worked around by
# copying the binary into a different location.
if 'DYLD_INSERT_LIBRARIES' in test.config.environment and \
(sys.executable.startswith('/System/') or \
sys.executable.startswith('/usr/bin/')):
- builddir = getBuildDir(cmd)
- mkdir_p(builddir)
copied_python = os.path.join(builddir, 'copied-system-python')
if not os.path.isfile(copied_python):
import shutil, subprocess
shutil.copy(python, copied_python)
cmd[0] = copied_python
+ if 'lldb-repro-capture' in test.config.available_features or \
+ 'lldb-repro-replay' in test.config.available_features:
+ reproducer_root = os.path.join(builddir, 'reproducers')
+ mkdir_p(reproducer_root)
+ reproducer_path = os.path.join(reproducer_root, testFile)
+ if 'lldb-repro-capture' in test.config.available_features:
+ cmd.extend(['--capture-path', reproducer_path])
+ else:
+ cmd.extend(['--replay-path', reproducer_path])
+
timeoutInfo = None
try:
out, err, exitCode = lit.util.executeCommand(