[lldb/Plugins] Move SBTarget::GetExtendedCrashInformation to SBProcess
authorMed Ismail Bennani <medismail.bennani@gmail.com>
Mon, 24 Feb 2020 15:04:16 +0000 (10:04 -0500)
committerMed Ismail Bennani <medismail.bennani@gmail.com>
Mon, 24 Feb 2020 22:37:04 +0000 (23:37 +0100)
This patch moves the SB API method GetExtendedCrashInformation from
SBTarget to SBProcess since it only makes sense to call this method on a
sane process which might not be the case on a SBTarget object.

It also addresses some feedbacks received after landing the first patch
for the 'crash-info' feature.

Differential Revision: https://reviews.llvm.org/D75049

Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
13 files changed:
lldb/bindings/interface/SBProcess.i
lldb/bindings/interface/SBTarget.i
lldb/include/lldb/API/SBProcess.h
lldb/include/lldb/API/SBStructuredData.h
lldb/include/lldb/API/SBTarget.h
lldb/include/lldb/Target/Platform.h
lldb/source/API/SBProcess.cpp
lldb/source/API/SBTarget.cpp
lldb/source/Commands/CommandObjectProcess.cpp
lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
lldb/test/API/functionalities/process_crash_info/TestProcessCrashInfo.py
lldb/test/API/functionalities/process_crash_info/main.c

index ac6a265faec9f8f5f864c267147c1aba91ee6656..b54c4629f9df857565022133a7be616b85df658b 100644 (file)
@@ -346,6 +346,11 @@ public:
     bool
     GetDescription (lldb::SBStream &description);
 
+    %feature("autodoc", "
+    Returns the process' extended crash information.") GetExtendedCrashInformation;
+    lldb::SBStructuredData
+    GetExtendedCrashInformation ();
+
     uint32_t
     GetNumSupportedHardwareWatchpoints (lldb::SBError &error) const;
 
index aec7ab94942ae7cdf7e88d6731216e23912496c4..371bf5c35ebd046ad1e7bac9fff83c36cb9cc8df 100644 (file)
@@ -949,12 +949,6 @@ public:
     void
     SetLaunchInfo (const lldb::SBLaunchInfo &launch_info);
 
-    %feature("autodoc", "
-    Returns the platform's process extended crash information.") GetExtendedCrashInformation;
-    lldb::SBStructuredData
-    GetExtendedCrashInformation ();
-
-
     void SetCollectingStats(bool v);
 
     bool GetCollectingStats();
index ed62ae4282682b4f9cfe00efdfc924dd86d194f6..a90ec2a29a39978b437994d3e1558dc7a1e841a2 100644 (file)
@@ -222,6 +222,8 @@ public:
 
   bool GetDescription(lldb::SBStream &description);
 
+  SBStructuredData GetExtendedCrashInformation();
+
   /// Start Tracing with the given SBTraceOptions.
   ///
   /// \param[in] options
index f712d23e54f83bdd9893c65137a274ca7d24db29..44a86bdabe259c1076236e009aa4dba7d43e5611 100644 (file)
@@ -91,6 +91,7 @@ protected:
   friend class SBTraceOptions;
   friend class SBDebugger;
   friend class SBTarget;
+  friend class SBProcess;
   friend class SBThread;
   friend class SBThreadPlan;
   friend class SBBreakpoint;
index f95c89d9a47ac93c5a26edb76c917c78206fb25f..a50e791d4fe3c26c4be67d9bbc18572de5a208c5 100644 (file)
@@ -819,8 +819,6 @@ public:
 
   void SetLaunchInfo(const lldb::SBLaunchInfo &launch_info);
 
-  SBStructuredData GetExtendedCrashInformation();
-
 protected:
   friend class SBAddress;
   friend class SBBlock;
index 79bbc130ef869cfd0665c06164f9e256e4f2e6d9..f347e7beae28f83521159ed877f4468f34987a9c 100644 (file)
@@ -831,8 +831,8 @@ public:
   /// nullptr. This dictionnary is generic and extensible, as it contains an
   /// array for each different type of crash information.
   ///
-  /// \param[in] target
-  ///     The target running the crashed process.
+  /// \param[in] process
+  ///     The crashed process.
   ///
   /// \return
   ///     A structured data dictionnary containing at each entry, the crash
@@ -840,7 +840,7 @@ public:
   ///     entry value. \b nullptr if not implemented or  if the process has no
   ///     crash information entry. \b error if an error occured.
   virtual llvm::Expected<StructuredData::DictionarySP>
-  FetchExtendedCrashInformation(lldb_private::Target &target) {
+  FetchExtendedCrashInformation(lldb_private::Process &process) {
     return nullptr;
   }
 
index 1a93950c3069db107c1663dc3bfb26a7bbfb7c23..ab216015741f6c9c80875f5ce3e63913797accec 100644 (file)
@@ -18,6 +18,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
@@ -1010,6 +1011,30 @@ bool SBProcess::GetDescription(SBStream &description) {
   return true;
 }
 
+SBStructuredData SBProcess::GetExtendedCrashInformation() {
+  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStructuredData, SBProcess,
+                             GetExtendedCrashInformation);
+  SBStructuredData data;
+  ProcessSP process_sp(GetSP());
+  if (!process_sp)
+    return LLDB_RECORD_RESULT(data);
+
+  PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
+
+  if (!platform_sp)
+    return LLDB_RECORD_RESULT(data);
+
+  auto expected_data =
+      platform_sp->FetchExtendedCrashInformation(*process_sp.get());
+
+  if (!expected_data)
+    return LLDB_RECORD_RESULT(data);
+
+  StructuredData::ObjectSP fetched_data = *expected_data;
+  data.m_impl_up->SetObjectSP(fetched_data);
+  return LLDB_RECORD_RESULT(data);
+}
+
 uint32_t
 SBProcess::GetNumSupportedHardwareWatchpoints(lldb::SBError &sb_error) const {
   LLDB_RECORD_METHOD_CONST(uint32_t, SBProcess,
@@ -1385,6 +1410,8 @@ void RegisterMethods<SBProcess>(Registry &R) {
   LLDB_REGISTER_METHOD(lldb::addr_t, SBProcess, ReadPointerFromMemory,
                        (lldb::addr_t, lldb::SBError &));
   LLDB_REGISTER_METHOD(bool, SBProcess, GetDescription, (lldb::SBStream &));
+  LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBProcess,
+                       GetExtendedCrashInformation, ());
   LLDB_REGISTER_METHOD_CONST(uint32_t, SBProcess,
                              GetNumSupportedHardwareWatchpoints,
                              (lldb::SBError &));
index b07120b4c9f3996616f9ffc5846407d0aec3de1e..b90e77280d24c90d978dc8b00570e035e5269d2e 100644 (file)
@@ -2388,30 +2388,6 @@ void SBTarget::SetLaunchInfo(const lldb::SBLaunchInfo &launch_info) {
     m_opaque_sp->SetProcessLaunchInfo(launch_info.ref());
 }
 
-SBStructuredData SBTarget::GetExtendedCrashInformation() {
-  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStructuredData, SBTarget,
-                             GetExtendedCrashInformation);
-  SBStructuredData data;
-  TargetSP target_sp(GetSP());
-  if (!target_sp)
-    return LLDB_RECORD_RESULT(data);
-
-  PlatformSP platform_sp = target_sp->GetPlatform();
-
-  if (!target_sp)
-    return LLDB_RECORD_RESULT(data);
-
-  auto expected_data =
-      platform_sp->FetchExtendedCrashInformation(*target_sp.get());
-
-  if (!expected_data)
-    return LLDB_RECORD_RESULT(data);
-
-  StructuredData::ObjectSP fetched_data = *expected_data;
-  data.m_impl_up->SetObjectSP(fetched_data);
-  return LLDB_RECORD_RESULT(data);
-}
-
 namespace lldb_private {
 namespace repro {
 
@@ -2654,8 +2630,6 @@ void RegisterMethods<SBTarget>(Registry &R) {
   LLDB_REGISTER_METHOD_CONST(lldb::SBLaunchInfo, SBTarget, GetLaunchInfo, ());
   LLDB_REGISTER_METHOD(void, SBTarget, SetLaunchInfo,
                        (const lldb::SBLaunchInfo &));
-  LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBTarget,
-                       GetExtendedCrashInformation, ());
   LLDB_REGISTER_METHOD(
       size_t, SBTarget, ReadMemory,
       (const lldb::SBAddress, void *, size_t, lldb::SBError &));
index 4ee085e97e4caaa1ec1903d0ee85aac7bb7bf621..504aec406d1fa8e972925e4c2e569d22bb253783 100644 (file)
@@ -1283,7 +1283,7 @@ protected:
       }
 
       auto expected_crash_info =
-          platform_sp->FetchExtendedCrashInformation(process->GetTarget());
+          platform_sp->FetchExtendedCrashInformation(*process);
 
       if (!expected_crash_info) {
         result.AppendError(llvm::toString(expected_crash_info.takeError()));
index 3790bd09a1f1ca9b370d40547b5ff21c3806a290..b21f1a20ba7315f337f2b87e6bab52bd2a0d8826 100644 (file)
@@ -1503,10 +1503,10 @@ PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
 }
 
 llvm::Expected<StructuredData::DictionarySP>
-PlatformDarwin::FetchExtendedCrashInformation(lldb_private::Target &target) {
+PlatformDarwin::FetchExtendedCrashInformation(Process &process) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-  StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(target);
+  StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(process);
 
   if (!annotations || !annotations->GetSize()) {
     LLDB_LOG(log, "Couldn't extract crash information annotations");
@@ -1522,11 +1522,11 @@ PlatformDarwin::FetchExtendedCrashInformation(lldb_private::Target &target) {
 }
 
 StructuredData::ArraySP
-PlatformDarwin::ExtractCrashInfoAnnotations(Target &target) {
+PlatformDarwin::ExtractCrashInfoAnnotations(Process &process) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
 
   ConstString section_name("__crash_info");
-  ProcessSP process_sp = target.GetProcessSP();
+  Target &target = process.GetTarget();
   StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>();
 
   for (ModuleSP module : target.GetImages().Modules()) {
@@ -1562,8 +1562,8 @@ PlatformDarwin::ExtractCrashInfoAnnotations(Target &target) {
     Status error;
     CrashInfoAnnotations annotations;
     size_t expected_size = sizeof(CrashInfoAnnotations);
-    size_t bytes_read = process_sp->ReadMemoryFromInferior(
-        load_addr, &annotations, expected_size, error);
+    size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations,
+                                                       expected_size, error);
 
     if (expected_size != bytes_read || error.Fail()) {
       LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}",
@@ -1587,7 +1587,7 @@ PlatformDarwin::ExtractCrashInfoAnnotations(Target &target) {
 
     std::string message;
     bytes_read =
-        process_sp->ReadCStringFromMemory(annotations.message, message, error);
+        process.ReadCStringFromMemory(annotations.message, message, error);
 
     if (message.empty() || bytes_read != message.size() || error.Fail()) {
       LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}",
@@ -1603,8 +1603,8 @@ PlatformDarwin::ExtractCrashInfoAnnotations(Target &target) {
       LLDB_LOG(log, "No message2 available for module {0}.", module_name);
 
     std::string message2;
-    bytes_read = process_sp->ReadCStringFromMemory(annotations.message2,
-                                                   message2, error);
+    bytes_read =
+        process.ReadCStringFromMemory(annotations.message2, message2, error);
 
     if (!message2.empty() && bytes_read == message2.size() && error.Success())
       if (message2.back() == '\n')
index 302dac413423eee5c783ed1b4d13f6223b52e55d..bd23d50178b778f8e61fc566aea2691449d14a1f 100644 (file)
@@ -86,7 +86,7 @@ public:
   };
 
   llvm::Expected<lldb_private::StructuredData::DictionarySP>
-  FetchExtendedCrashInformation(lldb_private::Target &target) override;
+  FetchExtendedCrashInformation(lldb_private::Process &process) override;
 
 protected:
   struct CrashInfoAnnotations {
@@ -107,15 +107,15 @@ protected:
   /// extract the section to gather the messages annotations and the abort
   /// cause.
   ///
-  /// \param[in] target
-  ///     The target running the crashed process.
+  /// \param[in] process
+  ///     The crashed process.
   ///
   /// \return
   ///     A  structured data array containing at each entry in each entry, the
   ///     module spec, its UUID, the crash messages and the abort cause.
   ///     \b nullptr if process has no crash information annotations.
   lldb_private::StructuredData::ArraySP
-  ExtractCrashInfoAnnotations(lldb_private::Target &target);
+  ExtractCrashInfoAnnotations(lldb_private::Process &process);
 
   void ReadLibdispatchOffsetsAddress(lldb_private::Process *process);
 
index 979efe0a160d9b2ff893360eb210a9b29a0d59f8..3caa7c5d905a9818bb6529189b39884651d974e5 100644 (file)
@@ -8,6 +8,8 @@ import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
+from lldbsuite.test import lldbtest
+
 
 class PlatformProcessCrashInfoTestCase(TestBase):
 
@@ -17,7 +19,7 @@ class PlatformProcessCrashInfoTestCase(TestBase):
         TestBase.setUp(self)
         self.runCmd("settings set auto-confirm true")
         self.source = "main.c"
-        self.line = 3
+        self.line = line_number(self.source, '// break here')
 
     def tearDown(self):
         self.runCmd("settings clear auto-confirm")
@@ -52,7 +54,10 @@ class PlatformProcessCrashInfoTestCase(TestBase):
         stream = lldb.SBStream()
         self.assertTrue(stream)
 
-        crash_info = target.GetExtendedCrashInformation()
+        process = target.GetProcess()
+        self.assertTrue(process)
+
+        crash_info = process.GetExtendedCrashInformation()
 
         error = crash_info.GetAsJSON(stream)
 
@@ -62,24 +67,6 @@ class PlatformProcessCrashInfoTestCase(TestBase):
 
         self.assertIn("pointer being freed was not allocated", stream.GetData())
 
-    @skipUnlessDarwin
-    def test_before_launch(self):
-        """Test that lldb doesn't fetch the extended crash information
-        dictionnary from if the process wasn't launched yet."""
-        self.build()
-        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
-        self.assertTrue(target, VALID_TARGET)
-
-        stream = lldb.SBStream()
-        self.assertTrue(stream)
-
-        crash_info = target.GetExtendedCrashInformation()
-
-        error = crash_info.GetAsJSON(stream)
-        self.assertFalse(error.Success())
-        self.assertIn("No structured data.", error.GetCString())
-
-    @skipUnlessDarwin
     def test_on_sane_process(self):
         """Test that lldb doesn't fetch the extended crash information
         dictionnary from a 'sane' stopped process."""
@@ -90,7 +77,10 @@ class PlatformProcessCrashInfoTestCase(TestBase):
         stream = lldb.SBStream()
         self.assertTrue(stream)
 
-        crash_info = target.GetExtendedCrashInformation()
+        process = target.GetProcess()
+        self.assertTrue(process)
+
+        crash_info = process.GetExtendedCrashInformation()
 
         error = crash_info.GetAsJSON(stream)
         self.assertFalse(error.Success())
index 49733512898b8b6d6ddc240a2db40e230c9cc0b8..9ed467f8e70f3eccea822af84a60b51455cd5cd3 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdlib.h>
+
 int main() {
-  int *var = malloc(sizeof(int));
+  int *var = malloc(sizeof(int)); // break here
   free(var);
   free(var);
   return 0;