ReproducerInstrumentation.h 41 KB

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