[Lldb-commits] [PATCH] D56322: [Reproducers] SBReproducer framework

Pavel Labath via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 5 05:14:30 PST 2019

labath added a comment.

Thank you. I like the new test, but see my comment about avoiding duplicating macros in the test. Besides returning objects, I can think of a couple of more interesting scenarios to cover:

- recursive calls (to exercise the g_global_boundary thingy)
- having two objects with identical `this` pointers (you can use placement `new` to guarantee that)
- calling the "custom" function during replay

Comment at: unittests/Utility/ReproducerInstrumentationTest.cpp:60-62
+template <typename T> bool Equals(T LHS, T RHS) {
+  return std::fabs(RHS - LHS) < std::numeric_limits<T>::epsilon();
googletest already has apis for this: EXPECT_FLOAT/DOUBLE_EQ or EXPECT_NEAR.

Comment at: unittests/Utility/ReproducerInstrumentationTest.cpp:67-122
+#define SB_RECORD_CONSTRUCTOR(Class, Signature, ...)                           \
+  lldb_private::repro::Recorder sb_recorder(g_serializer, g_registry,          \
+                                            LLVM_PRETTY_FUNCTION);             \
+  sb_recorder.Record(&lldb_private::repro::construct<Class Signature>::doit,   \
+                     __VA_ARGS__);                                             \
+  sb_recorder.RecordResult(this);
Since these macros are the actual "public" interface of the instrumentation framework, and they do contain non-trivial logic, I think it would be nice to test the real macros, instead of redefining them here. (It would also be nice to simply avoid duplicating code.)

Would something like this work:
- move the macros to ReproducerInstrumentation.h (maybe also rename to `LLDB_RECORD_blah_blah`).
- parameterize them on a macro for getting the instrumentation classes. So, something like:

#define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...)                           \
  if (InstrumentationData data = LLDB_GET_INSTRUMENTATION_DATA()) {  \
    lldb_private::repro::Recorder recorder(                                 \
        data.GetSerializer(),                   \
        data.GetRegistry(),                     \
        LLVM_PRETTY_FUNCTION);                                                 \
    sb_recorder.Record(&lldb_private::repro::construct<Class Signature>::doit, \
                       __VA_ARGS__);                                           \
    sb_recorder.RecordResult(this);                                            \
where `InstrumentationData` is essentially `std::pair<Serializer *, Registry *>` with a suitable `operator bool`. Then the tests could define `LLDB_GET_INSTRUMENTATION_DATA` simply to `InstrumentationData(&g_serializer, &g_registry)` and the "real" code could do something like
#define LLDB_GET_INSTRUMENTATION_DATA lldb_private::repro::GetInstrumentationData()

InstrumentationData GetInstrumentationData() {
  auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator();
  if (!g) return {};
  auto &p = g->GetOrCreate<SBProvider>();
  return {p.GetSerializer(), p.GetRegistry();

Comment at: unittests/Utility/ReproducerInstrumentationTest.cpp:143-148
+    EXPECT_EQ(g_a, 0);
+    EXPECT_EQ(g_b, 0);
+    EXPECT_EQ(g_c, 0);
+    EXPECT_EQ(g_d, "");
+    EXPECT_EQ(g_e, 0);
+    EXPECT_EQ(g_f, false);
This seems rather pointless, as you've just set the variables to those values. What are you testing here? The compiler?

Comment at: unittests/Utility/ReproducerInstrumentationTest.cpp:384
+  llvm::raw_string_ostream os(str);
+  g_serializer = Serializer(os);
Make g_serializer `llvm:Optional`, and then you can avoid needing it be copyable (I think making the Serializer class copyable is a bad idea for the same reason than making raw_ostream copyable would be a bad idea)

Comment at: unittests/Utility/ReproducerInstrumentationTest.cpp:399-404
+  EXPECT_EQ(foo.g_a, 100);
+  EXPECT_EQ(foo.g_b, 200);
+  EXPECT_TRUE(Equals(foo.g_c, c));
+  EXPECT_EQ(foo.g_d, "bar");
+  EXPECT_TRUE(Equals(foo.g_e, e));
+  EXPECT_EQ(foo.g_f, true);
access variables via the class (InstrumentedFoo::g_a) to make it clear that they are static.



More information about the lldb-commits mailing list