1 //===-- ReproducerInstrumentation.h -----------------------------*- C++ -*-===//
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 
8 #ifndef LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H
9 #define LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H
10 
11 #include "lldb/Utility/FileSpec.h"
12 #include "lldb/Utility/Log.h"
13 #include "lldb/Utility/Logging.h"
14 
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Support/ErrorHandling.h"
18 
19 #include <map>
20 #include <type_traits>
21 
22 template <typename T,
23           typename std::enable_if<std::is_fundamental<T>::value, int>::type = 0>
stringify_append(llvm::raw_string_ostream & ss,const T & t)24 inline void stringify_append(llvm::raw_string_ostream &ss, const T &t) {
25   ss << t;
26 }
27 
28 template <typename T, typename std::enable_if<!std::is_fundamental<T>::value,
29                                               int>::type = 0>
stringify_append(llvm::raw_string_ostream & ss,const T & t)30 inline void stringify_append(llvm::raw_string_ostream &ss, const T &t) {
31   ss << &t;
32 }
33 
34 template <typename T>
stringify_append(llvm::raw_string_ostream & ss,T * t)35 inline void stringify_append(llvm::raw_string_ostream &ss, T *t) {
36   ss << reinterpret_cast<void *>(t);
37 }
38 
39 template <typename T>
stringify_append(llvm::raw_string_ostream & ss,const T * t)40 inline void stringify_append(llvm::raw_string_ostream &ss, const T *t) {
41   ss << reinterpret_cast<const void *>(t);
42 }
43 
44 template <>
45 inline void stringify_append<char>(llvm::raw_string_ostream &ss,
46                                    const char *t) {
47   ss << '\"' << t << '\"';
48 }
49 
50 template <>
51 inline void stringify_append<std::nullptr_t>(llvm::raw_string_ostream &ss,
52                                              const std::nullptr_t &t) {
53   ss << "\"nullptr\"";
54 }
55 
56 template <typename Head>
stringify_helper(llvm::raw_string_ostream & ss,const Head & head)57 inline void stringify_helper(llvm::raw_string_ostream &ss, const Head &head) {
58   stringify_append(ss, head);
59 }
60 
61 template <typename Head, typename... Tail>
stringify_helper(llvm::raw_string_ostream & ss,const Head & head,const Tail &...tail)62 inline void stringify_helper(llvm::raw_string_ostream &ss, const Head &head,
63                              const Tail &... tail) {
64   stringify_append(ss, head);
65   ss << ", ";
66   stringify_helper(ss, tail...);
67 }
68 
stringify_args(const Ts &...ts)69 template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
70   std::string buffer;
71   llvm::raw_string_ostream ss(buffer);
72   stringify_helper(ss, ts...);
73   return ss.str();
74 }
75 
76 // Define LLDB_REPRO_INSTR_TRACE to trace to stderr instead of LLDB's log
77 // infrastructure. This is useful when you need to see traces before the logger
78 // is initialized or enabled.
79 // #define LLDB_REPRO_INSTR_TRACE
80 
81 #define LLDB_REGISTER_CONSTRUCTOR(Class, Signature)                            \
82   R.Register<Class * Signature>(&construct<Class Signature>::record, "",       \
83                                 #Class, #Class, #Signature)
84 
85 #define LLDB_REGISTER_METHOD(Result, Class, Method, Signature)                 \
86   R.Register(                                                                  \
87       &invoke<Result(Class::*) Signature>::method<(&Class::Method)>::record,   \
88       #Result, #Class, #Method, #Signature)
89 
90 #define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature)           \
91   R.Register(&invoke<Result(Class::*)                                          \
92                          Signature const>::method<(&Class::Method)>::record,   \
93              #Result, #Class, #Method, #Signature)
94 
95 #define LLDB_REGISTER_STATIC_METHOD(Result, Class, Method, Signature)          \
96   R.Register(&invoke<Result(*) Signature>::method<(&Class::Method)>::record,   \
97              #Result, #Class, #Method, #Signature)
98 
99 #define LLDB_REGISTER_CHAR_PTR_METHOD_STATIC(Result, Class, Method)            \
100   R.Register(                                                                  \
101       &invoke<Result (*)(char *, size_t)>::method<(&Class::Method)>::record,   \
102       &invoke_char_ptr<Result (*)(char *,                                      \
103                                   size_t)>::method<(&Class::Method)>::record,  \
104       #Result, #Class, #Method, "(char*, size_t");
105 
106 #define LLDB_REGISTER_CHAR_PTR_METHOD(Result, Class, Method)                   \
107   R.Register(&invoke<Result (Class::*)(char *, size_t)>::method<(              \
108                  &Class::Method)>::record,                                     \
109              &invoke_char_ptr<Result (Class::*)(char *, size_t)>::method<(     \
110                  &Class::Method)>::record,                                     \
111              #Result, #Class, #Method, "(char*, size_t");
112 
113 #define LLDB_REGISTER_CHAR_PTR_METHOD_CONST(Result, Class, Method)             \
114   R.Register(&invoke<Result (Class::*)(char *, size_t)                         \
115                          const>::method<(&Class::Method)>::record,             \
116              &invoke_char_ptr<Result (Class::*)(char *, size_t)                \
117                                   const>::method<(&Class::Method)>::record,    \
118              #Result, #Class, #Method, "(char*, size_t");
119 
120 #define LLDB_CONSTRUCT_(T, Class, ...)                                         \
121   lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION);               \
122   lldb_private::repro::construct<T>::handle(LLDB_GET_INSTRUMENTATION_DATA(),   \
123                                             _recorder, Class, __VA_ARGS__);
124 
125 #define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...)                         \
126   LLDB_CONSTRUCT_(Class Signature, this, __VA_ARGS__)
127 
128 #define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class)                                 \
129   LLDB_CONSTRUCT_(Class(), this, lldb_private::repro::EmptyArg())
130 
131 #define LLDB_RECORD_(T1, T2, ...)                                              \
132   lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION,                \
133                                           stringify_args(__VA_ARGS__));        \
134   if (lldb_private::repro::InstrumentationData _data =                         \
135           LLDB_GET_INSTRUMENTATION_DATA()) {                                   \
136     if (lldb_private::repro::Serializer *_serializer =                         \
137             _data.GetSerializer()) {                                           \
138       _recorder.Record(*_serializer, _data.GetRegistry(),                      \
139                        &lldb_private::repro::invoke<T1>::method<T2>::record,   \
140                        __VA_ARGS__);                                           \
141     } else if (lldb_private::repro::Deserializer *_deserializer =              \
142                    _data.GetDeserializer()) {                                  \
143       if (_recorder.ShouldCapture()) {                                         \
144         return lldb_private::repro::invoke<T1>::method<T2>::replay(            \
145             _recorder, *_deserializer, _data.GetRegistry());                   \
146       }                                                                        \
147     }                                                                          \
148   }
149 
150 #define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...)              \
151   LLDB_RECORD_(Result(Class::*) Signature, (&Class::Method), this, __VA_ARGS__)
152 
153 #define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...)        \
154   LLDB_RECORD_(Result(Class::*) Signature const, (&Class::Method), this,       \
155                __VA_ARGS__)
156 
157 #define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method)                      \
158   LLDB_RECORD_(Result (Class::*)(), (&Class::Method), this)
159 
160 #define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method)                \
161   LLDB_RECORD_(Result (Class::*)() const, (&Class::Method), this)
162 
163 #define LLDB_RECORD_STATIC_METHOD(Result, Class, Method, Signature, ...)       \
164   LLDB_RECORD_(Result(*) Signature, (&Class::Method), __VA_ARGS__)
165 
166 #define LLDB_RECORD_STATIC_METHOD_NO_ARGS(Result, Class, Method)               \
167   LLDB_RECORD_(Result (*)(), (&Class::Method), lldb_private::repro::EmptyArg())
168 
169 #define LLDB_RECORD_CHAR_PTR_(T1, T2, StrOut, ...)                             \
170   lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION,                \
171                                           stringify_args(__VA_ARGS__));        \
172   if (lldb_private::repro::InstrumentationData _data =                         \
173           LLDB_GET_INSTRUMENTATION_DATA()) {                                   \
174     if (lldb_private::repro::Serializer *_serializer =                         \
175             _data.GetSerializer()) {                                           \
176       _recorder.Record(*_serializer, _data.GetRegistry(),                      \
177                        &lldb_private::repro::invoke<T1>::method<(T2)>::record, \
178                        __VA_ARGS__);                                           \
179     } else if (lldb_private::repro::Deserializer *_deserializer =              \
180                    _data.GetDeserializer()) {                                  \
181       if (_recorder.ShouldCapture()) {                                         \
182         return lldb_private::repro::invoke_char_ptr<T1>::method<T2>::replay(   \
183             _recorder, *_deserializer, _data.GetRegistry(), StrOut);           \
184       }                                                                        \
185     }                                                                          \
186   }
187 
188 #define LLDB_RECORD_CHAR_PTR_METHOD(Result, Class, Method, Signature, StrOut,  \
189                                     ...)                                       \
190   LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature, (&Class::Method), StrOut,  \
191                         this, __VA_ARGS__)
192 
193 #define LLDB_RECORD_CHAR_PTR_METHOD_CONST(Result, Class, Method, Signature,    \
194                                           StrOut, ...)                         \
195   LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature const, (&Class::Method),    \
196                         StrOut, this, __VA_ARGS__)
197 
198 #define LLDB_RECORD_CHAR_PTR_STATIC_METHOD(Result, Class, Method, Signature,   \
199                                            StrOut, ...)                        \
200   LLDB_RECORD_CHAR_PTR_(Result(*) Signature, (&Class::Method), StrOut,         \
201                         __VA_ARGS__)
202 
203 #define LLDB_RECORD_RESULT(Result) _recorder.RecordResult(Result, true);
204 
205 /// The LLDB_RECORD_DUMMY macro is special because it doesn't actually record
206 /// anything. It's used to track API boundaries when we cannot record for
207 /// technical reasons.
208 #define LLDB_RECORD_DUMMY(Result, Class, Method, Signature, ...)               \
209   lldb_private::repro::Recorder _recorder;
210 
211 #define LLDB_RECORD_DUMMY_NO_ARGS(Result, Class, Method)                       \
212   lldb_private::repro::Recorder _recorder;
213 
214 namespace lldb_private {
215 namespace repro {
216 
217 template <class T>
218 struct is_trivially_serializable
219     : std::integral_constant<bool, std::is_fundamental<T>::value ||
220                                        std::is_enum<T>::value> {};
221 
222 /// Mapping between serialized indices and their corresponding objects.
223 ///
224 /// This class is used during replay to map indices back to in-memory objects.
225 ///
226 /// When objects are constructed, they are added to this mapping using
227 /// AddObjectForIndex.
228 ///
229 /// When an object is passed to a function, its index is deserialized and
230 /// AddObjectForIndex returns the corresponding object. If there is no object
231 /// for the given index, a nullptr is returend. The latter is valid when custom
232 /// replay code is in place and the actual object is ignored.
233 class IndexToObject {
234 public:
235   /// Returns an object as a pointer for the given index or nullptr if not
236   /// present in the map.
GetObjectForIndex(unsigned idx)237   template <typename T> T *GetObjectForIndex(unsigned idx) {
238     assert(idx != 0 && "Cannot get object for sentinel");
239     void *object = GetObjectForIndexImpl(idx);
240     return static_cast<T *>(object);
241   }
242 
243   /// Adds a pointer to an object to the mapping for the given index.
AddObjectForIndex(unsigned idx,T * object)244   template <typename T> T *AddObjectForIndex(unsigned idx, T *object) {
245     AddObjectForIndexImpl(
246         idx, static_cast<void *>(
247                  const_cast<typename std::remove_const<T>::type *>(object)));
248     return object;
249   }
250 
251   /// Adds a reference to an object to the mapping for the given index.
AddObjectForIndex(unsigned idx,T & object)252   template <typename T> T &AddObjectForIndex(unsigned idx, T &object) {
253     AddObjectForIndexImpl(
254         idx, static_cast<void *>(
255                  const_cast<typename std::remove_const<T>::type *>(&object)));
256     return object;
257   }
258 
259   /// Get all objects sorted by their index.
260   std::vector<void *> GetAllObjects() const;
261 
262 private:
263   /// Helper method that does the actual lookup. The void* result is later cast
264   /// by the caller.
265   void *GetObjectForIndexImpl(unsigned idx);
266 
267   /// Helper method that does the actual insertion.
268   void AddObjectForIndexImpl(unsigned idx, void *object);
269 
270   /// Keeps a mapping between indices and their corresponding object.
271   llvm::DenseMap<unsigned, void *> m_mapping;
272 };
273 
274 /// We need to differentiate between pointers to fundamental and
275 /// non-fundamental types. See the corresponding Deserializer::Read method
276 /// for the reason why.
277 struct PointerTag {};
278 struct ReferenceTag {};
279 struct ValueTag {};
280 struct FundamentalPointerTag {};
281 struct FundamentalReferenceTag {};
282 
283 /// Return the deserialization tag for the given type T.
284 template <class T> struct serializer_tag {
285   typedef typename std::conditional<std::is_trivially_copyable<T>::value,
286                                     ValueTag, ReferenceTag>::type type;
287 };
288 template <class T> struct serializer_tag<T *> {
289   typedef
290       typename std::conditional<std::is_fundamental<T>::value,
291                                 FundamentalPointerTag, PointerTag>::type type;
292 };
293 template <class T> struct serializer_tag<T &> {
294   typedef typename std::conditional<std::is_fundamental<T>::value,
295                                     FundamentalReferenceTag, ReferenceTag>::type
296       type;
297 };
298 
299 /// Deserializes data from a buffer. It is used to deserialize function indices
300 /// to replay, their arguments and return values.
301 ///
302 /// Fundamental types and strings are read by value. Objects are read by their
303 /// index, which get translated by the IndexToObject mapping maintained in
304 /// this class.
305 ///
306 /// Additional bookkeeping with regards to the IndexToObject is required to
307 /// deserialize objects. When a constructor is run or an object is returned by
308 /// value, we need to capture the object and add it to the index together with
309 /// its index. This is the job of HandleReplayResult(Void).
310 class Deserializer {
311 public:
312   Deserializer(llvm::StringRef buffer) : m_buffer(buffer) {}
313 
314   /// Returns true when the buffer has unread data.
315   bool HasData(unsigned size) { return size <= m_buffer.size(); }
316 
317   /// Deserialize and interpret value as T.
318   template <typename T> T Deserialize() {
319     T t = Read<T>(typename serializer_tag<T>::type());
320 #ifdef LLDB_REPRO_INSTR_TRACE
321     llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> "
322                  << stringify_args(t) << "\n";
323 #endif
324     return t;
325   }
326 
327   template <typename T> const T &HandleReplayResult(const T &t) {
328     unsigned result = Deserialize<unsigned>();
329     if (is_trivially_serializable<T>::value)
330       return t;
331     // We need to make a copy as the original object might go out of scope.
332     return *m_index_to_object.AddObjectForIndex(result, new T(t));
333   }
334 
335   /// Store the returned value in the index-to-object mapping.
336   template <typename T> T &HandleReplayResult(T &t) {
337     unsigned result = Deserialize<unsigned>();
338     if (is_trivially_serializable<T>::value)
339       return t;
340     // We need to make a copy as the original object might go out of scope.
341     return *m_index_to_object.AddObjectForIndex(result, new T(t));
342   }
343 
344   /// Store the returned value in the index-to-object mapping.
345   template <typename T> T *HandleReplayResult(T *t) {
346     unsigned result = Deserialize<unsigned>();
347     if (is_trivially_serializable<T>::value)
348       return t;
349     return m_index_to_object.AddObjectForIndex(result, t);
350   }
351 
352   /// All returned types are recorded, even when the function returns a void.
353   /// The latter requires special handling.
354   void HandleReplayResultVoid() {
355     unsigned result = Deserialize<unsigned>();
356     assert(result == 0);
357     (void)result;
358   }
359 
360   std::vector<void *> GetAllObjects() const {
361     return m_index_to_object.GetAllObjects();
362   }
363 
364 private:
365   template <typename T> T Read(ValueTag) {
366     assert(HasData(sizeof(T)));
367     T t;
368     std::memcpy(reinterpret_cast<char *>(&t), m_buffer.data(), sizeof(T));
369     m_buffer = m_buffer.drop_front(sizeof(T));
370     return t;
371   }
372 
373   template <typename T> T Read(PointerTag) {
374     typedef typename std::remove_pointer<T>::type UnderlyingT;
375     return m_index_to_object.template GetObjectForIndex<UnderlyingT>(
376         Deserialize<unsigned>());
377   }
378 
379   template <typename T> T Read(ReferenceTag) {
380     typedef typename std::remove_reference<T>::type UnderlyingT;
381     // If this is a reference to a fundamental type we just read its value.
382     return *m_index_to_object.template GetObjectForIndex<UnderlyingT>(
383         Deserialize<unsigned>());
384   }
385 
386   /// This method is used to parse references to fundamental types. Because
387   /// they're not recorded in the object table we have serialized their value.
388   /// We read its value, allocate a copy on the heap, and return a pointer to
389   /// the copy.
390   template <typename T> T Read(FundamentalPointerTag) {
391     typedef typename std::remove_pointer<T>::type UnderlyingT;
392     return new UnderlyingT(Deserialize<UnderlyingT>());
393   }
394 
395   /// This method is used to parse references to fundamental types. Because
396   /// they're not recorded in the object table we have serialized their value.
397   /// We read its value, allocate a copy on the heap, and return a reference to
398   /// the copy.
399   template <typename T> T Read(FundamentalReferenceTag) {
400     // If this is a reference to a fundamental type we just read its value.
401     typedef typename std::remove_reference<T>::type UnderlyingT;
402     return *(new UnderlyingT(Deserialize<UnderlyingT>()));
403   }
404 
405   /// Mapping of indices to objects.
406   IndexToObject m_index_to_object;
407 
408   /// Buffer containing the serialized data.
409   llvm::StringRef m_buffer;
410 };
411 
412 /// Partial specialization for C-style strings. We read the string value
413 /// instead of treating it as pointer.
414 template <> const char *Deserializer::Deserialize<const char *>();
415 template <> const char **Deserializer::Deserialize<const char **>();
416 template <> const uint8_t *Deserializer::Deserialize<const uint8_t *>();
417 template <> const void *Deserializer::Deserialize<const void *>();
418 template <> char *Deserializer::Deserialize<char *>();
419 template <> void *Deserializer::Deserialize<void *>();
420 
421 /// Helpers to auto-synthesize function replay code. It deserializes the replay
422 /// function's arguments one by one and finally calls the corresponding
423 /// function.
424 template <typename... Remaining> struct DeserializationHelper;
425 
426 template <typename Head, typename... Tail>
427 struct DeserializationHelper<Head, Tail...> {
428   template <typename Result, typename... Deserialized> struct deserialized {
429     static Result doit(Deserializer &deserializer,
430                        Result (*f)(Deserialized..., Head, Tail...),
431                        Deserialized... d) {
432       return DeserializationHelper<Tail...>::
433           template deserialized<Result, Deserialized..., Head>::doit(
434               deserializer, f, d..., deserializer.Deserialize<Head>());
435     }
436   };
437 };
438 
439 template <> struct DeserializationHelper<> {
440   template <typename Result, typename... Deserialized> struct deserialized {
441     static Result doit(Deserializer &deserializer, Result (*f)(Deserialized...),
442                        Deserialized... d) {
443       return f(d...);
444     }
445   };
446 };
447 
448 /// The replayer interface.
449 struct Replayer {
450   virtual ~Replayer() {}
451   virtual void operator()(Deserializer &deserializer) const = 0;
452 };
453 
454 /// The default replayer deserializes the arguments and calls the function.
455 template <typename Signature> struct DefaultReplayer;
456 template <typename Result, typename... Args>
457 struct DefaultReplayer<Result(Args...)> : public Replayer {
458   DefaultReplayer(Result (*f)(Args...)) : Replayer(), f(f) {}
459 
460   void operator()(Deserializer &deserializer) const override {
461     Replay(deserializer);
462   }
463 
464   Result Replay(Deserializer &deserializer) const {
465     return deserializer.HandleReplayResult(
466         DeserializationHelper<Args...>::template deserialized<Result>::doit(
467             deserializer, f));
468   }
469 
470   Result (*f)(Args...);
471 };
472 
473 /// Partial specialization for function returning a void type. It ignores the
474 /// (absent) return value.
475 template <typename... Args>
476 struct DefaultReplayer<void(Args...)> : public Replayer {
477   DefaultReplayer(void (*f)(Args...)) : Replayer(), f(f) {}
478 
479   void operator()(Deserializer &deserializer) const override {
480     Replay(deserializer);
481   }
482 
483   void Replay(Deserializer &deserializer) const {
484     DeserializationHelper<Args...>::template deserialized<void>::doit(
485         deserializer, f);
486     deserializer.HandleReplayResultVoid();
487   }
488 
489   void (*f)(Args...);
490 };
491 
492 /// The registry contains a unique mapping between functions and their ID. The
493 /// IDs can be serialized and deserialized to replay a function. Functions need
494 /// to be registered with the registry for this to work.
495 class Registry {
496 private:
497   struct SignatureStr {
498     SignatureStr(llvm::StringRef result = {}, llvm::StringRef scope = {},
499                  llvm::StringRef name = {}, llvm::StringRef args = {})
500         : result(result), scope(scope), name(name), args(args) {}
501 
502     std::string ToString() const;
503 
504     llvm::StringRef result;
505     llvm::StringRef scope;
506     llvm::StringRef name;
507     llvm::StringRef args;
508   };
509 
510 public:
511   Registry() = default;
512   virtual ~Registry() = default;
513 
514   /// Register a default replayer for a function.
515   template <typename Signature>
516   void Register(Signature *f, llvm::StringRef result = {},
517                 llvm::StringRef scope = {}, llvm::StringRef name = {},
518                 llvm::StringRef args = {}) {
519     DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(f),
520                SignatureStr(result, scope, name, args));
521   }
522 
523   /// Register a replayer that invokes a custom function with the same
524   /// signature as the replayed function.
525   template <typename Signature>
526   void Register(Signature *f, Signature *g, llvm::StringRef result = {},
527                 llvm::StringRef scope = {}, llvm::StringRef name = {},
528                 llvm::StringRef args = {}) {
529     DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(g),
530                SignatureStr(result, scope, name, args));
531   }
532 
533   /// Replay functions from a file.
534   bool Replay(const FileSpec &file);
535 
536   /// Replay functions from a buffer.
537   bool Replay(llvm::StringRef buffer);
538 
539   /// Replay functions from a deserializer.
540   bool Replay(Deserializer &deserializer);
541 
542   /// Returns the ID for a given function address.
543   unsigned GetID(uintptr_t addr);
544 
545   /// Get the replayer matching the given ID.
546   Replayer *GetReplayer(unsigned id);
547 
548   std::string GetSignature(unsigned id);
549 
550   void CheckID(unsigned expected, unsigned actual);
551 
552 protected:
553   /// Register the given replayer for a function (and the ID mapping).
554   void DoRegister(uintptr_t RunID, std::unique_ptr<Replayer> replayer,
555                   SignatureStr signature);
556 
557 private:
558   /// Mapping of function addresses to replayers and their ID.
559   std::map<uintptr_t, std::pair<std::unique_ptr<Replayer>, unsigned>>
560       m_replayers;
561 
562   /// Mapping of IDs to replayer instances.
563   std::map<unsigned, std::pair<Replayer *, SignatureStr>> m_ids;
564 };
565 
566 /// Maps an object to an index for serialization. Indices are unique and
567 /// incremented for every new object.
568 ///
569 /// Indices start at 1 in order to differentiate with an invalid index (0) in
570 /// the serialized buffer.
571 class ObjectToIndex {
572 public:
573   template <typename T> unsigned GetIndexForObject(T *t) {
574     return GetIndexForObjectImpl(static_cast<const void *>(t));
575   }
576 
577 private:
578   unsigned GetIndexForObjectImpl(const void *object);
579 
580   llvm::DenseMap<const void *, unsigned> m_mapping;
581 };
582 
583 /// Serializes functions, their arguments and their return type to a stream.
584 class Serializer {
585 public:
586   Serializer(llvm::raw_ostream &stream = llvm::outs()) : m_stream(stream) {}
587 
588   /// Recursively serialize all the given arguments.
589   template <typename Head, typename... Tail>
590   void SerializeAll(const Head &head, const Tail &... tail) {
591     Serialize(head);
592     SerializeAll(tail...);
593   }
594 
595   void SerializeAll() { m_stream.flush(); }
596 
597 private:
598   /// Serialize pointers. We need to differentiate between pointers to
599   /// fundamental types (in which case we serialize its value) and pointer to
600   /// objects (in which case we serialize their index).
601   template <typename T> void Serialize(T *t) {
602 #ifdef LLDB_REPRO_INSTR_TRACE
603     llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
604                  << stringify_args(t) << "\n";
605 #endif
606     if (std::is_fundamental<T>::value) {
607       Serialize(*t);
608     } else {
609       unsigned idx = m_tracker.GetIndexForObject(t);
610       Serialize(idx);
611     }
612   }
613 
614   /// Serialize references. We need to differentiate between references to
615   /// fundamental types (in which case we serialize its value) and references
616   /// to objects (in which case we serialize their index).
617   template <typename T> void Serialize(T &t) {
618 #ifdef LLDB_REPRO_INSTR_TRACE
619     llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
620                  << stringify_args(t) << "\n";
621 #endif
622     if (is_trivially_serializable<T>::value) {
623       m_stream.write(reinterpret_cast<const char *>(&t), sizeof(T));
624     } else {
625       unsigned idx = m_tracker.GetIndexForObject(&t);
626       Serialize(idx);
627     }
628   }
629 
630   void Serialize(const void *v) {
631     // FIXME: Support void*
632   }
633 
634   void Serialize(void *v) {
635     // FIXME: Support void*
636   }
637 
638   void Serialize(const char *t) {
639 #ifdef LLDB_REPRO_INSTR_TRACE
640     llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
641                  << stringify_args(t) << "\n";
642 #endif
643     const size_t size = t ? strlen(t) : std::numeric_limits<size_t>::max();
644     Serialize(size);
645     if (t) {
646       m_stream << t;
647       m_stream.write(0x0);
648     }
649   }
650 
651   void Serialize(const char **t) {
652     size_t size = 0;
653     if (!t) {
654       Serialize(size);
655       return;
656     }
657 
658     // Compute the size of the array.
659     const char *const *temp = t;
660     while (*temp++)
661       size++;
662     Serialize(size);
663 
664     // Serialize the content of the array.
665     while (*t)
666       Serialize(*t++);
667   }
668 
669   /// Serialization stream.
670   llvm::raw_ostream &m_stream;
671 
672   /// Mapping of objects to indices.
673   ObjectToIndex m_tracker;
674 }; // namespace repro
675 
676 class InstrumentationData {
677 public:
678   Serializer *GetSerializer() { return m_serializer; }
679   Deserializer *GetDeserializer() { return m_deserializer; }
680   Registry &GetRegistry() { return *m_registry; }
681 
682   operator bool() {
683     return (m_serializer != nullptr || m_deserializer != nullptr) &&
684            m_registry != nullptr;
685   }
686 
687   static void Initialize(Serializer &serializer, Registry &registry);
688   static void Initialize(Deserializer &serializer, Registry &registry);
689   static InstrumentationData &Instance();
690 
691 protected:
692   friend llvm::optional_detail::OptionalStorage<InstrumentationData, true>;
693   friend llvm::Optional<InstrumentationData>;
694 
695   InstrumentationData()
696       : m_serializer(nullptr), m_deserializer(nullptr), m_registry(nullptr) {}
697   InstrumentationData(Serializer &serializer, Registry &registry)
698       : m_serializer(&serializer), m_deserializer(nullptr),
699         m_registry(&registry) {}
700   InstrumentationData(Deserializer &deserializer, Registry &registry)
701       : m_serializer(nullptr), m_deserializer(&deserializer),
702         m_registry(&registry) {}
703 
704 private:
705   static llvm::Optional<InstrumentationData> &InstanceImpl();
706 
707   Serializer *m_serializer;
708   Deserializer *m_deserializer;
709   Registry *m_registry;
710 };
711 
712 struct EmptyArg {};
713 
714 /// RAII object that records function invocations and their return value.
715 ///
716 /// API calls are only captured when the API boundary is crossed. Once we're in
717 /// the API layer, and another API function is called, it doesn't need to be
718 /// recorded.
719 ///
720 /// When a call is recored, its result is always recorded as well, even if the
721 /// function returns a void. For functions that return by value, RecordResult
722 /// should be used. Otherwise a sentinel value (0) will be serialized.
723 ///
724 /// Because of the functional overlap between logging and recording API calls,
725 /// this class is also used for logging.
726 class Recorder {
727 public:
728   Recorder();
729   Recorder(llvm::StringRef pretty_func, std::string &&pretty_args = {});
730   ~Recorder();
731 
732   /// Records a single function call.
733   template <typename Result, typename... FArgs, typename... RArgs>
734   void Record(Serializer &serializer, Registry &registry, Result (*f)(FArgs...),
735               const RArgs &... args) {
736     m_serializer = &serializer;
737     if (!ShouldCapture())
738       return;
739 
740     unsigned id = registry.GetID(uintptr_t(f));
741 
742 #ifdef LLDB_REPRO_INSTR_TRACE
743     Log(id);
744 #endif
745 
746     serializer.SerializeAll(id);
747     serializer.SerializeAll(args...);
748 
749     if (std::is_class<typename std::remove_pointer<
750             typename std::remove_reference<Result>::type>::type>::value) {
751       m_result_recorded = false;
752     } else {
753       serializer.SerializeAll(0);
754       m_result_recorded = true;
755     }
756   }
757 
758   /// Records a single function call.
759   template <typename... Args>
760   void Record(Serializer &serializer, Registry &registry, void (*f)(Args...),
761               const Args &... args) {
762     m_serializer = &serializer;
763     if (!ShouldCapture())
764       return;
765 
766     unsigned id = registry.GetID(uintptr_t(f));
767 
768 #ifdef LLDB_REPRO_INSTR_TRACE
769     Log(id);
770 #endif
771 
772     serializer.SerializeAll(id);
773     serializer.SerializeAll(args...);
774 
775     // Record result.
776     serializer.SerializeAll(0);
777     m_result_recorded = true;
778   }
779 
780   /// Specializations for the no-argument methods. These are passed an empty
781   /// dummy argument so the same variadic macro can be used. These methods
782   /// strip the arguments before forwarding them.
783   template <typename Result>
784   void Record(Serializer &serializer, Registry &registry, Result (*f)(),
785               const EmptyArg &arg) {
786     Record(serializer, registry, f);
787   }
788 
789   /// Record the result of a function call.
790   template <typename Result>
791   Result RecordResult(Result &&r, bool update_boundary) {
792     // When recording the result from the LLDB_RECORD_RESULT macro, we need to
793     // update the boundary so we capture the copy constructor. However, when
794     // called to record the this pointer of the (copy) constructor, the
795     // boundary should not be toggled, because it is called from the
796     // LLDB_RECORD_CONSTRUCTOR macro, which might be followed by other API
797     // calls.
798     if (update_boundary)
799       UpdateBoundary();
800     if (m_serializer && ShouldCapture()) {
801       assert(!m_result_recorded);
802       m_serializer->SerializeAll(r);
803       m_result_recorded = true;
804     }
805     return std::forward<Result>(r);
806   }
807 
808   template <typename Result, typename T>
809   Result Replay(Deserializer &deserializer, Registry &registry, uintptr_t addr,
810                 bool update_boundary) {
811     unsigned actual_id = registry.GetID(addr);
812     unsigned id = deserializer.Deserialize<unsigned>();
813     registry.CheckID(id, actual_id);
814     return ReplayResult<Result>(
815         static_cast<DefaultReplayer<T> *>(registry.GetReplayer(id))
816             ->Replay(deserializer),
817         update_boundary);
818   }
819 
820   void Replay(Deserializer &deserializer, Registry &registry, uintptr_t addr) {
821     unsigned actual_id = registry.GetID(addr);
822     unsigned id = deserializer.Deserialize<unsigned>();
823     registry.CheckID(id, actual_id);
824     registry.GetReplayer(id)->operator()(deserializer);
825   }
826 
827   template <typename Result>
828   Result ReplayResult(Result &&r, bool update_boundary) {
829     if (update_boundary)
830       UpdateBoundary();
831     return std::forward<Result>(r);
832   }
833 
834   bool ShouldCapture() { return m_local_boundary; }
835 
836 private:
837   template <typename T> friend struct replay;
838   void UpdateBoundary() {
839     if (m_local_boundary)
840       g_global_boundary = false;
841   }
842 
843 #ifdef LLDB_REPRO_INSTR_TRACE
844   void Log(unsigned id) {
845     llvm::errs() << "Recording " << id << ": " << m_pretty_func << " ("
846                  << m_pretty_args << ")\n";
847   }
848 #endif
849 
850   Serializer *m_serializer;
851 
852   /// Pretty function for logging.
853   llvm::StringRef m_pretty_func;
854   std::string m_pretty_args;
855 
856   /// Whether this function call was the one crossing the API boundary.
857   bool m_local_boundary;
858 
859   /// Whether the return value was recorded explicitly.
860   bool m_result_recorded;
861 
862   /// Whether we're currently across the API boundary.
863   static bool g_global_boundary;
864 };
865 
866 /// To be used as the "Runtime ID" of a constructor. It also invokes the
867 /// constructor when called.
868 template <typename Signature> struct construct;
869 template <typename Class, typename... Args> struct construct<Class(Args...)> {
870   static Class *handle(lldb_private::repro::InstrumentationData data,
871                        lldb_private::repro::Recorder &recorder, Class *c,
872                        const EmptyArg &) {
873     return handle(data, recorder, c);
874   }
875 
876   static Class *handle(lldb_private::repro::InstrumentationData data,
877                        lldb_private::repro::Recorder &recorder, Class *c,
878                        Args... args) {
879     if (!data)
880       return nullptr;
881 
882     if (Serializer *serializer = data.GetSerializer()) {
883       recorder.Record(*serializer, data.GetRegistry(), &record, args...);
884       recorder.RecordResult(c, false);
885     } else if (Deserializer *deserializer = data.GetDeserializer()) {
886       if (recorder.ShouldCapture()) {
887         replay(recorder, *deserializer, data.GetRegistry());
888       }
889     }
890 
891     return nullptr;
892   }
893 
894   static Class *record(Args... args) { return new Class(args...); }
895 
896   static Class *replay(Recorder &recorder, Deserializer &deserializer,
897                        Registry &registry) {
898     return recorder.Replay<Class *, Class *(Args...)>(
899         deserializer, registry, uintptr_t(&record), false);
900   }
901 };
902 
903 /// To be used as the "Runtime ID" of a member function. It also invokes the
904 /// member function when called.
905 template <typename Signature> struct invoke;
906 template <typename Result, typename Class, typename... Args>
907 struct invoke<Result (Class::*)(Args...)> {
908   template <Result (Class::*m)(Args...)> struct method {
909     static Result record(Class *c, Args... args) { return (c->*m)(args...); }
910 
911     static Result replay(Recorder &recorder, Deserializer &deserializer,
912                          Registry &registry) {
913       return recorder.Replay<Result, Result(Class *, Args...)>(
914           deserializer, registry, uintptr_t(&record), true);
915     }
916   };
917 };
918 
919 template <typename Class, typename... Args>
920 struct invoke<void (Class::*)(Args...)> {
921   template <void (Class::*m)(Args...)> struct method {
922     static void record(Class *c, Args... args) { (c->*m)(args...); }
923     static void replay(Recorder &recorder, Deserializer &deserializer,
924                        Registry &registry) {
925       recorder.Replay(deserializer, registry, uintptr_t(&record));
926     }
927   };
928 };
929 
930 template <typename Result, typename Class, typename... Args>
931 struct invoke<Result (Class::*)(Args...) const> {
932   template <Result (Class::*m)(Args...) const> struct method {
933     static Result record(Class *c, Args... args) { return (c->*m)(args...); }
934     static Result replay(Recorder &recorder, Deserializer &deserializer,
935                          Registry &registry) {
936       return recorder.Replay<Result, Result(Class *, Args...)>(
937           deserializer, registry, uintptr_t(&record), true);
938     }
939   };
940 };
941 
942 template <typename Class, typename... Args>
943 struct invoke<void (Class::*)(Args...) const> {
944   template <void (Class::*m)(Args...) const> struct method {
945     static void record(Class *c, Args... args) { return (c->*m)(args...); }
946     static void replay(Recorder &recorder, Deserializer &deserializer,
947                        Registry &registry) {
948       recorder.Replay(deserializer, registry, uintptr_t(&record));
949     }
950   };
951 };
952 
953 template <typename Signature> struct replay;
954 
955 template <typename Result, typename Class, typename... Args>
956 struct replay<Result (Class::*)(Args...)> {
957   template <Result (Class::*m)(Args...)> struct method {};
958 };
959 
960 template <typename Result, typename... Args>
961 struct invoke<Result (*)(Args...)> {
962   template <Result (*m)(Args...)> struct method {
963     static Result record(Args... args) { return (*m)(args...); }
964     static Result replay(Recorder &recorder, Deserializer &deserializer,
965                          Registry &registry) {
966       return recorder.Replay<Result, Result(Args...)>(deserializer, registry,
967                                                       uintptr_t(&record), true);
968     }
969   };
970 };
971 
972 template <typename... Args> struct invoke<void (*)(Args...)> {
973   template <void (*m)(Args...)> struct method {
974     static void record(Args... args) { return (*m)(args...); }
975     static void replay(Recorder &recorder, Deserializer &deserializer,
976                        Registry &registry) {
977       recorder.Replay(deserializer, registry, uintptr_t(&record));
978     }
979   };
980 };
981 
982 /// Special handling for functions returning strings as (char*, size_t).
983 /// {
984 
985 /// For inline replay, we ignore the arguments and use the ones from the
986 /// serializer instead. This doesn't work for methods that use a char* and a
987 /// size to return a string. For one these functions have a custom replayer to
988 /// prevent override the input buffer. Furthermore, the template-generated
989 /// deserialization is not easy to hook into.
990 ///
991 /// The specializations below hand-implement the serialization logic for the
992 /// inline replay. Instead of using the function from the registry, it uses the
993 /// one passed into the macro.
994 template <typename Signature> struct invoke_char_ptr;
995 template <typename Result, typename Class, typename... Args>
996 struct invoke_char_ptr<Result (Class::*)(Args...) const> {
997   template <Result (Class::*m)(Args...) const> struct method {
998     static Result record(Class *c, char *s, size_t l) {
999       char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
1000       return (c->*m)(buffer, l);
1001     }
1002 
1003     static Result replay(Recorder &recorder, Deserializer &deserializer,
1004                          Registry &registry, char *str) {
1005       deserializer.Deserialize<unsigned>();
1006       Class *c = deserializer.Deserialize<Class *>();
1007       deserializer.Deserialize<const char *>();
1008       size_t l = deserializer.Deserialize<size_t>();
1009       return recorder.ReplayResult(
1010           std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true);
1011     }
1012   };
1013 };
1014 
1015 template <typename Signature> struct invoke_char_ptr;
1016 template <typename Result, typename Class, typename... Args>
1017 struct invoke_char_ptr<Result (Class::*)(Args...)> {
1018   template <Result (Class::*m)(Args...)> struct method {
1019     static Result record(Class *c, char *s, size_t l) {
1020       char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
1021       return (c->*m)(buffer, l);
1022     }
1023 
1024     static Result replay(Recorder &recorder, Deserializer &deserializer,
1025                          Registry &registry, char *str) {
1026       deserializer.Deserialize<unsigned>();
1027       Class *c = deserializer.Deserialize<Class *>();
1028       deserializer.Deserialize<const char *>();
1029       size_t l = deserializer.Deserialize<size_t>();
1030       return recorder.ReplayResult(
1031           std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true);
1032     }
1033   };
1034 };
1035 
1036 template <typename Result, typename... Args>
1037 struct invoke_char_ptr<Result (*)(Args...)> {
1038   template <Result (*m)(Args...)> struct method {
1039     static Result record(char *s, size_t l) {
1040       char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
1041       return (*m)(buffer, l);
1042     }
1043 
1044     static Result replay(Recorder &recorder, Deserializer &deserializer,
1045                          Registry &registry, char *str) {
1046       deserializer.Deserialize<unsigned>();
1047       deserializer.Deserialize<const char *>();
1048       size_t l = deserializer.Deserialize<size_t>();
1049       return recorder.ReplayResult(
1050           std::move(deserializer.HandleReplayResult((*m)(str, l))), true);
1051     }
1052   };
1053 };
1054 /// }
1055 
1056 } // namespace repro
1057 } // namespace lldb_private
1058 
1059 #endif // LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H
1060