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