forked from OSchip/llvm-project
[Reproducers] Support capturing a reproducer without an explicit path.
Tablegen doesn't support options that are both flags and take values as an argument. I noticed this when doing the tablegen rewrite, but forgot that that affected the reproducer --capture flag. This patch makes --capture a flag and adds --capture-path to specify a path for the reproducer. In reality I expect this to be mostly used for testing, but it could be useful nonetheless. Differential revision: https://reviews.llvm.org/D59238 llvm-svn: 355936
This commit is contained in:
parent
5c1177a68f
commit
13ecae2f9a
|
@ -18,6 +18,7 @@ namespace lldb {
|
|||
/// in the interface or implementation of this class.
|
||||
class LLDB_API SBReproducer {
|
||||
public:
|
||||
static const char *Capture();
|
||||
static const char *Capture(const char *path);
|
||||
static const char *Replay(const char *path);
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# RUN: rm -rf %t.repro
|
||||
# RUN: %clangxx %S/Inputs/foo.cpp -g -o %t.out
|
||||
|
||||
# RUN: %lldb -x -b -s %S/Inputs/DataFormatter.in --capture %t.repro %t.out | FileCheck %s
|
||||
# RUN: %lldb -x -b -s %S/Inputs/DataFormatter.in --capture --capture-path %t.repro %t.out | FileCheck %s
|
||||
# RUN: %lldb --replay %t.repro | FileCheck %s
|
||||
|
||||
# CHECK: stop reason = breakpoint 1.1
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# RUN: rm -rf %t.txt
|
||||
|
||||
# RUN: echo "CAPTURE" >> %t.txt
|
||||
# RUN: %lldb -x -b --capture %t.repro \
|
||||
# RUN: %lldb -x -b --capture --capture-path %t.repro \
|
||||
# RUN: -o 'run' \
|
||||
# RUN: -o 'image list' \
|
||||
# RUN: -o 'reproducer generate' \
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
# This tests that stepping continues to work when replaying a reproducer.
|
||||
|
||||
# RUN: rm -rf %t.repro
|
||||
# RUN: %clang %S/Inputs/stepping.c -O0 -g -o %t.out
|
||||
# RUN: grep -v '#' %s > %t.in
|
||||
|
||||
# RUN: %lldb -x -b -s %t.in --capture %t.repro %t.out | FileCheck %s --check-prefix CHECK
|
||||
# RUN: %lldb -x -b -s %t.in --capture --capture-path %t.repro %t.out | FileCheck %s --check-prefix CHECK
|
||||
# RUN: %lldb --replay %t.repro | FileCheck %s --check-prefix CHECK
|
||||
|
||||
# Set breakpoints in a,b and c and verify we stop there when stepping.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# REQUIRES: system-darwin
|
||||
|
||||
# Start fresh.
|
||||
# RUN: rm -rf %t.repro
|
||||
# RUN: rm -rf %t.root
|
||||
# RUN: rm -rf %t.clang-cache
|
||||
# RUN: rm -rf %t.lldb-cache
|
||||
|
@ -18,7 +19,7 @@
|
|||
# RUN: %clang %t.root/main.cpp -g -fmodules -fcxx-modules -fmodules-cache-path=%t.clang-cache -o %t.root/a.out
|
||||
|
||||
# Capture the debug session.
|
||||
# RUN: %lldb -x -b -o 'settings set symbols.clang-modules-cache-path %t.lldb-cache' -s %S/Inputs/ModuleCXX.in --capture %t.repro %t.root/a.out | FileCheck %s --check-prefix CAPTURE
|
||||
# RUN: %lldb -x -b -o 'settings set symbols.clang-modules-cache-path %t.lldb-cache' -s %S/Inputs/ModuleCXX.in --capture --capture-path %t.repro %t.root/a.out | FileCheck %s --check-prefix CAPTURE
|
||||
# CAPTURE: (success = 0)
|
||||
|
||||
# RUN: cat %t.repro/files.yaml | FileCheck %s --check-prefix YAML
|
||||
|
|
|
@ -1,7 +1,17 @@
|
|||
# Check that errors are propagated to the driver.
|
||||
#
|
||||
# RUN: not %lldb --capture --capture-path %t/bogus/bogus 2>&1 | FileCheck %s --check-prefix INVALID-CAPTURE
|
||||
# RUN: not %lldb --replay %t/bogus/bogus 2>&1 | FileCheck %s --check-prefix INVALID-REPLAY
|
||||
#
|
||||
# INVALID-CAPTURE: unable to create reproducer directory
|
||||
# INVALID-REPLAY: unable to load reproducer index
|
||||
|
||||
# RUN: not %lldb --capture %t/bogus/bogus 2>&1 | FileCheck %s --check-prefix CAPTURE
|
||||
# RUN: not %lldb --replay %t/bogus/bogus 2>&1 | FileCheck %s --check-prefix REPLAY
|
||||
|
||||
# CAPTURE: unable to create reproducer directory
|
||||
# REPLAY: unable to load reproducer index
|
||||
# Check that all option combination work as expected.
|
||||
#
|
||||
# RUN: %lldb --capture --capture-path %t.repro -b -o 'reproducer status' 2>&1 | FileCheck %s --check-prefix NO-WARNING --check-prefix STATUS-CAPTURE
|
||||
# RUN: %lldb --capture -b -o 'reproducer status' 2>&1 | FileCheck %s --check-prefix NO-WARNING --check-prefix STATUS-CAPTURE
|
||||
# RUN: %lldb --capture-path %t.repro -b -o 'reproducer status' 2>&1 | FileCheck %s --check-prefix WARNING --check-prefix STATUS-CAPTURE
|
||||
#
|
||||
# NO-WARNING-NOT: warning: -capture-path specified without -capture
|
||||
# WARNING: warning: -capture-path specified without -capture
|
||||
# STATUS-CAPTURE: Reproducer is in capture mode.
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
# process. To ensure we're not actually running the original binary we check
|
||||
# that the string "testing" is not printed.
|
||||
|
||||
# RUN: rm -rf %t.repro
|
||||
# RUN: %clang %S/Inputs/simple.c -g -o %t.out
|
||||
# RUN: %lldb -x -b -s %S/Inputs/FileCapture.in --capture %t.repro %t.out | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE
|
||||
# RUN: %lldb -x -b -s %S/Inputs/FileCapture.in --capture --capture-path %t.repro %t.out | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE
|
||||
# RUN: rm %t.out
|
||||
# RUN: %lldb --replay %t.repro | FileCheck %s --check-prefix CHECK --check-prefix REPLAY
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
# process. To ensure we're not actually running the original binary we check
|
||||
# that the string "testing" is not printed.
|
||||
|
||||
# RUN: rm -rf %t.repro
|
||||
# RUN: %clang %S/Inputs/simple.c -g -o %t.out
|
||||
# RUN: %lldb -x -b -s %S/Inputs/GDBRemoteCapture.in --capture %t.repro %t.out | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE
|
||||
# RUN: %lldb -x -b -s %S/Inputs/GDBRemoteCapture.in --capture --capture-path %t.repro %t.out | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE
|
||||
# RUN: %lldb --replay %t.repro | FileCheck %s --check-prefix CHECK --check-prefix REPLAY
|
||||
|
||||
# CHECK: Breakpoint 1
|
||||
|
|
|
@ -2940,6 +2940,15 @@ SBRegistry::SBRegistry() {
|
|||
}
|
||||
}
|
||||
|
||||
const char *SBReproducer::Capture() {
|
||||
static std::string error;
|
||||
if (auto e = Reproducer::Initialize(ReproducerMode::Capture, llvm::None)) {
|
||||
error = llvm::toString(std::move(e));
|
||||
return error.c_str();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *SBReproducer::Capture(const char *path) {
|
||||
static std::string error;
|
||||
if (auto e =
|
||||
|
|
|
@ -849,6 +849,38 @@ EXAMPLES:
|
|||
llvm::outs() << examples;
|
||||
}
|
||||
|
||||
llvm::Optional<int> InitializeReproducer(opt::InputArgList &input_args) {
|
||||
if (auto *replay_path = input_args.getLastArg(OPT_replay)) {
|
||||
if (const char *error = SBReproducer::Replay(replay_path->getValue())) {
|
||||
WithColor::error() << "reproducer replay failed: " << error << '\n';
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool capture = input_args.hasArg(OPT_capture);
|
||||
auto *capture_path = input_args.getLastArg(OPT_capture_path);
|
||||
|
||||
if (capture || capture_path) {
|
||||
if (capture_path) {
|
||||
if (!capture)
|
||||
WithColor::warning() << "-capture-path specified without -capture\n";
|
||||
if (const char *error = SBReproducer::Capture(capture_path->getValue())) {
|
||||
WithColor::error() << "reproducer capture failed: " << error << '\n';
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
const char *error = SBReproducer::Capture();
|
||||
if (error) {
|
||||
WithColor::error() << "reproducer capture failed: " << error << '\n';
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return llvm::None;
|
||||
}
|
||||
|
||||
int
|
||||
#ifdef _MSC_VER
|
||||
wmain(int argc, wchar_t const *wargv[])
|
||||
|
@ -889,23 +921,8 @@ main(int argc, char const *argv[])
|
|||
<< '\n';
|
||||
}
|
||||
|
||||
if (auto *arg = input_args.getLastArg(OPT_capture)) {
|
||||
auto arg_value = arg->getValue();
|
||||
const char *error = SBReproducer::Capture(arg_value);
|
||||
if (error) {
|
||||
WithColor::error() << "reproducer capture failed: " << error << '\n';
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto *arg = input_args.getLastArg(OPT_replay)) {
|
||||
auto arg_value = arg->getValue();
|
||||
const char *error = SBReproducer::Replay(arg_value);
|
||||
if (error) {
|
||||
WithColor::error() << "reproducer replay failed: " << error << '\n';
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if (auto exit_code = InitializeReproducer(input_args)) {
|
||||
return *exit_code;
|
||||
}
|
||||
|
||||
SBError error = SBDebugger::InitializeWithErrorHandling();
|
||||
|
|
|
@ -219,9 +219,11 @@ def: Flag<["-"], "d">,
|
|||
Alias<debug>,
|
||||
HelpText<"Alias for --debug">;
|
||||
|
||||
def capture: Separate<["--", "-"], "capture">,
|
||||
def capture: F<"capture">,
|
||||
HelpText<"Tells the debugger to capture a reproducer.">;
|
||||
def capture_path: Separate<["--", "-"], "capture-path">,
|
||||
MetaVarName<"<filename>">,
|
||||
HelpText<"Tells the debugger to capture a reproducer to <filename>.">;
|
||||
HelpText<"Tells the debugger to use the given filename for the reproducer.">;
|
||||
def replay: Separate<["--", "-"], "replay">,
|
||||
MetaVarName<"<filename>">,
|
||||
HelpText<"Tells the debugger to replay a reproducer from <filename>.">;
|
||||
|
|
Loading…
Reference in New Issue