kubamracek updated this revision to Diff 136933.

https://reviews.llvm.org/D43884

Files:
  packages/Python/lldbsuite/test/lang/objc/exceptions/Makefile
  packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py
  packages/Python/lldbsuite/test/lang/objc/exceptions/main.m
  source/Plugins/Language/ObjC/NSException.cpp

Index: source/Plugins/Language/ObjC/NSException.cpp
===================================================================
--- source/Plugins/Language/ObjC/NSException.cpp
+++ source/Plugins/Language/ObjC/NSException.cpp
@@ -34,8 +34,8 @@
 using namespace lldb_private::formatters;
 
 static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp,
-                          ValueObjectSP *reason_sp,
-                          ValueObjectSP *userinfo_sp) {
+                          ValueObjectSP *reason_sp, ValueObjectSP *userinfo_sp,
+                          ValueObjectSP *reserved_sp) {
   ProcessSP process_sp(valobj.GetProcessSP());
   if (!process_sp)
     return false;
@@ -65,10 +65,14 @@
   auto userinfo = process_sp->ReadPointerFromMemory(ptr + 3 * ptr_size, error);
   if (error.Fail() || userinfo == LLDB_INVALID_ADDRESS)
     return false;
+  auto reserved = process_sp->ReadPointerFromMemory(ptr + 4 * ptr_size, error);
+  if (error.Fail() || reserved == LLDB_INVALID_ADDRESS)
+    return false;
 
   InferiorSizedWord name_isw(name, *process_sp);
   InferiorSizedWord reason_isw(reason, *process_sp);
   InferiorSizedWord userinfo_isw(userinfo, *process_sp);
+  InferiorSizedWord reserved_isw(reserved, *process_sp);
 
   CompilerType voidstar = process_sp->GetTarget()
                               .GetScratchClangASTContext()
@@ -87,15 +91,19 @@
     *userinfo_sp = ValueObject::CreateValueObjectFromData(
         "userInfo", userinfo_isw.GetAsData(process_sp->GetByteOrder()),
         valobj.GetExecutionContextRef(), voidstar);
+  if (reserved_sp)
+    *reserved_sp = ValueObject::CreateValueObjectFromData(
+        "reserved", reserved_isw.GetAsData(process_sp->GetByteOrder()),
+        valobj.GetExecutionContextRef(), voidstar);
 
   return true;
 }
 
 bool lldb_private::formatters::NSException_SummaryProvider(
     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
   lldb::ValueObjectSP name_sp;
   lldb::ValueObjectSP reason_sp;
-  if (!ExtractFields(valobj, &name_sp, &reason_sp, nullptr))
+  if (!ExtractFields(valobj, &name_sp, &reason_sp, nullptr, nullptr))
     return false;
 
   if (!name_sp || !reason_sp)
@@ -121,35 +129,51 @@
   ~NSExceptionSyntheticFrontEnd() override = default;
 
   size_t CalculateNumChildren() override {
-    return 1;
+    return 4;
   }
 
   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
     switch (idx) {
-      case 0: return m_userinfo_sp;
+      case 0: return m_name_sp;
+      case 1: return m_reason_sp;
+      case 2: return m_userinfo_sp;
+      case 3: return m_reserved_sp;
     }
     return lldb::ValueObjectSP();
   }
 
   bool Update() override {
+    m_name_sp.reset();
+    m_reason_sp.reset();
     m_userinfo_sp.reset();
-    if (!ExtractFields(m_backend, nullptr, nullptr, &m_userinfo_sp)) {
+    m_reserved_sp.reset();
+
+    if (!ExtractFields(m_backend, &m_name_sp, &m_reason_sp, &m_userinfo_sp,
+                       &m_reserved_sp)) {
       return false;
     }
     return true;
   }
 
   bool MightHaveChildren() override { return true; }
 
   size_t GetIndexOfChildWithName(const ConstString &name) override {
+    static ConstString g___name("name");
+    static ConstString g___reason("reason");
     static ConstString g___userInfo("userInfo");
-    if (name == g___userInfo)
-      return 0;
+    static ConstString g___reserved("reserved");
+    if (name == g___name) return 0;
+    if (name == g___reason) return 1;
+    if (name == g___userInfo) return 2;
+    if (name == g___reserved) return 3;
     return UINT32_MAX;
   }
 
 private:
+  ValueObjectSP m_name_sp;
+  ValueObjectSP m_reason_sp;
   ValueObjectSP m_userinfo_sp;
+  ValueObjectSP m_reserved_sp;
 };
 
 SyntheticChildrenFrontEnd *
Index: packages/Python/lldbsuite/test/lang/objc/exceptions/main.m
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/lang/objc/exceptions/main.m
@@ -0,0 +1,36 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+void foo()
+{
+    NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"some_value", @"some_key", nil];
+    @throw [[NSException alloc] initWithName:@"ThrownException" reason:@"SomeReason" userInfo:info];
+}
+
+int main (int argc, const char * argv[])
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"some_value", @"some_key", nil];
+    NSException *e1 = [[NSException alloc] initWithName:@"ExceptionName" reason:@"SomeReason" userInfo:info];
+    NSException *e2;
+
+    @try {
+        foo();
+    } @catch(NSException *e) {
+        e2 = e;
+    }
+
+    NSLog(@"1"); // Set break point at this line.
+    [pool drain];
+    return 0;
+}
+
Index: packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py
@@ -0,0 +1,90 @@
+# encoding: utf-8
+"""
+Test lldb Obj-C exception support.
+"""
+
+from __future__ import print_function
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class ObjCExceptionsTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessDarwin
+    def test_objc_exceptions_1(self):
+        self.build()
+
+        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+        self.assertTrue(target, VALID_TARGET)
+
+        lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", lldb.SBFileSpec("main.m"))
+
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped', 'stop reason = breakpoint'])
+
+        thread = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
+        frame = thread.GetSelectedFrame()
+
+        self.expect(
+            'frame variable e1',
+            substrs=[
+                '(NSException *) e1 = ',
+                'name: @"ExceptionName" - reason: @"SomeReason"'
+            ])
+
+        self.expect(
+            'frame variable --dynamic-type no-run-target *e1',
+            substrs=[
+                '(NSException) *e1 = ',
+                'name = ', '@"ExceptionName"',
+                'reason = ', '@"SomeReason"',
+                'userInfo = ', '1 key/value pair',
+                'reserved = ', 'nil',
+            ])
+
+        e1 = frame.FindVariable("e1")
+        self.assertTrue(e1)
+        self.assertEqual(e1.type.name, "NSException *")
+        self.assertEqual(e1.GetSummary(), 'name: @"ExceptionName" - reason: @"SomeReason"')
+        self.assertEqual(e1.GetChildMemberWithName("name").description, "ExceptionName")
+        self.assertEqual(e1.GetChildMemberWithName("reason").description, "SomeReason")
+        userInfo = e1.GetChildMemberWithName("userInfo").dynamic
+        self.assertEqual(userInfo.summary, "1 key/value pair")
+        self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key")
+        self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value")
+        self.assertEqual(e1.GetChildMemberWithName("reserved").description, "<nil>")
+
+        self.expect(
+            'frame variable e2',
+            substrs=[
+                '(NSException *) e2 = ',
+                'name: @"ThrownException" - reason: @"SomeReason"'
+            ])
+
+        self.expect(
+            'frame variable --dynamic-type no-run-target *e2',
+            substrs=[
+                '(NSException) *e2 = ',
+                'name = ', '@"ThrownException"',
+                'reason = ', '@"SomeReason"',
+                'userInfo = ', '1 key/value pair',
+                'reserved = ',
+            ])
+
+        e2 = frame.FindVariable("e2")
+        self.assertTrue(e2)
+        self.assertEqual(e2.type.name, "NSException *")
+        self.assertEqual(e2.GetSummary(), 'name: @"ThrownException" - reason: @"SomeReason"')
+        self.assertEqual(e2.GetChildMemberWithName("name").description, "ThrownException")
+        self.assertEqual(e2.GetChildMemberWithName("reason").description, "SomeReason")
+        userInfo = e2.GetChildMemberWithName("userInfo").dynamic
+        self.assertEqual(userInfo.summary, "1 key/value pair")
+        self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key")
+        self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value")
+        self.assertGreater(e2.GetChildMemberWithName("reserved").dynamic.num_children, 0)
Index: packages/Python/lldbsuite/test/lang/objc/exceptions/Makefile
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/lang/objc/exceptions/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to