[Lldb-commits] [lldb] 2f025bb - [lldb/Reproducers] Implement custom replayers for (char *, size_t)

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Wed Feb 5 20:00:11 PST 2020


Author: Jonas Devlieghere
Date: 2020-02-05T19:59:38-08:00
New Revision: 2f025bb87c33a25e3a0d226cdb663f237ccd602e

URL: https://github.com/llvm/llvm-project/commit/2f025bb87c33a25e3a0d226cdb663f237ccd602e
DIFF: https://github.com/llvm/llvm-project/commit/2f025bb87c33a25e3a0d226cdb663f237ccd602e.diff

LOG: [lldb/Reproducers] Implement custom replayers for (char *, size_t)

Some SB API methods returns strings through a char* and a length. This
is a problem for the deserializer, which considers a single type at a
time, and therefore cannot know how many bytes to allocate for the
character buffer.

We can solve this problem by implementing a custom replayer, which
ignores the passed-in char* and allocates a buffer of the correct size
itself, before invoking the original API method or function.

This patch adds three new macros to register a custom replayer for
methods that take a char* and a size_t. It supports arbitrary return
values (some functions return a bool while others return a size_t).

Added: 
    

Modified: 
    lldb/include/lldb/Utility/ReproducerInstrumentation.h
    lldb/source/API/SBDebugger.cpp
    lldb/source/API/SBFileSpec.cpp
    lldb/source/API/SBProcess.cpp
    lldb/source/API/SBStructuredData.cpp
    lldb/source/API/SBThread.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/lldb/include/lldb/Utility/ReproducerInstrumentation.h
index bc28999221db..a562511d6012 100644
--- a/lldb/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/lldb/include/lldb/Utility/ReproducerInstrumentation.h
@@ -90,6 +90,32 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
       static_cast<Result(*) Signature>(&Class::Method), #Result, #Class,       \
       #Method, #Signature)
 
+#define LLDB_REGISTER_CHAR_PTR_REDIRECT_STATIC(Result, Class, Method)          \
+  {                                                                            \
+    static auto _redirect = [](char *s, size_t l) -> Result {                  \
+      return char_ptr_redirect_static<Result>(Class::Method, s, l);            \
+    };                                                                         \
+    R.Register<Result(char *, size_t)>(                                        \
+        static_cast<Result (*)(char *, size_t)>(&Class::Method), _redirect);   \
+  }
+#define LLDB_REGISTER_CHAR_PTR_REDIRECT(Result, Class, Method)                 \
+  {                                                                            \
+    R.Register(&invoke<Result (Class::*)(char *, size_t)>::method<(            \
+                   &Class::Method)>::doit,                                     \
+               &char_ptr_redirect<Result (Class::*)(char *, size_t)>::method<( \
+                   &Class::Method)>::doit,                                     \
+               #Result, #Class, #Method, "(char*, size_t");                    \
+  }
+#define LLDB_REGISTER_CHAR_PTR_REDIRECT_CONST(Result, Class, Method)           \
+  {                                                                            \
+    R.Register(                                                                \
+        &invoke<Result (Class::*)(char *, size_t)                              \
+                    const>::method_const<(&Class::Method)>::doit,              \
+        &char_ptr_redirect<Result (Class::*)(char *, size_t)                   \
+                               const>::method_const<(&Class::Method)>::doit,   \
+        #Result, #Class, #Method, "(char*, size_t");                           \
+  }
+
 #define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...)                         \
   lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION,                \
                                           stringify_args(__VA_ARGS__));        \
@@ -621,8 +647,6 @@ class Serializer {
     }
   }
 
-  void Serialize(char *t) { Serialize(static_cast<const char *>(t)); }
-
   void Serialize(const char **t) {
     size_t size = 0;
     if (!t) {
@@ -779,6 +803,33 @@ class Recorder {
   static bool g_global_boundary;
 };
 
+template <typename Signature> struct char_ptr_redirect;
+template <typename Result, typename Class>
+struct char_ptr_redirect<Result (Class::*)(char *, size_t) const> {
+  template <Result (Class::*m)(char *, size_t) const> struct method_const {
+    static Result doit(Class *c, char *s, size_t l) {
+      char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
+      return (c->*m)(buffer, l);
+    }
+  };
+};
+template <typename Result, typename Class>
+struct char_ptr_redirect<Result (Class::*)(char *, size_t)> {
+  template <Result (Class::*m)(char *, size_t)> struct method {
+    static Result doit(Class *c, char *s, size_t l) {
+      char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
+      return (c->*m)(buffer, l);
+    }
+  };
+};
+
+template <typename Result>
+Result char_ptr_redirect_static(Result (*f)(char *, size_t), char *s,
+                                size_t l) {
+  char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
+  return f(buffer, l);
+}
+
 } // namespace repro
 } // namespace lldb_private
 

diff  --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 4a093b1ebb9d..1aeb5e2ca9ff 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -1627,14 +1627,6 @@ static SBError SetFileRedirect(SBDebugger *, SBFile file) { return SBError(); }
 
 static SBError SetFileRedirect(SBDebugger *, FileSP file) { return SBError(); }
 
-static bool GetDefaultArchitectureRedirect(char *arch_name,
-                                           size_t arch_name_len) {
-  // The function is writing to its argument. Without the redirect it would
-  // write into the replay buffer.
-  char buffer[1024];
-  return SBDebugger::GetDefaultArchitecture(buffer, arch_name_len);
-}
-
 template <> void RegisterMethods<SBDebugger>(Registry &R) {
   // Custom implementation.
   R.Register(&invoke<void (SBDebugger::*)(
@@ -1643,9 +1635,6 @@ template <> void RegisterMethods<SBDebugger>(Registry &R) {
   R.Register(&invoke<void (SBDebugger::*)(
                  FILE *, bool)>::method<&SBDebugger::SetOutputFileHandle>::doit,
              &SetFileHandleRedirect);
-  R.Register<bool(char *, size_t)>(static_cast<bool (*)(char *, size_t)>(
-                                       &SBDebugger::GetDefaultArchitecture),
-                                   &GetDefaultArchitectureRedirect);
 
   R.Register(&invoke<SBError (SBDebugger::*)(
                  SBFile)>::method<&SBDebugger::SetInputFile>::doit,
@@ -1667,6 +1656,9 @@ template <> void RegisterMethods<SBDebugger>(Registry &R) {
                  FileSP)>::method<&SBDebugger::SetErrorFile>::doit,
              &SetFileRedirect);
 
+  LLDB_REGISTER_CHAR_PTR_REDIRECT_STATIC(bool, SBDebugger,
+                                         GetDefaultArchitecture);
+
   LLDB_REGISTER_CONSTRUCTOR(SBDebugger, ());
   LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &));
   LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &));

diff  --git a/lldb/source/API/SBFileSpec.cpp b/lldb/source/API/SBFileSpec.cpp
index 3fece033e840..a9b3c0f99f9d 100644
--- a/lldb/source/API/SBFileSpec.cpp
+++ b/lldb/source/API/SBFileSpec.cpp
@@ -213,10 +213,10 @@ void RegisterMethods<SBFileSpec>(Registry &R) {
   LLDB_REGISTER_METHOD_CONST(const char *, SBFileSpec, GetDirectory, ());
   LLDB_REGISTER_METHOD(void, SBFileSpec, SetFilename, (const char *));
   LLDB_REGISTER_METHOD(void, SBFileSpec, SetDirectory, (const char *));
-  LLDB_REGISTER_METHOD_CONST(uint32_t, SBFileSpec, GetPath, (char *, size_t));
   LLDB_REGISTER_METHOD_CONST(bool, SBFileSpec, GetDescription,
                              (lldb::SBStream &));
   LLDB_REGISTER_METHOD(void, SBFileSpec, AppendPathComponent, (const char *));
+  LLDB_REGISTER_CHAR_PTR_REDIRECT_CONST(uint32_t, SBFileSpec, GetPath);
 }
 
 }

diff  --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index 5578550552be..ffb5a3fa8569 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -1313,10 +1313,6 @@ void RegisterMethods<SBProcess>(Registry &R) {
                        (lldb::tid_t, lldb::addr_t));
   LLDB_REGISTER_METHOD_CONST(lldb::SBTarget, SBProcess, GetTarget, ());
   LLDB_REGISTER_METHOD(size_t, SBProcess, PutSTDIN, (const char *, size_t));
-  LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetSTDOUT, (char *, size_t));
-  LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetSTDERR, (char *, size_t));
-  LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetAsyncProfileData,
-                             (char *, size_t));
   LLDB_REGISTER_METHOD(lldb::SBTrace, SBProcess, StartTrace,
                        (lldb::SBTraceOptions &, lldb::SBError &));
   LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState,
@@ -1416,6 +1412,10 @@ void RegisterMethods<SBProcess>(Registry &R) {
   LLDB_REGISTER_METHOD(lldb::SBMemoryRegionInfoList, SBProcess,
                        GetMemoryRegions, ());
   LLDB_REGISTER_METHOD(lldb::SBProcessInfo, SBProcess, GetProcessInfo, ());
+
+  LLDB_REGISTER_CHAR_PTR_REDIRECT_CONST(size_t, SBProcess, GetSTDOUT);
+  LLDB_REGISTER_CHAR_PTR_REDIRECT_CONST(size_t, SBProcess, GetSTDERR);
+  LLDB_REGISTER_CHAR_PTR_REDIRECT_CONST(size_t, SBProcess, GetAsyncProfileData);
 }
 
 }

diff  --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp
index c9a8e0a3e849..bc820ba7e2ef 100644
--- a/lldb/source/API/SBStructuredData.cpp
+++ b/lldb/source/API/SBStructuredData.cpp
@@ -205,11 +205,9 @@ size_t SBStructuredData::GetStringValue(char *dst, size_t dst_len) const {
 namespace lldb_private {
 namespace repro {
 
-template <>
-void RegisterMethods<SBStructuredData>(Registry &R) {
+template <> void RegisterMethods<SBStructuredData>(Registry &R) {
   LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, ());
-  LLDB_REGISTER_CONSTRUCTOR(SBStructuredData,
-                            (const lldb::SBStructuredData &));
+  LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, (const lldb::SBStructuredData &));
   LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, (const lldb::EventSP &));
   LLDB_REGISTER_CONSTRUCTOR(SBStructuredData,
                             (lldb_private::StructuredDataImpl *));
@@ -236,12 +234,11 @@ void RegisterMethods<SBStructuredData>(Registry &R) {
                              GetItemAtIndex, (size_t));
   LLDB_REGISTER_METHOD_CONST(uint64_t, SBStructuredData, GetIntegerValue,
                              (uint64_t));
-  LLDB_REGISTER_METHOD_CONST(double, SBStructuredData, GetFloatValue,
-                             (double));
+  LLDB_REGISTER_METHOD_CONST(double, SBStructuredData, GetFloatValue, (double));
   LLDB_REGISTER_METHOD_CONST(bool, SBStructuredData, GetBooleanValue, (bool));
-  LLDB_REGISTER_METHOD_CONST(size_t, SBStructuredData, GetStringValue,
-                             (char *, size_t));
+  LLDB_REGISTER_CHAR_PTR_REDIRECT_CONST(size_t, SBStructuredData,
+                                        GetStringValue);
 }
 
-}
-}
+} // namespace repro
+} // namespace lldb_private

diff  --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 6fe4f66763cb..ff1a428b83cd 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -313,7 +313,7 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
 }
 
 size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
-  LLDB_RECORD_DUMMY(size_t, SBThread, GetStopDescription, (char *, size_t),
+  LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t),
                      dst, dst_len);
 
   std::unique_lock<std::recursive_mutex> lock;
@@ -1444,8 +1444,6 @@ void RegisterMethods<SBThread>(Registry &R) {
   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
                        GetStopReasonExtendedBacktraces,
                        (lldb::InstrumentationRuntimeType));
-  LLDB_REGISTER_METHOD(size_t, SBThread, GetStopDescription,
-                       (char *, size_t));
   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
@@ -1522,6 +1520,7 @@ void RegisterMethods<SBThread>(Registry &R) {
   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
                        ());
   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
+  LLDB_REGISTER_CHAR_PTR_REDIRECT(size_t, SBThread, GetStopDescription);
 }
 
 }


        


More information about the lldb-commits mailing list