diff options
-rw-r--r-- | lldb/include/lldb/API/SBReproducer.h | 2 | ||||
-rw-r--r-- | lldb/source/API/SBReproducer.cpp | 20 | ||||
-rw-r--r-- | lldb/test/Shell/Reproducer/TestVersionCheck.test | 29 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.cpp | 4 | ||||
-rw-r--r-- | lldb/tools/driver/Options.td | 2 |
5 files changed, 53 insertions, 4 deletions
diff --git a/lldb/include/lldb/API/SBReproducer.h b/lldb/include/lldb/API/SBReproducer.h index 93e567607aa..8bb530a0fe4 100644 --- a/lldb/include/lldb/API/SBReproducer.h +++ b/lldb/include/lldb/API/SBReproducer.h @@ -20,7 +20,7 @@ class LLDB_API SBReproducer { public: static const char *Capture(); 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 = false); static const char *GetPath(); static bool Generate(); }; diff --git a/lldb/source/API/SBReproducer.cpp b/lldb/source/API/SBReproducer.cpp index d50d95ebb54..1107161a419 100644 --- a/lldb/source/API/SBReproducer.cpp +++ b/lldb/source/API/SBReproducer.cpp @@ -22,8 +22,8 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBHostOS.h" #include "lldb/API/SBReproducer.h" - #include "lldb/Host/FileSystem.h" +#include "lldb/lldb-private.h" using namespace lldb; using namespace lldb_private; @@ -124,7 +124,7 @@ const char *SBReproducer::Capture(const char *path) { return nullptr; } -const char *SBReproducer::Replay(const char *path) { +const char *SBReproducer::Replay(const char *path, bool skip_version_check) { static std::string error; if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) { error = llvm::toString(std::move(e)); @@ -137,6 +137,22 @@ const char *SBReproducer::Replay(const char *path) { return error.c_str(); } + if (!skip_version_check) { + llvm::Expected<std::string> version = loader->LoadBuffer<VersionProvider>(); + if (!version) { + error = llvm::toString(version.takeError()); + return error.c_str(); + } + if (lldb_private::GetVersion() != llvm::StringRef(*version).rtrim()) { + error = "reproducer capture and replay version don't match:\n"; + error.append("reproducer captured with:\n"); + error.append(*version); + error.append("reproducer replayed with:\n"); + error.append(lldb_private::GetVersion()); + return error.c_str(); + } + } + FileSpec file = loader->GetFile<SBProvider::Info>(); if (!file) { error = "unable to get replay data from reproducer."; diff --git a/lldb/test/Shell/Reproducer/TestVersionCheck.test b/lldb/test/Shell/Reproducer/TestVersionCheck.test new file mode 100644 index 00000000000..e3fb60367ce --- /dev/null +++ b/lldb/test/Shell/Reproducer/TestVersionCheck.test @@ -0,0 +1,29 @@ +# REQUIRES: system-darwin + +# This tests the reproducer version check. + +# RUN: rm -rf %t.repro +# RUN: %clang_host %S/Inputs/simple.c -g -o %t.out +# RUN: %lldb -x -b -s %S/Inputs/FileCapture.in --capture --capture-path %t.repro %t.out | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE + +# Make sure that replay works. +# RUN: %lldb --replay %t.repro | FileCheck %s --check-prefix CHECK --check-prefix REPLAY + +# Change the reproducer version. +# RUN: echo "bogus" >> %t.repro/version.txt + +# Make sure that replay works. +# RUN: not %lldb --replay %t.repro 2>&1 | FileCheck %s --check-prefix ERROR + +# Make sure that we can circumvent the version check with -reproducer-skip-version-check. +# RUN: %lldb --replay %t.repro -reproducer-skip-version-check | FileCheck %s --check-prefix CHECK --check-prefix REPLAY + +# CAPTURE: testing +# REPLAY-NOT: testing + +# CHECK: Process {{.*}} exited + +# CAPTURE: Reproducer is in capture mode. +# CAPTURE: Reproducer written + +# ERROR: error: reproducer replay failed: reproducer capture and replay version don't match diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index e13507be22d..73874389aa1 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -797,7 +797,9 @@ 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())) { + const bool skip_version_check = input_args.hasArg(OPT_skip_version_check); + if (const char *error = + SBReproducer::Replay(replay_path->getValue(), skip_version_check)) { WithColor::error() << "reproducer replay failed: " << error << '\n'; return 1; } diff --git a/lldb/tools/driver/Options.td b/lldb/tools/driver/Options.td index 485c0d44bc8..c237f568f64 100644 --- a/lldb/tools/driver/Options.td +++ b/lldb/tools/driver/Options.td @@ -232,5 +232,7 @@ def capture_path: Separate<["--", "-"], "capture-path">, def replay: Separate<["--", "-"], "replay">, MetaVarName<"<filename>">, HelpText<"Tells the debugger to replay a reproducer from <filename>.">; +def skip_version_check: F<"reproducer-skip-version-check">, + HelpText<"Skip the reproducer version check.">; def REM : R<["--"], "">; |