1 //===-- ReproducerInstrumentationTest.cpp ---------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11 
12 #include <cmath>
13 #include <limits>
14 
15 #include "lldb/Utility/ReproducerInstrumentation.h"
16 
17 using namespace lldb_private;
18 using namespace lldb_private::repro;
19 
20 struct Foo {
21   int m = 1;
22 };
23 struct Bar {
24   double m = 2;
25 };
26 
operator ==(const Foo & LHS,const Foo & RHS)27 bool operator==(const Foo &LHS, const Foo &RHS) { return LHS.m == RHS.m; }
operator ==(const Bar & LHS,const Bar & RHS)28 bool operator==(const Bar &LHS, const Bar &RHS) { return LHS.m == RHS.m; }
29 
30 struct Pod {
31   bool a = true;
32   bool b = false;
33   char c = 'a';
34   float d = 1.1f;
35   int e = 2;
36   long long f = 3;
37   long g = 4;
38   short h = 5;
39   unsigned char i = 'b';
40   unsigned int j = 6;
41   unsigned long long k = 7;
42   unsigned long l = 8;
43   unsigned short m = 9;
44 
PodPod45   Pod() {}
46 };
47 
48 class TestingRegistry : public Registry {
49 public:
50   TestingRegistry();
51 };
52 
53 static llvm::Optional<TestingRegistry> g_registry;
54 static llvm::Optional<Serializer> g_serializer;
55 static llvm::Optional<Deserializer> g_deserializer;
56 
57 class TestInstrumentationData : public InstrumentationData {
58 public:
TestInstrumentationData()59   TestInstrumentationData() : InstrumentationData() {}
TestInstrumentationData(Serializer & serializer,Registry & registry)60   TestInstrumentationData(Serializer &serializer, Registry &registry)
61       : InstrumentationData(serializer, registry) {}
TestInstrumentationData(Deserializer & deserializer,Registry & registry)62   TestInstrumentationData(Deserializer &deserializer, Registry &registry)
63       : InstrumentationData(deserializer, registry) {}
64 };
65 
GetTestInstrumentationData()66 inline TestInstrumentationData GetTestInstrumentationData() {
67   assert(!(g_serializer && g_deserializer));
68   if (g_serializer)
69     return TestInstrumentationData(*g_serializer, *g_registry);
70   if (g_deserializer)
71     return TestInstrumentationData(*g_deserializer, *g_registry);
72   return TestInstrumentationData();
73 }
74 
75 class TestInstrumentationDataRAII {
76 public:
TestInstrumentationDataRAII(llvm::raw_string_ostream & os)77   TestInstrumentationDataRAII(llvm::raw_string_ostream &os) {
78     g_registry.emplace();
79     g_serializer.emplace(os);
80     g_deserializer.reset();
81   }
82 
TestInstrumentationDataRAII(llvm::StringRef buffer)83   TestInstrumentationDataRAII(llvm::StringRef buffer) {
84     g_registry.emplace();
85     g_serializer.reset();
86     g_deserializer.emplace(buffer);
87   }
88 
~TestInstrumentationDataRAII()89   ~TestInstrumentationDataRAII() { Reset(); }
90 
Reset()91   void Reset() {
92     g_registry.reset();
93     g_serializer.reset();
94     g_deserializer.reset();
95   }
96 
97   static std::unique_ptr<TestInstrumentationDataRAII>
GetRecordingData(llvm::raw_string_ostream & os)98   GetRecordingData(llvm::raw_string_ostream &os) {
99     return std::make_unique<TestInstrumentationDataRAII>(os);
100   }
101 
102   static std::unique_ptr<TestInstrumentationDataRAII>
GetReplayData(llvm::StringRef buffer)103   GetReplayData(llvm::StringRef buffer) {
104     return std::make_unique<TestInstrumentationDataRAII>(buffer);
105   }
106 };
107 
108 #define LLDB_GET_INSTRUMENTATION_DATA() GetTestInstrumentationData()
109 
110 enum class Class {
111   Foo,
112   Bar,
113 };
114 
115 class Instrumented {
116 public:
117   virtual ~Instrumented() = default;
118   virtual void Validate() = 0;
119   virtual bool IsA(Class c) = 0;
120 };
121 
122 class InstrumentedFoo : public Instrumented {
123 public:
124   InstrumentedFoo() = default;
125   /// Instrumented methods.
126   /// {
127   InstrumentedFoo(int i);
128   InstrumentedFoo(const InstrumentedFoo &foo);
129   InstrumentedFoo &operator=(const InstrumentedFoo &foo);
130   void A(int a);
131   int GetA();
132   void B(int &b) const;
133   int &GetB();
134   int C(float *c);
135   float GetC();
136   int D(const char *d) const;
137   size_t GetD(char *buffer, size_t length);
138   static void E(double e);
139   double GetE();
140   static int F();
141   bool GetF();
142   void Validate() override;
143   //// }
IsA(Class c)144   virtual bool IsA(Class c) override { return c == Class::Foo; }
145 
146 private:
147   int m_a = 0;
148   mutable int m_b = 0;
149   float m_c = 0;
150   mutable std::string m_d = {};
151   static double g_e;
152   static bool g_f;
153   mutable int m_called = 0;
154 };
155 
156 class InstrumentedBar : public Instrumented {
157 public:
158   /// Instrumented methods.
159   /// {
160   InstrumentedBar();
161   InstrumentedFoo GetInstrumentedFoo();
162   InstrumentedFoo &GetInstrumentedFooRef();
163   InstrumentedFoo *GetInstrumentedFooPtr();
164   void SetInstrumentedFoo(InstrumentedFoo *foo);
165   void SetInstrumentedFoo(InstrumentedFoo &foo);
166   void Validate() override;
167   /// }
IsA(Class c)168   virtual bool IsA(Class c) override { return c == Class::Bar; }
169 
170 private:
171   bool m_get_instrumend_foo_called = false;
172   InstrumentedFoo *m_foo_set_by_ptr = nullptr;
173   InstrumentedFoo *m_foo_set_by_ref = nullptr;
174 };
175 
176 double InstrumentedFoo::g_e = 0;
177 bool InstrumentedFoo::g_f = false;
178 
179 struct Validator {
180   enum Validation { valid, invalid };
ValidatorValidator181   Validator(Class clazz, Validation validation)
182       : clazz(clazz), validation(validation) {}
183   Class clazz;
184   Validation validation;
185 };
186 
ValidateObjects(std::vector<void * > objects,std::vector<Validator> validators)187 void ValidateObjects(std::vector<void *> objects,
188                      std::vector<Validator> validators) {
189   ASSERT_EQ(validators.size(), objects.size());
190   for (size_t i = 0; i < validators.size(); ++i) {
191     Validator &validator = validators[i];
192     Instrumented *instrumented = static_cast<Instrumented *>(objects[i]);
193     EXPECT_TRUE(instrumented->IsA(validator.clazz));
194     switch (validator.validation) {
195     case Validator::valid:
196       instrumented->Validate();
197       break;
198     case Validator::invalid:
199       break;
200     }
201   }
202 }
203 
InstrumentedFoo(int i)204 InstrumentedFoo::InstrumentedFoo(int i) {
205   LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (int), i);
206 }
207 
InstrumentedFoo(const InstrumentedFoo & foo)208 InstrumentedFoo::InstrumentedFoo(const InstrumentedFoo &foo) {
209   LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &), foo);
210 }
211 
operator =(const InstrumentedFoo & foo)212 InstrumentedFoo &InstrumentedFoo::operator=(const InstrumentedFoo &foo) {
213   LLDB_RECORD_METHOD(InstrumentedFoo &,
214                      InstrumentedFoo, operator=,(const InstrumentedFoo &), foo);
215   return *this;
216 }
217 
A(int a)218 void InstrumentedFoo::A(int a) {
219   LLDB_RECORD_METHOD(void, InstrumentedFoo, A, (int), a);
220   B(a);
221   m_a = a;
222 }
223 
GetA()224 int InstrumentedFoo::GetA() {
225   LLDB_RECORD_METHOD_NO_ARGS(int, InstrumentedFoo, GetA);
226 
227   return m_a;
228 }
229 
B(int & b) const230 void InstrumentedFoo::B(int &b) const {
231   LLDB_RECORD_METHOD_CONST(void, InstrumentedFoo, B, (int &), b);
232   m_called++;
233   m_b = b;
234 }
235 
GetB()236 int &InstrumentedFoo::GetB() {
237   LLDB_RECORD_METHOD_NO_ARGS(int &, InstrumentedFoo, GetB);
238 
239   return m_b;
240 }
241 
C(float * c)242 int InstrumentedFoo::C(float *c) {
243   LLDB_RECORD_METHOD(int, InstrumentedFoo, C, (float *), c);
244   m_c = *c;
245   return 1;
246 }
247 
GetC()248 float InstrumentedFoo::GetC() {
249   LLDB_RECORD_METHOD_NO_ARGS(float, InstrumentedFoo, GetC);
250 
251   return m_c;
252 }
253 
D(const char * d) const254 int InstrumentedFoo::D(const char *d) const {
255   LLDB_RECORD_METHOD_CONST(int, InstrumentedFoo, D, (const char *), d);
256   m_d = std::string(d);
257   return 2;
258 }
259 
GetD(char * buffer,size_t length)260 size_t InstrumentedFoo::GetD(char *buffer, size_t length) {
261   LLDB_RECORD_CHAR_PTR_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t),
262                               buffer, "", length);
263   ::snprintf(buffer, length, "%s", m_d.c_str());
264   return m_d.size();
265 }
266 
E(double e)267 void InstrumentedFoo::E(double e) {
268   LLDB_RECORD_STATIC_METHOD(void, InstrumentedFoo, E, (double), e);
269   g_e = e;
270 }
271 
GetE()272 double InstrumentedFoo::GetE() {
273   LLDB_RECORD_METHOD_NO_ARGS(double, InstrumentedFoo, GetE);
274 
275   return g_e;
276 }
277 
F()278 int InstrumentedFoo::F() {
279   LLDB_RECORD_STATIC_METHOD_NO_ARGS(int, InstrumentedFoo, F);
280   g_f = true;
281   return 3;
282 }
283 
GetF()284 bool InstrumentedFoo::GetF() {
285   LLDB_RECORD_METHOD_NO_ARGS(bool, InstrumentedFoo, GetF);
286 
287   return g_f;
288 }
289 
Validate()290 void InstrumentedFoo::Validate() {
291   LLDB_RECORD_METHOD_NO_ARGS(void, InstrumentedFoo, Validate);
292   EXPECT_EQ(m_a, 100);
293   EXPECT_EQ(m_b, 200);
294   EXPECT_NEAR(m_c, 300.3, 0.01);
295   EXPECT_EQ(m_d, "bar");
296   EXPECT_NEAR(g_e, 400.4, 0.01);
297   EXPECT_EQ(g_f, true);
298   EXPECT_EQ(2, m_called);
299 }
300 
InstrumentedBar()301 InstrumentedBar::InstrumentedBar() {
302   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(InstrumentedBar);
303 }
304 
GetInstrumentedFoo()305 InstrumentedFoo InstrumentedBar::GetInstrumentedFoo() {
306   LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo, InstrumentedBar,
307                              GetInstrumentedFoo);
308   m_get_instrumend_foo_called = true;
309   return LLDB_RECORD_RESULT(InstrumentedFoo(0));
310 }
311 
GetInstrumentedFooRef()312 InstrumentedFoo &InstrumentedBar::GetInstrumentedFooRef() {
313   LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo &, InstrumentedBar,
314                              GetInstrumentedFooRef);
315   InstrumentedFoo *foo = new InstrumentedFoo(0);
316   m_get_instrumend_foo_called = true;
317   return LLDB_RECORD_RESULT(*foo);
318 }
319 
GetInstrumentedFooPtr()320 InstrumentedFoo *InstrumentedBar::GetInstrumentedFooPtr() {
321   LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo *, InstrumentedBar,
322                              GetInstrumentedFooPtr);
323   InstrumentedFoo *foo = new InstrumentedFoo(0);
324   m_get_instrumend_foo_called = true;
325   return LLDB_RECORD_RESULT(foo);
326 }
327 
SetInstrumentedFoo(InstrumentedFoo * foo)328 void InstrumentedBar::SetInstrumentedFoo(InstrumentedFoo *foo) {
329   LLDB_RECORD_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
330                      (InstrumentedFoo *), foo);
331   m_foo_set_by_ptr = foo;
332 }
333 
SetInstrumentedFoo(InstrumentedFoo & foo)334 void InstrumentedBar::SetInstrumentedFoo(InstrumentedFoo &foo) {
335   LLDB_RECORD_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
336                      (InstrumentedFoo &), foo);
337   m_foo_set_by_ref = &foo;
338 }
339 
Validate()340 void InstrumentedBar::Validate() {
341   LLDB_RECORD_METHOD_NO_ARGS(void, InstrumentedBar, Validate);
342 
343   EXPECT_TRUE(m_get_instrumend_foo_called);
344   EXPECT_NE(m_foo_set_by_ptr, nullptr);
345   EXPECT_EQ(m_foo_set_by_ptr, m_foo_set_by_ref);
346 }
347 
TestingRegistry()348 TestingRegistry::TestingRegistry() {
349   Registry &R = *this;
350 
351   LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (int i));
352   LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &));
353   LLDB_REGISTER_METHOD(InstrumentedFoo &,
354                        InstrumentedFoo, operator=,(const InstrumentedFoo &));
355   LLDB_REGISTER_METHOD(void, InstrumentedFoo, A, (int));
356   LLDB_REGISTER_METHOD_CONST(void, InstrumentedFoo, B, (int &));
357   LLDB_REGISTER_METHOD(int, InstrumentedFoo, C, (float *));
358   LLDB_REGISTER_METHOD_CONST(int, InstrumentedFoo, D, (const char *));
359   LLDB_REGISTER_STATIC_METHOD(void, InstrumentedFoo, E, (double));
360   LLDB_REGISTER_STATIC_METHOD(int, InstrumentedFoo, F, ());
361   LLDB_REGISTER_METHOD(void, InstrumentedFoo, Validate, ());
362 
363   LLDB_REGISTER_CONSTRUCTOR(InstrumentedBar, ());
364   LLDB_REGISTER_METHOD(InstrumentedFoo, InstrumentedBar, GetInstrumentedFoo,
365                        ());
366   LLDB_REGISTER_METHOD(InstrumentedFoo &, InstrumentedBar,
367                        GetInstrumentedFooRef, ());
368   LLDB_REGISTER_METHOD(InstrumentedFoo *, InstrumentedBar,
369                        GetInstrumentedFooPtr, ());
370   LLDB_REGISTER_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
371                        (InstrumentedFoo *));
372   LLDB_REGISTER_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
373                        (InstrumentedFoo &));
374   LLDB_REGISTER_METHOD(void, InstrumentedBar, Validate, ());
375   LLDB_REGISTER_METHOD(int, InstrumentedFoo, GetA, ());
376   LLDB_REGISTER_METHOD(int &, InstrumentedFoo, GetB, ());
377   LLDB_REGISTER_METHOD(float, InstrumentedFoo, GetC, ());
378   LLDB_REGISTER_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t));
379   LLDB_REGISTER_METHOD(double, InstrumentedFoo, GetE, ());
380   LLDB_REGISTER_METHOD(bool, InstrumentedFoo, GetF, ());
381 }
382 
383 static const Pod p;
384 
TEST(IndexToObjectTest,ObjectForIndex)385 TEST(IndexToObjectTest, ObjectForIndex) {
386   IndexToObject index_to_object;
387   Foo foo;
388   Bar bar;
389 
390   EXPECT_EQ(nullptr, index_to_object.GetObjectForIndex<Foo>(1));
391   EXPECT_EQ(nullptr, index_to_object.GetObjectForIndex<Bar>(2));
392 
393   index_to_object.AddObjectForIndex<Foo>(1, foo);
394   index_to_object.AddObjectForIndex<Bar>(2, &bar);
395 
396   EXPECT_EQ(&foo, index_to_object.GetObjectForIndex<Foo>(1));
397   EXPECT_EQ(&bar, index_to_object.GetObjectForIndex<Bar>(2));
398 }
399 
TEST(DeserializerTest,HasData)400 TEST(DeserializerTest, HasData) {
401   {
402     Deserializer deserializer("");
403     EXPECT_FALSE(deserializer.HasData(1));
404   }
405 
406   {
407     Deserializer deserializer("a");
408     EXPECT_TRUE(deserializer.HasData(1));
409     EXPECT_FALSE(deserializer.HasData(2));
410   }
411 }
412 
TEST(SerializationRountripTest,SerializeDeserializePod)413 TEST(SerializationRountripTest, SerializeDeserializePod) {
414   std::string str;
415   llvm::raw_string_ostream os(str);
416 
417   Serializer serializer(os);
418   serializer.SerializeAll(p.a, p.b, p.c, p.d, p.e, p.f, p.g, p.h, p.i, p.j, p.k,
419                           p.l, p.m);
420 
421   llvm::StringRef buffer(os.str());
422   Deserializer deserializer(buffer);
423 
424   EXPECT_EQ(p.a, deserializer.Deserialize<bool>());
425   EXPECT_EQ(p.b, deserializer.Deserialize<bool>());
426   EXPECT_EQ(p.c, deserializer.Deserialize<char>());
427   EXPECT_EQ(p.d, deserializer.Deserialize<float>());
428   EXPECT_EQ(p.e, deserializer.Deserialize<int>());
429   EXPECT_EQ(p.f, deserializer.Deserialize<long long>());
430   EXPECT_EQ(p.g, deserializer.Deserialize<long>());
431   EXPECT_EQ(p.h, deserializer.Deserialize<short>());
432   EXPECT_EQ(p.i, deserializer.Deserialize<unsigned char>());
433   EXPECT_EQ(p.j, deserializer.Deserialize<unsigned int>());
434   EXPECT_EQ(p.k, deserializer.Deserialize<unsigned long long>());
435   EXPECT_EQ(p.l, deserializer.Deserialize<unsigned long>());
436   EXPECT_EQ(p.m, deserializer.Deserialize<unsigned short>());
437 }
438 
TEST(SerializationRountripTest,SerializeDeserializePodPointers)439 TEST(SerializationRountripTest, SerializeDeserializePodPointers) {
440   std::string str;
441   llvm::raw_string_ostream os(str);
442 
443   Serializer serializer(os);
444   serializer.SerializeAll(&p.a, &p.b, &p.c, &p.d, &p.e, &p.f, &p.g, &p.h, &p.i,
445                           &p.j, &p.k, &p.l, &p.m);
446 
447   llvm::StringRef buffer(os.str());
448   Deserializer deserializer(buffer);
449 
450   EXPECT_EQ(p.a, *deserializer.Deserialize<bool *>());
451   EXPECT_EQ(p.b, *deserializer.Deserialize<bool *>());
452   EXPECT_EQ(p.c, *deserializer.Deserialize<char *>());
453   EXPECT_EQ(p.d, *deserializer.Deserialize<float *>());
454   EXPECT_EQ(p.e, *deserializer.Deserialize<int *>());
455   EXPECT_EQ(p.f, *deserializer.Deserialize<long long *>());
456   EXPECT_EQ(p.g, *deserializer.Deserialize<long *>());
457   EXPECT_EQ(p.h, *deserializer.Deserialize<short *>());
458   EXPECT_EQ(p.i, *deserializer.Deserialize<unsigned char *>());
459   EXPECT_EQ(p.j, *deserializer.Deserialize<unsigned int *>());
460   EXPECT_EQ(p.k, *deserializer.Deserialize<unsigned long long *>());
461   EXPECT_EQ(p.l, *deserializer.Deserialize<unsigned long *>());
462   EXPECT_EQ(p.m, *deserializer.Deserialize<unsigned short *>());
463 }
464 
TEST(SerializationRountripTest,SerializeDeserializePodReferences)465 TEST(SerializationRountripTest, SerializeDeserializePodReferences) {
466   std::string str;
467   llvm::raw_string_ostream os(str);
468 
469   Serializer serializer(os);
470   serializer.SerializeAll(p.a, p.b, p.c, p.d, p.e, p.f, p.g, p.h, p.i, p.j, p.k,
471                           p.l, p.m);
472 
473   llvm::StringRef buffer(os.str());
474   Deserializer deserializer(buffer);
475 
476   EXPECT_EQ(p.a, deserializer.Deserialize<bool &>());
477   EXPECT_EQ(p.b, deserializer.Deserialize<bool &>());
478   EXPECT_EQ(p.c, deserializer.Deserialize<char &>());
479   EXPECT_EQ(p.d, deserializer.Deserialize<float &>());
480   EXPECT_EQ(p.e, deserializer.Deserialize<int &>());
481   EXPECT_EQ(p.f, deserializer.Deserialize<long long &>());
482   EXPECT_EQ(p.g, deserializer.Deserialize<long &>());
483   EXPECT_EQ(p.h, deserializer.Deserialize<short &>());
484   EXPECT_EQ(p.i, deserializer.Deserialize<unsigned char &>());
485   EXPECT_EQ(p.j, deserializer.Deserialize<unsigned int &>());
486   EXPECT_EQ(p.k, deserializer.Deserialize<unsigned long long &>());
487   EXPECT_EQ(p.l, deserializer.Deserialize<unsigned long &>());
488   EXPECT_EQ(p.m, deserializer.Deserialize<unsigned short &>());
489 }
490 
TEST(SerializationRountripTest,SerializeDeserializeCString)491 TEST(SerializationRountripTest, SerializeDeserializeCString) {
492   const char *cstr = "string";
493 
494   std::string str;
495   llvm::raw_string_ostream os(str);
496 
497   Serializer serializer(os);
498   serializer.SerializeAll(cstr);
499 
500   llvm::StringRef buffer(os.str());
501   Deserializer deserializer(buffer);
502 
503   EXPECT_STREQ(cstr, deserializer.Deserialize<const char *>());
504 }
505 
TEST(SerializationRountripTest,SerializeDeserializeCStringNull)506 TEST(SerializationRountripTest, SerializeDeserializeCStringNull) {
507   const char *cstr = nullptr;
508 
509   std::string str;
510   llvm::raw_string_ostream os(str);
511 
512   Serializer serializer(os);
513   serializer.SerializeAll(cstr);
514 
515   llvm::StringRef buffer(os.str());
516   Deserializer deserializer(buffer);
517 
518   EXPECT_EQ(nullptr, deserializer.Deserialize<const char *>());
519 }
520 
TEST(SerializationRountripTest,SerializeDeserializeCStringArray)521 TEST(SerializationRountripTest, SerializeDeserializeCStringArray) {
522   const char *foo = "foo";
523   const char *bar = "bar";
524   const char *baz = "baz";
525   const char *arr[4] = {foo, bar, baz, nullptr};
526 
527   std::string str;
528   llvm::raw_string_ostream os(str);
529 
530   Serializer serializer(os);
531   serializer.SerializeAll(static_cast<const char **>(arr));
532 
533   llvm::StringRef buffer(os.str());
534   Deserializer deserializer(buffer);
535 
536   const char **deserialized = deserializer.Deserialize<const char **>();
537   EXPECT_STREQ("foo", deserialized[0]);
538   EXPECT_STREQ("bar", deserialized[1]);
539   EXPECT_STREQ("baz", deserialized[2]);
540 }
541 
TEST(SerializationRountripTest,SerializeDeserializeCStringArrayNullptrElem)542 TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptrElem) {
543   const char *arr[1] = {nullptr};
544 
545   std::string str;
546   llvm::raw_string_ostream os(str);
547 
548   Serializer serializer(os);
549   serializer.SerializeAll(static_cast<const char **>(arr));
550 
551   llvm::StringRef buffer(os.str());
552   Deserializer deserializer(buffer);
553 
554   const char **deserialized = deserializer.Deserialize<const char **>();
555   EXPECT_EQ(nullptr, deserialized);
556 }
557 
TEST(SerializationRountripTest,SerializeDeserializeCStringArrayNullptr)558 TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptr) {
559   std::string str;
560   llvm::raw_string_ostream os(str);
561 
562   Serializer serializer(os);
563   serializer.SerializeAll(static_cast<const char **>(nullptr));
564 
565   llvm::StringRef buffer(os.str());
566   Deserializer deserializer(buffer);
567 
568   const char **deserialized = deserializer.Deserialize<const char **>();
569   EXPECT_EQ(nullptr, deserialized);
570 }
571 
TEST(SerializationRountripTest,SerializeDeserializeObjectPointer)572 TEST(SerializationRountripTest, SerializeDeserializeObjectPointer) {
573   Foo foo;
574   Bar bar;
575 
576   std::string str;
577   llvm::raw_string_ostream os(str);
578 
579   unsigned sequence = 123;
580 
581   Serializer serializer(os);
582   serializer.SerializeAll(sequence, static_cast<unsigned>(1));
583   serializer.SerializeAll(sequence, static_cast<unsigned>(2));
584   serializer.SerializeAll(&foo, &bar);
585 
586   llvm::StringRef buffer(os.str());
587   Deserializer deserializer(buffer);
588 
589   deserializer.HandleReplayResult(&foo);
590   deserializer.HandleReplayResult(&bar);
591 
592   EXPECT_EQ(foo, *deserializer.Deserialize<Foo *>());
593   EXPECT_EQ(bar, *deserializer.Deserialize<Bar *>());
594 }
595 
TEST(SerializationRountripTest,SerializeDeserializeObjectReference)596 TEST(SerializationRountripTest, SerializeDeserializeObjectReference) {
597   Foo foo;
598   Bar bar;
599 
600   std::string str;
601   llvm::raw_string_ostream os(str);
602 
603   unsigned sequence = 123;
604 
605   Serializer serializer(os);
606   serializer.SerializeAll(sequence, static_cast<unsigned>(1));
607   serializer.SerializeAll(sequence, static_cast<unsigned>(2));
608   serializer.SerializeAll(foo, bar);
609 
610   llvm::StringRef buffer(os.str());
611   Deserializer deserializer(buffer);
612 
613   deserializer.HandleReplayResult(&foo);
614   deserializer.HandleReplayResult(&bar);
615 
616   EXPECT_EQ(foo, deserializer.Deserialize<Foo &>());
617   EXPECT_EQ(bar, deserializer.Deserialize<Bar &>());
618 }
619 
TEST(RecordReplayTest,InstrumentedFoo)620 TEST(RecordReplayTest, InstrumentedFoo) {
621   std::string str;
622   llvm::raw_string_ostream os(str);
623 
624   {
625     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
626 
627     int b = 200;
628     float c = 300.3f;
629     double e = 400.4;
630 
631     InstrumentedFoo foo(0);
632     foo.A(100);
633     foo.B(b);
634     foo.C(&c);
635     foo.D("bar");
636     InstrumentedFoo::E(e);
637     InstrumentedFoo::F();
638     foo.Validate();
639   }
640 
641   TestingRegistry registry;
642   Deserializer deserializer(os.str());
643   registry.Replay(deserializer);
644 
645   ValidateObjects(deserializer.GetAllObjects(),
646                   {{Class::Foo, Validator::valid}});
647 }
648 
TEST(RecordReplayTest,InstrumentedFooSameThis)649 TEST(RecordReplayTest, InstrumentedFooSameThis) {
650   std::string str;
651   llvm::raw_string_ostream os(str);
652 
653   {
654     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
655 
656     int b = 200;
657     float c = 300.3f;
658     double e = 400.4;
659 
660     InstrumentedFoo *foo = new InstrumentedFoo(0);
661     foo->A(100);
662     foo->B(b);
663     foo->C(&c);
664     foo->D("bar");
665     InstrumentedFoo::E(e);
666     InstrumentedFoo::F();
667     foo->Validate();
668     foo->~InstrumentedFoo();
669 
670     InstrumentedFoo *foo2 = new (foo) InstrumentedFoo(0);
671     foo2->A(100);
672     foo2->B(b);
673     foo2->C(&c);
674     foo2->D("bar");
675     InstrumentedFoo::E(e);
676     InstrumentedFoo::F();
677     foo2->Validate();
678     delete foo2;
679   }
680 
681   TestingRegistry registry;
682   Deserializer deserializer(os.str());
683   registry.Replay(deserializer);
684 
685   ValidateObjects(deserializer.GetAllObjects(),
686                   {{Class::Foo, Validator::valid}});
687 }
688 
TEST(RecordReplayTest,InstrumentedBar)689 TEST(RecordReplayTest, InstrumentedBar) {
690   std::string str;
691   llvm::raw_string_ostream os(str);
692 
693   {
694     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
695 
696     InstrumentedBar bar;
697     InstrumentedFoo foo = bar.GetInstrumentedFoo();
698 
699     int b = 200;
700     float c = 300.3f;
701     double e = 400.4;
702 
703     foo.A(100);
704     foo.B(b);
705     foo.C(&c);
706     foo.D("bar");
707     InstrumentedFoo::E(e);
708     InstrumentedFoo::F();
709     foo.Validate();
710 
711     bar.SetInstrumentedFoo(foo);
712     bar.SetInstrumentedFoo(&foo);
713     bar.Validate();
714   }
715 
716   TestingRegistry registry;
717   Deserializer deserializer(os.str());
718   registry.Replay(deserializer);
719 
720   ValidateObjects(
721       deserializer.GetAllObjects(),
722       {
723           {Class::Bar, Validator::valid},   // bar
724           {Class::Foo, Validator::invalid}, // bar.GetInstrumentedFoo()
725           {Class::Foo, Validator::valid},   // foo
726       });
727 }
728 
TEST(RecordReplayTest,InstrumentedBarRef)729 TEST(RecordReplayTest, InstrumentedBarRef) {
730   std::string str;
731   llvm::raw_string_ostream os(str);
732 
733   {
734     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
735 
736     InstrumentedBar bar;
737     InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
738 
739     int b = 200;
740     float c = 300.3f;
741     double e = 400.4;
742 
743     foo.A(100);
744     foo.B(b);
745     foo.C(&c);
746     foo.D("bar");
747     InstrumentedFoo::E(e);
748     InstrumentedFoo::F();
749     foo.Validate();
750 
751     bar.SetInstrumentedFoo(foo);
752     bar.SetInstrumentedFoo(&foo);
753     bar.Validate();
754   }
755 
756   TestingRegistry registry;
757   Deserializer deserializer(os.str());
758   registry.Replay(deserializer);
759 
760   ValidateObjects(
761       deserializer.GetAllObjects(),
762       {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}});
763 }
764 
TEST(RecordReplayTest,InstrumentedBarPtr)765 TEST(RecordReplayTest, InstrumentedBarPtr) {
766   std::string str;
767   llvm::raw_string_ostream os(str);
768 
769   {
770     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
771 
772     InstrumentedBar bar;
773     InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
774 
775     int b = 200;
776     float c = 300.3f;
777     double e = 400.4;
778 
779     foo.A(100);
780     foo.B(b);
781     foo.C(&c);
782     foo.D("bar");
783     InstrumentedFoo::E(e);
784     InstrumentedFoo::F();
785     foo.Validate();
786 
787     bar.SetInstrumentedFoo(foo);
788     bar.SetInstrumentedFoo(&foo);
789     bar.Validate();
790   }
791 
792   TestingRegistry registry;
793   Deserializer deserializer(os.str());
794   registry.Replay(deserializer);
795 
796   ValidateObjects(
797       deserializer.GetAllObjects(),
798       {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}});
799 }
800 
TEST(PassiveReplayTest,InstrumentedFoo)801 TEST(PassiveReplayTest, InstrumentedFoo) {
802   std::string str;
803   llvm::raw_string_ostream os(str);
804 
805   {
806     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
807 
808     int b = 200;
809     float c = 300.3f;
810     double e = 400.4;
811 
812     InstrumentedFoo foo(0);
813     foo.A(100);
814     foo.B(b);
815     foo.C(&c);
816     foo.D("bar");
817     InstrumentedFoo::E(e);
818     InstrumentedFoo::F();
819     foo.Validate();
820 
821     EXPECT_EQ(foo.GetA(), 100);
822     EXPECT_EQ(foo.GetB(), 200);
823     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
824     char buffer[100];
825     foo.GetD(buffer, 100);
826     EXPECT_STREQ(buffer, "bar");
827     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
828     EXPECT_EQ(foo.GetF(), true);
829   }
830 
831   std::string buffer = os.str();
832 
833   {
834     auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
835 
836     int b = 999;
837     float c = 999.9f;
838     double e = 999.9;
839 
840     InstrumentedFoo foo(9);
841     foo.A(999);
842     foo.B(b);
843     foo.C(&c);
844     foo.D("999");
845     InstrumentedFoo::E(e);
846     InstrumentedFoo::F();
847     foo.Validate();
848 
849     EXPECT_EQ(foo.GetA(), 100);
850     EXPECT_EQ(foo.GetB(), 200);
851     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
852     char buffer[100];
853     foo.GetD(buffer, 100);
854     EXPECT_STREQ(buffer, "bar");
855     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
856     EXPECT_EQ(foo.GetF(), true);
857   }
858 }
859 
TEST(PassiveReplayTest,InstrumentedFooInvalid)860 TEST(PassiveReplayTest, InstrumentedFooInvalid) {
861   std::string str;
862   llvm::raw_string_ostream os(str);
863 
864   {
865     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
866 
867     int b = 200;
868     float c = 300.3f;
869     double e = 400.4;
870 
871     InstrumentedFoo foo(0);
872     foo.A(100);
873     foo.B(b);
874     foo.C(&c);
875     foo.D("bar");
876     InstrumentedFoo::E(e);
877     InstrumentedFoo::F();
878     foo.Validate();
879 
880     EXPECT_EQ(foo.GetA(), 100);
881     EXPECT_EQ(foo.GetB(), 200);
882     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
883     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
884     EXPECT_EQ(foo.GetF(), true);
885   }
886 
887   std::string buffer = os.str();
888 
889   {
890     auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
891 
892     int b = 999;
893     float c = 999.9f;
894     double e = 999.9;
895 
896     InstrumentedFoo foo(9);
897     foo.A(999);
898     foo.B(b);
899     foo.C(&c);
900     foo.D("999");
901     InstrumentedFoo::E(e);
902     InstrumentedFoo::F();
903     foo.Validate();
904 
905     EXPECT_EQ(foo.GetA(), 100);
906     // Detect divergence.
907     EXPECT_DEATH(foo.GetA(), "");
908   }
909 }
910 
TEST(PassiveReplayTest,InstrumentedBar)911 TEST(PassiveReplayTest, InstrumentedBar) {
912   std::string str;
913   llvm::raw_string_ostream os(str);
914 
915   {
916     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
917 
918     InstrumentedBar bar;
919     InstrumentedFoo foo = bar.GetInstrumentedFoo();
920 
921     int b = 200;
922     float c = 300.3f;
923     double e = 400.4;
924 
925     foo.A(100);
926     foo.B(b);
927     foo.C(&c);
928     foo.D("bar");
929     InstrumentedFoo::E(e);
930     InstrumentedFoo::F();
931     foo.Validate();
932 
933     EXPECT_EQ(foo.GetA(), 100);
934     EXPECT_EQ(foo.GetB(), 200);
935     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
936     char buffer[100];
937     foo.GetD(buffer, 100);
938     EXPECT_STREQ(buffer, "bar");
939     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
940     EXPECT_EQ(foo.GetF(), true);
941 
942     bar.SetInstrumentedFoo(foo);
943     bar.SetInstrumentedFoo(&foo);
944     bar.Validate();
945   }
946 
947   std::string buffer = os.str();
948 
949   {
950     auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
951 
952     InstrumentedBar bar;
953     InstrumentedFoo foo = bar.GetInstrumentedFoo();
954 
955     int b = 99;
956     float c = 999.9f;
957     double e = 999.9;
958 
959     foo.A(999);
960     foo.B(b);
961     foo.C(&c);
962     foo.D("999");
963     InstrumentedFoo::E(e);
964     InstrumentedFoo::F();
965     foo.Validate();
966 
967     EXPECT_EQ(foo.GetA(), 100);
968     EXPECT_EQ(foo.GetB(), 200);
969     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
970     char buffer[100];
971     foo.GetD(buffer, 100);
972     EXPECT_STREQ(buffer, "bar");
973     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
974     EXPECT_EQ(foo.GetF(), true);
975 
976     bar.SetInstrumentedFoo(foo);
977     bar.SetInstrumentedFoo(&foo);
978     bar.Validate();
979   }
980 }
981 
TEST(PassiveReplayTest,InstrumentedBarRef)982 TEST(PassiveReplayTest, InstrumentedBarRef) {
983   std::string str;
984   llvm::raw_string_ostream os(str);
985 
986   {
987     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
988 
989     InstrumentedBar bar;
990     InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
991 
992     int b = 200;
993     float c = 300.3f;
994     double e = 400.4;
995 
996     foo.A(100);
997     foo.B(b);
998     foo.C(&c);
999     foo.D("bar");
1000     InstrumentedFoo::E(e);
1001     InstrumentedFoo::F();
1002     foo.Validate();
1003 
1004     EXPECT_EQ(foo.GetA(), 100);
1005     EXPECT_EQ(foo.GetB(), 200);
1006     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1007     char buffer[100];
1008     foo.GetD(buffer, 100);
1009     EXPECT_STREQ(buffer, "bar");
1010     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1011     EXPECT_EQ(foo.GetF(), true);
1012 
1013     bar.SetInstrumentedFoo(foo);
1014     bar.SetInstrumentedFoo(&foo);
1015     bar.Validate();
1016   }
1017 
1018   std::string buffer = os.str();
1019 
1020   {
1021     auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
1022 
1023     InstrumentedBar bar;
1024     InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
1025 
1026     int b = 99;
1027     float c = 999.9f;
1028     double e = 999.9;
1029 
1030     foo.A(999);
1031     foo.B(b);
1032     foo.C(&c);
1033     foo.D("999");
1034     InstrumentedFoo::E(e);
1035     InstrumentedFoo::F();
1036     foo.Validate();
1037 
1038     EXPECT_EQ(foo.GetA(), 100);
1039     EXPECT_EQ(foo.GetB(), 200);
1040     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1041     char buffer[100];
1042     foo.GetD(buffer, 100);
1043     EXPECT_STREQ(buffer, "bar");
1044     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1045     EXPECT_EQ(foo.GetF(), true);
1046 
1047     bar.SetInstrumentedFoo(foo);
1048     bar.SetInstrumentedFoo(&foo);
1049     bar.Validate();
1050   }
1051 }
1052 
TEST(PassiveReplayTest,InstrumentedBarPtr)1053 TEST(PassiveReplayTest, InstrumentedBarPtr) {
1054   std::string str;
1055   llvm::raw_string_ostream os(str);
1056 
1057   {
1058     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
1059 
1060     InstrumentedBar bar;
1061     InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
1062 
1063     int b = 200;
1064     float c = 300.3f;
1065     double e = 400.4;
1066 
1067     foo.A(100);
1068     foo.B(b);
1069     foo.C(&c);
1070     foo.D("bar");
1071     InstrumentedFoo::E(e);
1072     InstrumentedFoo::F();
1073     foo.Validate();
1074 
1075     EXPECT_EQ(foo.GetA(), 100);
1076     EXPECT_EQ(foo.GetB(), 200);
1077     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1078     char buffer[100];
1079     foo.GetD(buffer, 100);
1080     EXPECT_STREQ(buffer, "bar");
1081     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1082     EXPECT_EQ(foo.GetF(), true);
1083 
1084     bar.SetInstrumentedFoo(foo);
1085     bar.SetInstrumentedFoo(&foo);
1086     bar.Validate();
1087   }
1088 
1089   std::string buffer = os.str();
1090 
1091   {
1092     auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
1093 
1094     InstrumentedBar bar;
1095     InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
1096 
1097     int b = 99;
1098     float c = 999.9f;
1099     double e = 999.9;
1100 
1101     foo.A(999);
1102     foo.B(b);
1103     foo.C(&c);
1104     foo.D("999");
1105     InstrumentedFoo::E(e);
1106     InstrumentedFoo::F();
1107     foo.Validate();
1108 
1109     EXPECT_EQ(foo.GetA(), 100);
1110     EXPECT_EQ(foo.GetB(), 200);
1111     EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1112     char buffer[100];
1113     foo.GetD(buffer, 100);
1114     EXPECT_STREQ(buffer, "bar");
1115     EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1116     EXPECT_EQ(foo.GetF(), true);
1117 
1118     bar.SetInstrumentedFoo(foo);
1119     bar.SetInstrumentedFoo(&foo);
1120     bar.Validate();
1121   }
1122 }
1123 
TEST(RecordReplayTest,ValidSequence)1124 TEST(RecordReplayTest, ValidSequence) {
1125   std::string str;
1126   llvm::raw_string_ostream os(str);
1127 
1128   {
1129     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
1130 
1131     unsigned sequence = 1;
1132     int (*f)() = &lldb_private::repro::invoke<int (*)()>::method<
1133         InstrumentedFoo::F>::record;
1134     unsigned id = g_registry->GetID(uintptr_t(f));
1135     g_serializer->SerializeAll(sequence, id);
1136 
1137     unsigned result = 0;
1138     g_serializer->SerializeAll(sequence, result);
1139   }
1140 
1141   TestingRegistry registry;
1142   Deserializer deserializer(os.str());
1143   registry.Replay(deserializer);
1144 }
1145 
TEST(RecordReplayTest,InvalidSequence)1146 TEST(RecordReplayTest, InvalidSequence) {
1147   std::string str;
1148   llvm::raw_string_ostream os(str);
1149 
1150   {
1151     auto data = TestInstrumentationDataRAII::GetRecordingData(os);
1152 
1153     unsigned sequence = 1;
1154     int (*f)() = &lldb_private::repro::invoke<int (*)()>::method<
1155         InstrumentedFoo::F>::record;
1156     unsigned id = g_registry->GetID(uintptr_t(f));
1157     g_serializer->SerializeAll(sequence, id);
1158 
1159     unsigned result = 0;
1160     unsigned invalid_sequence = 2;
1161     g_serializer->SerializeAll(invalid_sequence, result);
1162   }
1163 
1164   TestingRegistry registry;
1165   Deserializer deserializer(os.str());
1166   EXPECT_DEATH(registry.Replay(deserializer), "");
1167 }
1168