summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBReproducer.h2
-rw-r--r--lldb/source/API/SBReproducer.cpp20
-rw-r--r--lldb/test/Shell/Reproducer/TestVersionCheck.test29
-rw-r--r--lldb/tools/driver/Driver.cpp4
-rw-r--r--lldb/tools/driver/Options.td2
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<["--"], "">;
OpenPOWER on IntegriCloud