JDevlieghere created this revision. JDevlieghere added reviewers: labath, davide, aprantl. JDevlieghere added a project: LLDB.
Debugging issues with instrumentation capture and replay can be particularly tricky, especially because part of the process takes places even before the debugger is initialized. This patch adds more logging capabilities to these classes, hidden behind a macro define. Repository: rLLDB LLDB https://reviews.llvm.org/D58566 Files: lldb/include/lldb/Utility/ReproducerInstrumentation.h lldb/source/Utility/ReproducerInstrumentation.cpp
Index: lldb/source/Utility/ReproducerInstrumentation.cpp =================================================================== --- lldb/source/Utility/ReproducerInstrumentation.cpp +++ lldb/source/Utility/ReproducerInstrumentation.cpp @@ -44,22 +44,38 @@ bool Registry::Replay(llvm::StringRef buffer) { Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_API); - Deserializer deserializer(buffer); while (deserializer.HasData(1)) { unsigned id = deserializer.Deserialize<unsigned>(); - LLDB_LOG(log, "Replaying function #{0}", id); +#ifndef LLDB_REPRO_INSTR_TRACE + LLDB_LOG(log, "Replaying {0}: {1}", id, GetSignature(id)); +#else + (void)log; + llvm::errs() << "Replaying " << id << ": " << GetSignature(id) << "\n"; +#endif + assert(m_ids.count(id) != 0 && "Invalid id?"); m_ids[id]->operator()(deserializer); } return true; } -void Registry::DoRegister(uintptr_t RunID, std::unique_ptr<Replayer> replayer) { +unsigned Registry::DoRegister(uintptr_t RunID, + std::unique_ptr<Replayer> replayer) { const unsigned id = m_replayers.size() + 1; assert(m_replayers.find(RunID) == m_replayers.end()); m_replayers[RunID] = std::make_pair(std::move(replayer), id); m_ids[id] = m_replayers[RunID].first.get(); + return id; +} + +void Registry::RegisterSignature(unsigned id, llvm::StringRef result, + llvm::StringRef theclass, + llvm::StringRef method, + llvm::StringRef signature) { + m_signatures[id] = (result + (result.empty() ? "" : " ") + theclass + + "::" + method + signature) + .str(); } unsigned Registry::GetID(uintptr_t addr) { Index: lldb/include/lldb/Utility/ReproducerInstrumentation.h =================================================================== --- lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ lldb/include/lldb/Utility/ReproducerInstrumentation.h @@ -18,15 +18,37 @@ #include <map> +// Define LLDB_REPRO_INSTR_TRACE to trace to stderr instead of LLDB's log +// infrastructure. This is useful when you need to see traces before the logger +// is initialized or enabled. +// #define LLDB_REPRO_INSTR_TRACE + #define LLDB_REGISTER_CONSTRUCTOR(Class, Signature) \ - Register<Class * Signature>(&construct<Class Signature>::doit) + { \ + unsigned id = \ + Register<Class * Signature>(&construct<Class Signature>::doit); \ + RegisterSignature(id, "", #Class, #Class, #Signature); \ + } + #define LLDB_REGISTER_METHOD(Result, Class, Method, Signature) \ - Register(&invoke<Result(Class::*) Signature>::method<&Class::Method>::doit) + { \ + unsigned id = Register( \ + &invoke<Result(Class::*) Signature>::method<&Class::Method>::doit); \ + RegisterSignature(id, #Result, #Class, #Method, #Signature); \ + } #define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature) \ - Register(&invoke<Result(Class::*) \ - Signature const>::method_const<&Class::Method>::doit) + { \ + unsigned id = Register( \ + &invoke<Result(Class::*) \ + Signature const>::method_const<&Class::Method>::doit); \ + RegisterSignature(id, #Result, #Class, #Method, #Signature); \ + } #define LLDB_REGISTER_STATIC_METHOD(Result, Class, Method, Signature) \ - Register<Result Signature>(static_cast<Result(*) Signature>(&Class::Method)) + { \ + unsigned id = Register<Result Signature>( \ + static_cast<Result(*) Signature>(&Class::Method)); \ + RegisterSignature(id, #Result, #Class, #Method, #Signature); \ + } #define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...) \ LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "{0}", \ @@ -224,6 +246,9 @@ /// Deserialize and interpret value as T. template <typename T> T Deserialize() { +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << "\n"; +#endif return Read<T>(typename serializer_tag<T>::type()); } @@ -376,14 +401,16 @@ virtual ~Registry() = default; /// Register a default replayer for a function. - template <typename Signature> void Register(Signature *f) { - DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(f)); + template <typename Signature> unsigned Register(Signature *f) { + return DoRegister(uintptr_t(f), + llvm::make_unique<DefaultReplayer<Signature>>(f)); } /// Register a replayer that invokes a custom function with the same /// signature as the replayed function. - template <typename Signature> void Register(Signature *f, Signature *g) { - DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(g)); + template <typename Signature> unsigned Register(Signature *f, Signature *g) { + return DoRegister(uintptr_t(f), + llvm::make_unique<DefaultReplayer<Signature>>(g)); } /// Replay functions from a file. @@ -395,9 +422,16 @@ /// Returns the ID for a given function address. unsigned GetID(uintptr_t addr); + /// Return the signature for the given id. + llvm::StringRef GetSignature(unsigned id) { return m_signatures[id]; } + protected: /// Register the given replayer for a function (and the ID mapping). - void DoRegister(uintptr_t RunID, std::unique_ptr<Replayer> replayer); + unsigned DoRegister(uintptr_t RunID, std::unique_ptr<Replayer> replayer); + + void RegisterSignature(unsigned id, llvm::StringRef result, + llvm::StringRef theclass, llvm::StringRef method, + llvm::StringRef signature); private: /// Mapping of function addresses to replayers and their ID. @@ -406,6 +440,9 @@ /// Mapping of IDs to replayer instances. std::map<unsigned, Replayer *> m_ids; + + /// Mapping of IDs to string for debugging. + std::map<unsigned, std::string> m_signatures; }; /// To be used as the "Runtime ID" of a constructor. It also invokes the @@ -551,8 +588,12 @@ unsigned id = m_registry.GetID(uintptr_t(f)); - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "Recording ({0}) '{1}'", +#ifndef LLDB_REPRO_INSTR_TRACE + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "Recording {0}: {1}", id, m_pretty_func); +#else + llvm::errs() << "Recording " << id << ": " << m_pretty_func << "\n"; +#endif m_serializer.SerializeAll(id); m_serializer.SerializeAll(args...); @@ -574,8 +615,12 @@ unsigned id = m_registry.GetID(uintptr_t(f)); - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "Recording ({0}) '{1}'", +#ifndef LLDB_REPRO_INSTR_TRACE + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "Recording {0}: {1}", id, m_pretty_func); +#else + llvm::errs() << "Recording " << id << ": " << m_pretty_func << "\n"; +#endif m_serializer.SerializeAll(id); m_serializer.SerializeAll(args...);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits